When studying Azure DevOps, I found that using IaC for building and tearing down resources is useful. This post will show you how to create an Azure DevOps self-hosted agent pool using Terraform.
Infrastructure as Code (IaC) is a great way to manage resources in the cloud. It
allows you to create, update, and delete resources in a programmatic way. While
studying for my AZ-400 certification, I found that building Azure resources manually
each time running exercises was time-consuming. I decided to use Terraform to
automate the process.
In this post, I'll share what I learned, creating the necessary Azure resources to run
a self-hosted agent pool using Terraform. This will allow you to run your CI/CD
pipelines on your own infrastructure.
There are many Azure resources involved in automating the creation of a VM to run a self-hosted agent. Here is a list of the resources:
Resource Group
Virtual Network
Subnet
Network Security Group
Public IP Address
Network Interface
Virtual Machine
Azure DevOps Agent
I learned that putting everything in one file like main.tf is not a good
practice. It's better to split the configuration into multiple files. Here is
an example of how to structure the files:
This file is the entry point for Terraform. It contains the provider and module
blocks. I also put in the azure Resource Group in this file. The highlighted
lines are the parameters for the service principal.
Security warning: You are exposing port 3389 to the Internet. It is OK for a
lab, but be aware on this for production environments
Before we can create a VM, we need to make sure it will be accessible. This code
creates a Virtual Network, Subnet, and Network Security Group,
allowing RDP traffic.
This file builds the Azure VM for us. It creates a Public IP Address, Network Interface, and the Virtual Machine
running Windows Server 2022. The size "Standard_B2s" is a small VM size, but it's enough for a self-hosted agent.
We need a place to store the script used to install the Azure DevOps agent. This code creates a Storage Account, storage container
and a storage blob. The highlighted line is defining the source of the script we need to
store online.
This file creates the Azure DevOps agent. It uses the
azurerm_virtual_machine_extension resource to run a script on the VM. The
script installs the Azure DevOps agent. The highlighted lines are the block
downloading the script for installing the agent and running the script.
Security warning: Keep sensitive information out of your repo.
This file contains the values for the variables. Keep this out of your repo for security and privacy reasons. .gitignore this file.
Fill in the values from the JSON object you saved earlier, as well as the Azure DevOps URL, PAT, and Pool name. You can set other
variables as well, according to your needs.
After the Terraform run is complete, you can verify the resources in the Azure
portal. You should see the Resource Group, Virtual Machine, and the Azure
DevOps agent in the Azure DevOps portal.
It was a lot of work to create the Terraform configuration, but it was worth
it. I learned a lot about Azure resources and how to automate the creation of
resources. I hope this post helps you to move on with your IaC and DevOps journey.
In this experience, I only scratched the surface of what you can do with
Terraform. There are many more resources and possibilities to explore. The next steps
for me are to learn creating a CI/CD pipeline in Azure DevOps or GitHub Actions
to deploy the resources automatically. I also need to work on setting Terraform
variables securely in my repos, as well as finding a more secure way to store
TFSTATE files.
For me, it was a great learning experience. I hope you enjoyed it too.