How to import Azure resources into your Terraform state file when using the Azure Developer CLI

Terraform is a great Infrastructure as Code tool for managing your Azure resources. The Azure Developer CLI is a great tool for managing your entire application lifecycle (build, infrastructure setup & application deployment).

Normally, you can use azd up or azd provision to execute the Terraform code associated with your Azure Developer CLI directory. This will run the various Terraform CLI commands for you and manage the state file.

However, if there are existing resources in your Azure environment, Terraform will fail with the following error:

Error: A resource with the ID "/subscriptions/cfnot2-a512-real-sub1-b3GUIDa44/resourceGroups/rg-azure-website/providers/Microsoft.Network/virtualNetworks/vnet-mgznotrealgzjm/subnets/subnet1" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_subnet" for more information.

Normally, you would run the terraform import command to bring these resources into your Terraform state file. However, since the Azure Developer CLI is the one running your Terraform CLI commands, it is not obvious how to do the import.

By running the azd provision --debug command, I was able to see the underlying commands that the Azure Developer CLI is running. These include some extra flags on the Terraform CLI commands to understand the Azure Developer CLI directory structure.

Your Azure Developer CLI directory structure (filtered to just the parts related to Terraform) looks like this:

/
----.azure
--------azure-website
------------infra
----------------main.tfvars.json
----------------terraform.tfstate
----infra
--------modules
------------virtual_network
----------------main.tf
--------main.tf
--------main.tfvars.json
--------providers.tf
--------variables.tf
----src
----azure.yaml

The azd provision command is run from the root directory. However, the state file is stored inside a directory with the same name as the Azure Developer CLI environment you created. We need to reference both this directory and the directory where the actual Terraform *.tf files are located.

We must also run the Terraform commands in the same order that the Azure Developer CLI does.

First, navigate to the directory where the Azure Developer CLI originally stored the state file.

cd C:\Users\dkschrute\source\repos\azure-website\.azure\azure-website\infra

Next, we must initialize the Terraform CLI.

terraform -chdir=C:\Users\dkschrute\source\repos\azure-website\infra init -upgrade

Now we can do the import. Note that we will use the same ADDR (the path in the Terraform modules) & ID (the Azure resource ID) from the original error message. Also note that I am escaping the double quotes with a backtick since this is PowerShell; use a backslash in bash.

terraform -chdir=C:\Users\dkschrute\source\repos\azure-website\infra import -var-file=C:\Users\dkschrute\source\repos\azure-website\.azure\azure-website\infra\main.tfvars.json -state=C:\Users\dkschrute\source\repos\azure-website\.azure\azure-website\infra\terraform.tfstate module.virtual_network.azurerm_subnet.subnet[`"subnet1`"] /subscriptions/cfnot2-a512-real-sub1-b3GUIDa44/resourceGroups/rg-azure-website/providers/Microsoft.Network/virtualNetworks/vnet-mgznotrealgzjm/subnets/subnet1

Let’s break down the extra arguments required.

  • -chdir – This tells the Terraform CLI where to find your Terraform module files (the *.tf files)
  • -var-file – This tells the Terraform CLI where to find the main.tfvars.json file. This file has the values that will get passed in as variables. We need to reference the one in the .azure directory instead of the original one in the infra directory since some of the values comes from Azure Developer CLI environment variables.
  • -state – This tells the Terraform CLI where to find the local Terraform state file. Note that I am using a local state file.

Leave a Reply

Your email address will not be published. Required fields are marked *