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.yamlThe 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\infraNext, we must initialize the Terraform CLI.
terraform -chdir=C:\Users\dkschrute\source\repos\azure-website\infra init -upgradeNow 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/subnet1Let’s break down the extra arguments required.
- -chdir – This tells the Terraform CLI where to find your Terraform module files (the
*.tffiles) - -var-file – This tells the Terraform CLI where to find the
main.tfvars.jsonfile. This file has the values that will get passed in as variables. We need to reference the one in the.azuredirectory instead of the original one in theinfradirectory 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.