Bootstrap a VM to Azure Automation DSC using Terraform
Terraform is a great product that allows teams to easily and rapidly provision massive amounts of infrastructure to the Cloud Provider of their choosing. Whether you are using AWS, Azure, Digital Ocean, GCP, or one of the dozens of other providers available, Terraform alleviates much of the burden of managing large amounts of cloud resources.
Terraform is a great tool for managing most, if not all, of your cloud based infrastructure. In keeping with modern DevOps principles, Terraform allows teams to easily define their Infrastructure as Code, allowing for Change Tracking via a common Source Control provider. Once you have your terraform files in Source Control, you can build your CI\CD pipeline to enable real time deployments of various forms of Cloud Based Infrastructure.
One thing Terraform does not do is configure your servers, nor does it need to. Many tools exist today to configure servers including; Ansible, SaltStack, Chef, Puppet, and DSC.
Coming from an Azure shop, we have been exploring using Azure Automation DSC to configure servers created with Terraform. There are currently a number of ways to onboard a VM to Azure Automation including using the portal or AzureRm PowerShell cmdlets.
We were originally planning on using the AzureRM PowerShell cmdlet in a Jenkins Build Step to onboard new VM’s once the Terraform scripts completed. We never really liked this solution though, so we decided to dig a little deeper.
What we really wanted was for the DSC configuration to be applied as soon as the VM was created. We decided to focus our effort on the azurerm_virtual_machine_extension in Terraform since there is an existing extension for DSC.
However, when configuring the extension via Terraform, which is using Azure Resource Templates behind the scenes, configuration was not so simple and straightforward. It took more than a few tries to figure out the correct set of values to pass to the extension in order to configure it.
While the following is indeed a correct signature for the DSC Extension;
Filling in appropriate values for the ModulesUrl, SasToken and ConfigurationFunction does not actually work. While the DSC extension is installed on the VM, it is not registered with the Azure Automation service and it can cause your Terraform Apply to get stuck and never finish.
To get around this originally, we were downloading a DSCMetaConfig to our server, then configuring it with a CustomScriptExtension. Though this first pass did work, it was kind of slow and had the side-effect of configuring the VMs in a way that would cause us to be charged by Azure;
Eventually though we able to figure out the proper set of configuration values such that not only could we configure and onboard a VM with one vm extension, but we could also ensure that we did not incur additional costs from Azure.
Complete Scripts
Below are the full Terraform scripts we use to onboard Windows and Linux VMs to Azure Automation using Terraform.
Windows Virtual Machine
The azurerm_virtual_machine_extension has a depends_on value which should be set to the name of your VM resource. This is needed to ensure that the VM Extension is installed AFTER your VM has been created.
Linux Virtual Machine
A Linux VM can also be automatically registered with Azure Automation DSC, though the process is a little different. DSC on Linux requires that VMs have the Open Management Infrastructure (OMI) and DSC packages installed first. Once these two packages are installed, a python script can be called which will register the VM with a Pull Server, which is our Azure Automation account in this case.
The following script performs this configuration automatically;
We save this script to a secure Blob Storage within Azure, then download and execute it with the following Terraform config.
Just like the VM Extension for windows, this one has a depends_on value to ensure that the extension is installed after the VM is created.
Azure Automation Credentials
Each of these VM Extensions requires us to supply values for the RegistrationUrl and registrationKeyPrivate. Each also allows for supplying the name of a DSC NodeConfiguration.
The RegistrationUrl and registrationKeyPrivate are found on the Keys blade under the Account Settings section of your Azure Automation configuration.
In Conclusion
Terraform is a great tool for provisioning your infrastructure. In a Microsoft Shop, DSC is a powerful tool for configuring your servers. Combing the two together can ease the burden of managing vast amounts of infrastructure.
Hopefully this article has helped you learn how to automatically onboard a new Virtual Machine to Azure Automation DSC.