- Published on
Azure Export for Terraform: A Comprehensive How-To Guide
- Authors
- Name
- Saif Segni
Introduction
Azure Export for Terraform is a tool designed to help reduce friction in translation between Azure and Terraform concepts.
Azure Export for Terraform exports supported resources into Terraform state and generate the corresponding Terraform configuration.It is possible to import into Terraform (or export from Azure, hence the name) a single resource, resources from a resource group, or a set of customizable resources.
In this demo , I will show you how to install Microsoft Azure Export for Terraform, and important existing Azure resources and discuss some best practices and limitations of the tool.
Prerequisites
- An Azure account and subscription .
- Terraform installed on your machine with version >= v0.12.
- Azure CLI installed on your machine .
- Azure profile configured within Azure CLI to read resources in your Azure subscription .
Install Microsoft Azure Export for Terraform
For an installation with apt , you must carry out the following steps:
- Import the Microsoft repository key:
$ curl -sSL https://packages.microsoft.com/keys/microsoft.asc > /etc/apt/trusted.gpg.d/microsoft.asc
- Add packages-microsoft-com-prod repository:
ver=20.04 # or 22.04
$ apt-add-repository https://packages.microsoft.com/ubuntu/${ver}/prod
- Install:
$ apt-get install aztfexport
- Verify the installation :
aztfexport -v
aztfexport version v0.14.0(fb772ba)
- Check the help
$ aztfexport -h
NAME:
aztfexport - A tool to bring existing Azure resources under Terraform's management
USAGE:
aztfexport <command> [option] <scope>
VERSION:
v0.14.0(fb772ba)
COMMANDS:
config Configuring the tool
resource, res Exporting a single resource
resource-group, rg Exporting a resource group and the nested resources resides within it
query Exporting a customized scope of resources determined by an Azure Resource Graph where predicate
mapping-file, map Exporting a customized scope of resources determined by the resource mapping file
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
Import Existing Resources
For this demo , I will use an azure resource group called “my-rg-test01”
$ az group show --name my-rg-test01
{
"id": "/subscriptions/***************/resourceGroups/my-rg-test01",
"location": "francecentral",
"managedBy": null,
"name": "my-rg-test01",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"env": "test"
},
"type": "Microsoft.Resources/resourceGroups"
}
Inside this resource group , I have create a virtual netwok “my-vnet-test01” with two subnets : default and my-subnet-test01
Now let’s use the aztfexport command to import this resource and manage it with teraform :
$ aztfexport resource-group my-rg-test01
After the tool initializes, a list of the resources to be exported is displayed. Each line has an Azure resourceID matched to the corresponding AzureRM resource type.
The list of available commands displays at the bottom of the display.Press w to run the export.
Verify the results
If we check our directory , We will find files that have been created
$ tree
.
├── aztfexportResourceMapping.json
├── main.tf
├── provider.tf
├── terraform.tf
└── terraform.tfstate
0 directories, 5 files
We can see the terraform configruation block for our resource group , vnet and the two subnets
- In the provider.tf file, we have the bare minimum, as our authentication method is az cli ,even for the terraform.tf file which automatically selects a provider version.
- The terraform.tfstate file which clearly shows that our state is, at this stage, still local
- The aztfexportResourceMapping.json file that mapp your azure resource id with the terraform id
Terraform workflow
Finally let’s run the Terraform workflow :
$ terraform init
$ terraform plan
azurerm_virtual_network.res-1: Refreshing state... [id=/subscriptions/********************/resourceGroups/my-rg-test01/providers/Microsoft.Network/virtualNetworks/my-vnet-test01]
azurerm_resource_group.res-0: Refreshing state... [id=/subscriptions/********************/resourceGroups/my-rg-test01]
azurerm_subnet.res-3: Refreshing state... [id=/subscriptions/********************/resourceGroups/my-rg-test01/providers/Microsoft.Network/virtualNetworks/my-vnet-test01/subnets/my-subnet-test]
azurerm_subnet.res-2: Refreshing state... [id=/subscriptions/********************/resourceGroups/my-rg-test01/providers/Microsoft.Network/virtualNetworks/my-vnet-test01/subnets/default]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
The terminal outputs No changes needed !The infrastructure and its corresponding state have been successfully exported to Terraform.
Tips
- In case of remote tfstate , use the — backend-type & — backend-config value options to define your backend configuration
- In case of importing one azure resource , you need to specify the resource id (aztfexport resource [option] resource-id )
- For a non-interactive resource, add the — non-interactive flag: aztfexport rg — non-interactive myResourceGroup.
- Save the mapping file and import resources based in this mapping file (aztfexport mapping-file [option] resource-mapping-file )
- To import and add resource to an existant state file , use — append option
- Use the — hcl-only to generates HCL code (and mapping file), but not the files for resource management (e.g. the state file).
Limitations
- Microsoft Azure Export for Terraform doesn’t generate variable files, everything is defined in a static way.
- The tool currently declares dependencies explicitly. You must know the mapping of the relationships between resources to refactor the code to include any implicit dependencies.
- Certain properties within AzureRM are write-only and aren’t included in the generated code that Azure Export for Terraform creates. The issue is addressed by defining the property after exporting to HCL code.
- Certain resources in Azure can be defined as either a property in a parent Terraform resource or an individual Terraform resource. One example is a subnet. Azure Export for Terraform defines the resource as an individual resource,but it’s best practice to match your existing coding configuration.
that’s all folks 👏 thanks for reading 🙏