‘Reverse Engineering’ Azure to Terraform
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. Terraform has great support for Azure, and it’s capabilities are being added to frequently see link
Configuration files describe to Terraform the components needed to run a single application or your entire Azure subscription. Terraform generates an execution plan describing what it will do to reach the desired state (terraform plan) , and then executes (terraform apply) it to build the described infrastructure in Azure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.
The above is taken form the Terraform website and Terraform is a great tool for creating new Azure Infrastructure and has some real advantages, notably the terraform plan capabilities and the simple elegant configuration language used to describe the infrastructure.
One problem with Terraform though is: What if you already have a Azure deployment you have built with ARM templates , PowerShell, cli2 or by just using the portal, how can you bring these under the control of terraform ?
Terraform Import Challenges
A partial answer to this problem is to use a “terraform import” command that allows you to import the current state of an Azure resource, but there are a few problems with this approach:
- Multiple terraform imports have to be performed, referencing the correct full Azure resource ID.
- You have to create a “stub” terraform configuration file for each of the resources before the import will work
- The terraform stub file will have lots of information/parameters missing and does not represent your current infrastructure
- You have to pay close attention to naming conventions as many Azure resources are interlinked. For example for a single VM you may have NIC(s), Public IP(s), NSG(s) , VNET, Subnet(s) , Route Table(s), Managed Disk(s) and A Storage Account for diagnostics. All these have to be consistently named as they will be cross-referenced in the terraform configuration files
- A terraform plan command will likely show you there is much work to be done editing in all the missing information into your terraform configuration files.
The ‘az2tf’ Tool
What is needed is a tool that will read your current Azure deployment and automatically creates fully populated terraform configuration files and perform the corresponding ‘terraform import’ commands.
A subsequent ‘terraform plan’ command should report zero additions/deletions are required to the infrastructure and ideally zero ‘changes’ (The later is hard to achieve due to transient bugs and inconsistencies in how some string values are handled – but they are being worked through.).
This neutral output from the terraform plan command will give confidence that the automatically generated terraform configuration file are an accurate representation of the existing infrastructure within Azure.
A tool that can achieve the above called “az2tf” and is freely available on github here
This is written in a number “bash” shell scripts (one for each terraform provider) called from a master script ‘az2tf.sh’ and is intended to be run form the Terraform marketplace image:
https://docs.microsoft.com/en-us/azure/terraform/terraform-vm-msi
The tool is “use at your own risk” – but as it makes no changes to Azure and simply reads information , generates config files and runs a terraform plan it’s safe to use on any Azure subscription.
Using the ‘az2tf’ tool
Ensure you have setup and authorised both terraform and Azure cli2 correctly for your subscription (you’ll need read access – and also access (list, read) to any KeyVaults you use)
Download ‘az2tf’ or clone from github into an empty directory on your terraform vm
Run from the command line:
./az2tf.sh -s <your subscription id>
or
./az2tf.sh -s <your subscription id> -g <a resource group name>
Wait patiently – it’s slow – but good 🙂
As it runs it will:
- Create a new sub directory tf.<your subscription id>
- You’ll then see it looping around the terraform providers generating terraform config files and performing terraform imports.
- For the final step it runs a terraform plan command
More details on the project page README.md on github
As this is a ‘hobby project’ there will be issues as a tool like this will need extensive testing to find all the edge cases, so check back regularly on github for updates and also for support of new azurerm terraform providers.
Part 2 (tbd) will go on the talk about how the tool was put together, using the primary tools – Azure cli2 ,bash (particularly jq and printf).