[Webinar] How to Boost Developer Productivity with Policy-Driven IaC

➡️ Register Now

Terraform

How to Use Terraform Import Block for Importing Resources

what is terraform import block

Subscribe to our Newsletter

Mission Infrastructure newsletter is a monthly digest of the latest posts from our blog, curated to give you the insights you need to advance your infrastructure game.

With Terraform 1.5 and later, you can use the import block to manage the import of resources directly in your configuration. This feature simplifies the process of importing existing infrastructure into Terraform state, eliminating the need for a separate CLI terraform import command.

In this article, we explain the import block and how to use it to import different resources.

What is a Terraform import block?

The Terraform import block introduced in Terraform v1.5.0 provides a declarative approach for importing existing infrastructure resources into a Terraform state file. It allows resource imports to become an integral part of Terraform’s planning process — similar to other managed resources — rather than being treated as a direct state operation. 

As a result, the import block improves transparency and aligns resource imports with the core principles of infrastructure as code (IaC), enabling users to manage their infrastructure more effectively and predictably. 

The syntax for an import block in Terraform is as follows:

import {
  to = <resource_address>
  id = <resource_identifier>
}
  • to: Specifies the resource address in your configuration where the imported resource will be mapped. 
  • id: Defines the unique identifier of the existing resource in the provider’s API. Ensure that your Terraform provider is correctly configured to access the resource being imported.

Note that some resource types may have additional requirements or constraints for importing.

Import block vs. terraform import command

An import block in Terraform lets you define resources directly in your configuration file, simplifying the management of existing infrastructure.

In contrast, when the terraform import command is used without an import block, it links an existing resource to the Terraform state but does not automatically generate the corresponding configuration in your code. You must manually add this configuration afterward. The import command is particularly useful for one-time imports or transitioning infrastructure into Terraform management.

Both methods require careful handling to ensure consistency between the Terraform state and the actual infrastructure. Import blocks are generally better suited for ongoing resource management, whereas the standalone command works well for occasional imports.

Read more: Importing Existing Infrastructure Into Terraform

Example 1: Using Terraform import block to import an S3 bucket

Let’s suppose we have an existing AWS S3 bucket (my-existing-bucket) that you want to manage with Terraform.

The resource block specifies the S3 bucket (aws_s3_bucket.example) and the bucket attribute defines the name of the existing bucket:

resource "aws_s3_bucket" "example" {
  bucket = "my-existing-bucket"
}

import {
  to = aws_s3_bucket.example
  id = "my-existing-bucket"
}

The import block links the existing S3 bucket to the Terraform resource. 

  • to: Maps the imported resource to the address of the resource block (aws_s3_bucket.example)
  • id: Specifies the unique ID of the bucket (my-existing-bucket).

When you run terraform plan, Terraform reads the import block, checks the state of the existing S3 bucket, and shows a preview of the changes it will make to the state file. Then, after we run terraform apply, Terraform updates the state file to include the existing bucket, mapping it to the aws_s3_bucket.example resource.

After running terraform apply and successfully importing the resource, it is a best practice to remove the import block. Keeping it won’t cause any harm, but removing it helps maintain a clean configuration and minimizes potential confusion during future state management.

Example 2: Using Terraform import block to import an EC2 instance

Let’s consider another example: We have an existing EC2 instance with the ID i-1234567890abcdef0 and want to bring it under Terraform management.

We define the aws_instance resource we want Terraform to manage in the resource block. Make sure the attributes (e.g., ami, instance_type) match the existing instance’s configuration:

resource "aws_instance" "example" {
  ami           = "ami-0abcdef1234567890"  # Replace with the actual AMI ID
  instance_type = "t2.micro"
}

import {
  to = aws_instance.example
  id = "i-1234567890abcdef0"
}

In the import block:

  • to: Maps the resource in your configuration (aws_instance.example) to the existing resource.
  • id: Specifies the unique ID of the EC2 instance you are importing.

Once you add the resource block and the import statement to your Terraform configuration file, run terraform plan to preview the changes. Next, run terraform apply to import the resource into Terraform’s state file.

After the import, Terraform will manage the existing EC2 instance, ensuring its configuration remains declarative.

Example 3: Using Terraform import block to import an Azure Resource Group

In the next example, we will be importing an Azure Resource Group.

We have an existing Azure Resource Group named example-resource-group in the East US region, and we want to manage it with Terraform.

First, in the resource block we define the azurerm_resource_group resource that Terraform will manage:

resource "azurerm_resource_group" "example" {
  name     = "example-resource-group"
  location = "East US"
}

import {
  to = azurerm_resource_group.example
  id = "/subscriptions/<subscription_id>/resourceGroups/example-resource-group"
}

The import block:

  • to: Maps the resource in your configuration (azurerm_resource_group.example) to the existing Azure resource.
  • id: Specifies the fully qualified Azure resource ID of the resource group. Remember to replace <subscription_id> with your actual subscription ID.

Add the resource and the import block to your Terraform configuration file. Next, run the terraform plan command to preview the changes and execute terraform apply to apply the changes and import the resource into Terraform’s state file.

Can you use the Terraform import block conditionally?

The Terraform import block is designed to be declarative and requires specific values known at plan time. Therefore, it cannot be used conditionally within your Terraform code

The import block does not support dynamic expressions or variables for determining the import ID based on conditions. Attempts to use constructs like count or variables within the import block will result in errors, as Terraform does not allow such arguments in this context.

Deploying Terraform resources with Spacelift

Spacelift is a wonderful tool if you need help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine. 

Spacelift can optionally manage the Terraform state for you, offering a backend synchronized with the rest of the platform to maximize convenience and security. It also enables you to import your state during stack creation, which is very useful for engineers who are migrating their old configurations and states to Spacelift.

It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box

If you want to learn more about Spacelift, create a free account today or book a demo with one of our engineers.

Key points

The introduction of the import block in Terraform 1.5+ simplifies resource management by enabling the direct import and definition of resources within configuration files. It aligns with IaC principles by reducing complexity and making it easier to integrate existing infrastructure into Terraform configurations.

Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.

Manage Terraform Better with Spacelift

Build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization and many more.

Learn more

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide