Azure Terraform Export: Importing Resources with Aztfexport
Tags: terraform, azure
Published: 2024-07-05 13:24:27

In this article, we will explore the `aztfexport` tool that can be used to bring existing Azure resources under Terraform's management. We will look at the tool itself, explaining what it is, what it does, and the typical workflow you will use with it. Then, we will move to a step-by-step setup tutorial with examples of how to use it. 

##What is the Azure Terraform Export tool (formerly Aztfy)?

`Aztfexport` is an open-source export tool created by Microsoft. It allows you to migrate existing Azure resources to [Terraform state files](https://spacelift.io/blog/terraform-state) using a single command to bring them under Terraform's control. The main benefit of this tool is consistent and automated resource management across all Azure environments. `Aztfexport` is also formerly known as `aztfy`.

Azure Terraform Export tool aims to take an existing resource group, individual resources, or a Graph query string from Azure and export it as Terraform code.

##Azure Terraform Export features and benefits

Benefits of using `aztfexport` features include:

-   Automated and simplified importing - `Aztfexport` streamlines the process of transitioning existing resources to Terraform. It enables the automatic import of existing resources into the Terraform state without having to do that separately. This also saves you the manual effort of creating Terraform configurations from scratch.
-   Improved IaC - By exporting Azure resources to Terraform, you embrace the IaC paradigm. Changes to your infrastructure become declarative, version-controlled, and reproducible.
-   Easy integration - `Aztfexport` seamlessly integrates with your existing Terraform workflows. You can incorporate the exported resources into your existing Terraform projects.
-   Community support -  `Aztfexport` is part of the Azure community ecosystem. There, you can find support, contribute, and collaborate with other users.

##Aztfexport workflow

Now, let's explore how does the Azure Export tool operate with Terraform and the workflow it follows when exporting resources.

1.  Identify which existing Azure resources you want to export.
2.  Decide whether to export the Azure resources into the Terraform state, or generate HCL code.
3.  Install `aztfexport` (see the section below[link] for this). Execute commands specifying the resource to be exported.
4.  Inspect the generated Terraform code and make any necessary adjustments, such as adding variables, modules, or customizations.
5.  Integrate the exported resources into your existing Terraform project. Once imported into the state, you can use Terraform commands (e.g., terraform plan, terraform apply) to manage the resources.

`Aztfexport` leverages another tool called [Aztft](https://github.com/magodo/aztft) to identify the Terraform resource type corresponding to an Azure resource ID. 

`Aztft` is a Go program and library that identifies the correct Terraform AzureRM provider resource type on the Azure resource ID. It then runs [Terraform import ](https://spacelift.io/blog/importing-exisiting-infrastructure-into-terraform)under the hood to import each resource into Terraform.

After importing, aztft uses tfadd to generate the Terraform HCL code for each imported resource. [Tfadd](https://github.com/magodo/tfadd) is another Go program and library for generating Terraform configuration from the Terraform state.

💡 You might also like:

-   [How to Manage DynamoDB Tables With Terraform](https://spacelift.io/blog/terraform-dynamodb)
-   [Terraform with Azure DevOps CI/CD Pipelines](https://spacelift.io/blog/terraform-azure-devops)
-   [How to Migrate Terraform State Between Different Backends](https://spacelift.io/blog/terraform-migrate-state)

##How to use Aztfexport?

In this tutorial section of the article, we will show you how to install Aztfexport and use it to export existing Azure resources to Terraform.

### 1\. Prerequisites

-   An Azure subscription containing some existing resources.
-   `aztfexport`requires a Terraform executable installed in your $PATH with a version greater than or equal to v0.12.

### 2\. Install Azure Export for Terraform

You can install `aztfexport` for various platforms like Windows, Linux, macOS, Ubuntu, Red Hat Linux, and Go Toolchain.

#### Windows

To install Azure Export on Windows, run:

```
winget install aztfexport
```

![](https://spacelift.io/_next/image?url=https%3A%2F%2Fspaceliftio.wpcomstaging.com%2Fwp-content%2Fuploads%2F2024%2F05%2Fazure-terrafy-windows.webp&w=3840&q=75)

Precompiled binaries and Windows MSI are also available in the [Releases](https://github.com/Azure/aztfexport) on GitHub.

#### Linux / MacOS:

To get `aztfexport` on Linux or MacOS run:

```
brew install aztfexport
```

#### Ubuntu 20.04 or 22.04

The Azure Export installation process for Ubuntu is as follows:

```
#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
```

#### Red Hat Linux 8 or 9

To install `aztfexport` on Red Hat Linux 8 or 9, follow the process below:

```
#Import the Microsoft repository key:

rpm --import https://packages.microsoft.com/keys/microsoft.asc

#Add packages-microsoft-com-prod repository:

ver=8 # or 9
dnf install -y https://packages.microsoft.com/config/rhel/${ver}/packages-microsoft-prod.rpm

#Install:

dnf install aztfexport
```

#### Go Toolchain

This command installs the Azure Export for Terraform with Go:

```
go install github.com/Azure/aztfexport@latest
```

### 3\. Create Azure resources

In this example, we will create a resource group named `my-rg-test01`. Inside this resource group, we will create a virtual network named `my-vnet-test01` with two subnets: `default` and `my-subnet-test01`.

To do this, go to the Azure portal, search for virtual networks, and hit 'create virtual network'. Create a new resource group called `my-rg-test01` and specify the name as `my-vnet-test01`. We have selected the region as (Europe) UK South.

![azure terraform export tool portal](https://spacelift.io/_next/image?url=https%3A%2F%2Fspaceliftio.wpcomstaging.com%2Fwp-content%2Fuploads%2F2024%2F05%2Fazure-terraform-export-tool-portal.webp&w=3840&q=75)

Hit Next, and on the IP addresses tab, enter the address space as 10.0.0.0/16 (default) and create two subnets. One called 'default' with address 10.0.1.0/24, and the other called my-subnet-test01 with address space 10.0.2.0/24.

![aztfexport example](https://spacelift.io/_next/image?url=https%3A%2F%2Fspaceliftio.wpcomstaging.com%2Fwp-content%2Fuploads%2F2024%2F05%2Faztfexport-example.webp&w=3840&q=75)

Press 'review and create' and then finally 'create'.

### 4\. Export the Azure resource

The syntax for the `aztfexport` command is shown below:

```
aztfexport [command] [option] <scope>
```

There are three options for the command, `resource`, `resource-group`, or `query`. They can be used depending on what you need to export. Note that the `resource-group` option also exports the nested contents.

For example, to export the resource group and its nested resources:

```
aztfexport resource-group my-rg-test01
```

After running this command, `aztfexport` will initialize and display a list of the resources to be exported.

You can also use an Azure graph query such as the one below to export the network resources:

```
aztfexport query -n "resourceGroup =~ 'my-rg-test01' and type contains 'Microsoft.Network'"
```

### 5\. View the results

The exported resources will be converted into Terraform code. We've successfully imported the infrastructure to Terraform! 

You'll find a `.aztfexport` suffix added to the generated files (e.g., `main.aztfexport.tf`) to avoid potential filename conflicts.

Now, let's inspect the generated Terraform code and make any necessary adjustments. Incorporate the exported VNet resource into your existing Terraform project.

The result should look something like this:

```
provider "azurerm" {
  features {}
}

resource "azurerm_virtual_network" "my_vnet" {
  name                = "my-vnet-test01"
  address_space       = ["10.0.0.0/16"]
  location            = "UK South"
  resource_group_name = "my-rg-test01"

  subnet {
    name           = "default"
    address_prefix = "10.0.1.0/24"
  }

  subnet {
    name           = "my-subnet-test01"
    address_prefix = "10.0.2.0/24"
  }
}
```

### 6\. Clean up

To avoid unexpected costs, don't forget to remove the test resources you created from the portal.

##Azure Terraform Export limitations

There are some limitations that come with the Azure Terraform export tool. For example:

-   The Terraform configurations generated by `aztfexport` are not meant to be comprehensive and do not ensure that the infrastructure can be fully reproduced from said generated configurations.
-   It only works with Azure resources.
-   Azure Export for Terraform is currently able to declare only explicit dependencies. You must know the mapping of the relationships between resources to refactor the code to include any needed implicit dependencies.

##Key points
`aztfexport` aims to make life simpler when bringing existing Azure resources under Terraform control by generating the code for them and bringing them into Terraform state management automatically.

We encourage you also to explore [how Spacelift makes it easy to work with Terraform](https://docs.spacelift.io/). If you need any help managing your Terraform infrastructure or building more complex workflows based on Terraform and other IaC tools, Spacelift is a fantastic tool for this. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box. 

If you want to learn more about Spacelift working with Azure, check our [documentation](https://docs.spacelift.io/integrations/cloud-providers/azure) or [book a demo with one of our engineers](https://spacelift.io/schedule-demo).

_Written by Jack Roper._