Terraform is a great tool for defining your infrastructure using code and getting it deployed to Azure or your chosen cloud provider. One of the many challenges you may face is importing existing infrastructure into Terraform so that you can then manage it through code along with the benefits that come along with that.
You will often hear the term state file. Terraform must store state about your managed infrastructure and configuration. Thee state is used by Terraform to map real world resources in the cloud back to your configuration and to keep track of metadata.
This state is stored by default in a local file named
terraform.tfstate however it can also be stored remotely and more commontly in an Azure storage account as a blog which is often what's chosen by large scale enterprises to avoid having local state files.
There are usually 3 steps that typically need to be completed in order to import your cloud resource into Terraform using the process provided by Hashicorp:
- Define your infrastructure using Terraform.
- Run Terraform import to update your state file.
- Run Terraform plan to verify the import is successful.
This method is well defined in the Terraform docs.
In this tutorial we will be talking about a new tool called Azure Terrafy developed by Microsoft which aims to automate the import process by generating both the configuration and state file for your existing infrastructure making it much easier to get started with Terraform.
You can install Azure Terrafy using the Go Tool chain by running:
go install github.com/Azure/aztfy@latest
If you haven't got Go then you can install it by following the instructions on the official Go docs.
You can also manually download the latest Binary from the Azure Terrafy Github page.
Just make sure to update your environment path so you can run Terrafy from your chosen shell.
This Stack Overflow article contains instructions for setting the PATH on Windows through the user interface.
For Mac OS you can run
echo $PATH and place the executable/binary into one of the listed paths.
Verify you have it correctly installed by running
We are now ready to start importing our infrastructure into Terraform .
Before we start the import we need to get the environment ready. Let's deploy an Azure Resource Group and a static web app resource using the Azure CLI and try to import it into Terraform using Terrafy to prove the concept.
Create Azure Resource Group
az group create --location "uksouth" --name "terafform-import-rg" --subscription "7309f068-5a47-4a28-851c-09979529cd8e"
You should get an output in the CLI once the RG provisioning is successful:
Create an Azure Static Web App Resource
Let's create an Azure Static Web App in the RG we created:
az staticwebapp create \ -n terraform-import-webapp \ -g "terafform-import-rg" \
You should get an output in the CLI that the provisioning was successful. Validate the Static Web App is deployed by navigating to the Resource Group in the Azure Portal:
Set up a new directory
Set up a new directory/folder where you want to Terrafy to store the Terraform files. By default it uses the root directory however you can also override this with a custom path.
mkdir <folder-name> to create a new folder.
2: Navigate into the directory above
Import the Infrastructure using Terrafy
Make sure you have logged into Azure using by running
az login and set the subscription that contains the RG and web app created earlier by running
az account set -s <subscription_id>
1: Run the import command
Terrafy will begin the import process by scanning the RG and presenting you with a list of resources to import. Navigation instructions are given at the bottom of your shell window.
2: Select the resource you want to import. If you want to import all of them just hit W on your keyboard.
In this case we want to import all our resources (static web app and RG) so we are going to hit W on our keyboard.
Terrafy will begin the import process and the Terraform files will be stored in the root directory we created earlier. You will be prompted once import is complete:
We can see we now have our state and Terraform files. Viewing the main.tf file shows the definition for our static web app and resource group:
You should note that currently Azure Terrafy does not support all resource types so if you see "skip" listed next to the resource this means it cannot be imported.
The final step is to validate that the Terraform state has been imported successfully by running Terraform.
We can see that Terraform is reporting that no changes are required and that our infrastructure in Azure matches our configuration or desired state in Terraform.
You can also specify a remote backend before running aztfy:
aztfy --backend-type=azurerm --backend-config=resource_group_name=<resource group name> --backend-config=storage_account_name=<account name> --backend-config=container_name=<container name> --backend-config=key=terraform.tfstate <importing resource group name>
We have successfully imported our infrastructure into Terraform using Azure Terrafy!
- Currently the configuration is imported into a single main.tf files. Modules should be considered.
- Dependencies. Aztfy uses many of the dependencies in your resource group to map those out in the templates (see the 'depends_on' line declared in the main.tf above), much of that can be cleaned up once naming conventions and modules are implemented.
- Currently you can only import at the resource group level however support will be added for subscriptions and management groups.
- Not all resources are currently supported for the import process.
This is certainly a great start to fully automating the TF import process and the tool will develop and grow making it much easier for enterprises to get started in managing their existing infrastructure with Terraform.
The above import process can be fully automated by running all the tasks in a DevOps pipeline and specifying only the RG name. Terrafy supports non-interactive "batch" mode which is CI/CD friendly.