(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisbon

How to import Azure resources into Terraform: step by step

João Barros 05 de July de 2026 4 min read

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?