How to import Azure resources into Terraform: step by step
Adopting Terraform in an Azure environment that already has manually created resources is a common challenge: you don't want to delete anything, you just want to start managing what already exists. Importing existing Azure resources into Terraform solves this — it brings your current infrastructure under code control without recreating it. This guide shows, step by step, how to use the terraform import command to bring an existing resource group into your Terraform state safely.
Prerequisites
- Terraform installed (version 1.5 or later recommended).
- Azure CLI installed and signed in with
az login. - Read permissions on the subscription and the resources you will import.
- An empty folder for the project and a text editor of your choice.
Step 1: Set up the provider and authenticate
Create a main.tf file and declare the azurerm provider. For learning, the simplest way to authenticate is to reuse the Azure CLI session, so first make sure you are on the right subscription.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
}
provider "azurerm" {
features {}
}
In the terminal, select the subscription and initialize the project:
az account set --subscription "SUBSCRIPTION-NAME-OR-ID"
terraform init
Step 2: Declare the resource block
The terraform import command does not generate code: it links a real resource to a block that must already exist in your configuration. So declare the resource first, even with only the essential attributes. We will use a resource group named rg-producao.
resource "azurerm_resource_group" "producao" {
name = "rg-producao"
location = "westeurope"
}
The name and location values must match exactly the resource that already exists in Azure, otherwise Terraform will propose recreating it.
Step 3: Get the resource ID in Azure
Every resource in Azure has a unique identifier. For the resource group, get it with the Azure CLI:
az group show --name rg-producao --query id --output tsv
The result has this format, and it is what you will use in the next step:
/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-producao
Step 4: Run terraform import
Now link the resource address in your code (azurerm_resource_group.producao) to the real ID you obtained. The address is the "internal name" in Terraform; the ID is the reference in Azure.
terraform import azurerm_resource_group.producao "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-producao"
If all goes well, the message Import successful! appears. The resource now exists in the state file (terraform.tfstate), although your code may still be incomplete.
Tip: the state can store sensitive values in plain text. Always use a secure remote backend (for example, an Azure Storage account) in real projects.
Step 5: Validate with terraform plan
Run a plan to compare your code with the state you just imported:
terraform plan
The goal is for the plan to propose no changes. If it does, it means your block is missing attributes (tags, for example) or some value differs from the real one. Adjust the code and repeat the plan until it is clean — this ensures Terraform will not modify or recreate the resource by accident.
Verify the result
Confirm the resource is really under Terraform management with two commands:
terraform state list
terraform state show azurerm_resource_group.producao
The first should list azurerm_resource_group.producao; the second shows every attribute stored in the state. When terraform plan returns No changes. Your infrastructure matches the configuration., the import is successfully complete.
Conclusion
You followed the full workflow: declare the block, get the ID, import, and validate with plan. From here you can bring all the manually created infrastructure into Terraform without the risk of recreating it. To import several resources at once, try the declarative import blocks (available since Terraform 1.5), which can even generate configuration with terraform plan -generate-config-out=generated.tf. Which resource in your subscription will be the first to enter Terraform?