Prerequisites (~30-60 minutes)

  1. Have an active Azure account. If you don’t have one yet, they give you $200 worth of credit to use within the first 30 days!
  2. Install Terraform and move it to a directory included in your system’s PATH.
  3. Install Ansible. This will be used to provision the instances. Some users may prefer to install Ansible inside of a virtual environment; that’s fine too.
  4. Install the Azure command line client and make sure it’s included in your system’s PATH.
  5. Either create or re-use an existing SSH keypair that you’ll use to authenticate to the logger host
  6. Make sure you’ve pulled down the most recent changes from the DetectionLab git repo
  7. Please note that the default credentials before provisioning are vagrant:Vagrant123 due to the windows SKU/AMI password complexity requirements!



  1. (5 Minutes) - Configure the terraform.tfvars file

    1. Copy the file at DetectionLab/Azure/Terraform/terraform.tfvars.example to DetectionLab/Azure/Terraform/terraform.tfvars
    2. In the newly copied terraform.tfvars, provide a value for each variable.

      Failing to complete this step will cause the lab to be unreachable.

  2. (5 Minutes) - Authenticate to Azure using az

    1. Run az login. This should bring up a browser that asks you to sign into your Azure account.
    2. Sign in and the window should say “You have logged into Microsoft Azure!”
  3. (3-20 Minutes) - Bring up the VM’s using Terraform

    1. cd to Azure/Terraform and run terraform init to initialize the working directory
    2. Make sure you followed the pre-reqs and have a terraform.tfvars file present with your public IP address whitelisted
    3. Run terraform apply to check the Terraform plan or terraform apply --auto-approve to bypass the check
    4. It will take ~20 minutes for logger to come online and finish provisioning, but you can move onto the next step once you see that DC, WEF, and WIN10 have fininshed creation (usually around 2 minutes):
    azurerm_virtual_machine.dc: Creation complete after 1m55s
    azurerm_virtual_machine.wef: Creation complete after 1m54s
    azurerm_virtual_machine.win10: Creation complete after 1m55s

At this point in time, we’re at this state:

  • Logger VM has been brought up and is provisioning
  • DC VM has been brought up but is unprovisioned
  • WEF VM has been brought up but is unprovisioned
  • WIN10 VM has been brought up but is unprovisioned

At this point in time, you should be able to open a new terminal window, navigate to DetectionLab/Azure/Terraform and run terraform output. You should see something like the following:

dc_public_ip = 52.183.119.x
fleet_url = https://52.191.170.x:8412
guacamole_url = https://52.191.136.x:8080/guacamole
logger_public_ip = 52.191.170.x
region = West US 2
splunk_url = https://52.191.170.x:8000
wef_public_ip = 52.191.136.x
win10_public_ip = 52.229.34.x

We’re going to use this output in the next step.


We’re going to use Ansible to fininsh provisioning the rest of the Windows hosts.

  1. (5 Minutes) - Configure the inventory.yml file
    1. Navigate to Azure/Ansible and open inventory.yml for editing.
    2. Take the public_ip values from terraform output and replace the x.x.x.x values with the public IP of each host

      NOTE: I’ve added a script at DetectionLab/Azure/ to help automate this for MacOS and Linux users.

Now that Ansible is configured for provisioning, there are two ways to go about this:

  • Provision each host one at a time (e.g. DC, then WEF, then WIN10). This is slower, but requires less steps.
  • Provision the DC, then provision WEF and WIN10 simultaneously. This is faster, but you’ll have to open multiple terminals and do a bit of manual work.

For the provisioning to be successful, the DC has to spin up Active Directory before provisioning of the WEF and WIN10 hosts can begin, otherwise they will fail to join the domain and provisioning will fail.

Slow but steady

If you’d like to take the slower but easier route, ensure you’re in the DetectionLab/Azure/Ansible directory and run ansible-playbook -v detectionlab.yml. This will provision the hosts one at a time (DC, WEF, then WIN10). However, if you’d like to go the faster route, follow the directions below.

Faster, but more hands-on

If you’d like to take the faster route, I recommend opening 3 terminal windows to DetectionLab/Azure/Ansible and following these steps:

  1. In the first window, run ansible-playbook -v detectionlab.yml --tags "dc"
  2. Once the DC has passed the Reboot Afer Domain Creation Ansible step, you can begin provisioning WEF and WIN10
  3. In the second window, run ansible-playbook -v detectionlab.yml --tags "wef"
  4. In the third window, run ansible-playbook -v detectionlab.yml --tags "win10"

If you run into any issues along the way, please open an issue on Github and I’ll do my best to find a solution.

Debugging / Troubleshooting / Known Issues

  • If an Ansible playbook fails (and they sometimes do), you can pick up where it left off with ansible-playbook -vvv detectionlab.yml --tags="hostname-goes-here" --start-at-task="taskname"
  • “Installing Red Team Tooling” hangs if AV isn’t disabled successfully

Future work required


As usual, this work is based off the heavy lifting that others have done. My primary sources for this work were:

Thank you to all of the sponsors who made this possible!