Terraform
Import
Note: Import blocks are only available in Terraform v1.5.0 and later.
Experimental: While we do not expect to make backwards-incompatible changes to syntax, the -generate-config-out
flag and how Terraform processes imports during the plan stage and generates configuration may change in future releases.
Use the import
block to import existing infrastructure resources into Terraform, bringing them under Terraform's management. Unlike the terraform import
command, configuration-driven import using import
blocks is predictable, works with CICD pipelines, and lets you preview an import operation before modifying state.
Once imported, Terraform tracks the resource in your state file. You can then manage the imported resource like any other, updating its attributes and destroying it as part of a standard resource lifecycle.
The import
block records that Terraform imported the resource and did not create it. After importing, you can optionally remove import blocks from your configuration or leave them as a record of the resource's origin.
Syntax
You can add an import
block to any Terraform configuration file. A common pattern is to create an imports.tf
file, or to place each import
block beside the resource
block it imports into.
import {
to = aws_instance.example
id = "i-abcd1234"
}
resource "aws_instance" "example" {
name = "hashi"
# (other resource arguments...)
}
The above import
block defines an import of the AWS instance with the ID "i-abcd1234" into the aws_instance.example
resource in the root module.
The import
block has the following arguments:
to
- The instance address this resource will have in your state file.id
- A string with the import ID of the resource, or an expression that evaluates to a string.provider
(optional) - An optional custom resource provider, see The Resource provider Meta-Argument for details.
If you do not set the provider
argument, Terraform attempts to import from the default provider.
Import ID
The import block's id
argument can be a literal string of your resource's import ID, or an expression that evaluates to a string, such as var.instance_id
. Terraform needs this import ID to locate the resource you want to import.
The import ID must be known at plan time for planning to succeed. If the value of id
is only known after apply, terraform plan
will fail with an error.
The identifier you use for a resource's import ID is resource-specific. You can find the required ID in the provider documentation for the resource you wish to import.
Import multiple instances with for_each
Multiple resource instances can be imported via a single import
block using the for_each
argument. The for_each
argument accepts a collection to iterate over, and results in an each
iterator in the same manner as it does for dynamic
blocks. The for_each
argument must be entirely known for the import plan to succeed, and for_each
cannot be used when generating configuration.
The resulting each.key
and each.value
values can be used both in the id
expression, and within index expressions in the to
argument. This allows the mapping of multiple instances to expanded resources:
locals {
buckets = {
"staging" = "bucket1"
"uat" = "bucket2"
"prod" = "bucket3"
}
}
import {
for_each = local.buckets
to = aws_s3_bucket.this[each.key]
id = each.value
}
resource "aws_s3_bucket" "this" {
for_each = local.buckets
}
The same process can also be used to expand the imports across multiple module instances:
locals {
buckets = [
{
group = "one"
key = "bucket1"
id = "one_1"
},
{
group = "one"
key = "bucket2"
id = "one_2"
},
{
group = "two"
key = "bucket1"
id = "two_1"
},
{
group = "one"
key = "bucket2"
id = "two_2"
},
]
}
import {
for_each = local.buckets
id = each.value.id
to = module.group[each.value.group].aws_s3_bucket.this[each.value.key]
}
Plan and apply an import
Terraform processes the import
block during the plan stage. Once a plan is approved, Terraform imports the resource into its state during the subsequent apply stage.
To import a resource using import
blocks, you must:
- Define an
import
block for the resource(s). - Add a corresponding
resource
block to your configuration , or generate configuration for that resource. - Run
terraform plan
to review how Terraform will import the resource(s). - Apply the configuration to import the resources and update your Terraform state.
Hands-on: Try the State Import tutorial.
The import
block is idempotent, meaning that applying an import action and running another plan will not generate another import action as long as that resource remains in your state.
Terraform only needs to import a given resource once. Attempting to import a resource into the same address again is a harmless no-op. You can remove import
blocks after completing the import or safely leave them in your configuration as a record of the resource's origin for future module maintainers. For more information on maintaining configurations over time, see Refactoring.
Resource configuration
Before importing, you must add configuration for every resource you want Terraform to import. Otherwise, Terraform throws an error during planning, insisting you add resource configuration before it can successfully import. You can create resource configuration manually or generate it using Terraform.
We recommend writing a resource
block if you know what most of the resource's arguments will be. For example, your configuration may already contain a similar resource whose configuration you can copy and modify.
We recommend generating configuration when importing multiple resources or a single complex resource that you do not already have the configuration for.
Add a resource
block
Add a resource
block for the resource to import. The resource address must match the import block's to
argument.
import {
to = aws_instance.example
id = "i-abcd1234"
}
resource "aws_instance" "example" {
name = "renderer"
}
Generate configuration
Terraform can generate HCL for resources that do not already exist in configuration. For more details, see Generating Configuration.
Examples
The following example demonstrates how to import into a module.
import {
to = module.instances.aws_instance.example
id = "i-abcd1234"
}
The below example shows how to use the value of a variable as the import ID.
import {
to = aws_instance.example
id = var.instance_id
}
The below example shows how to import a resource that includes count
.
import {
to = aws_instance.example[0]
id = "i-abcd1234"
}
The below example shows how to import a resource that includes for_each
.
import {
to = aws_instance.example["foo"]
id = "i-abcd1234"
}
Finally, the below example demonstrates how to import from a custom resource provider.
provider "aws" {
alias = "europe"
region = "eu-west-1"
}
import {
provider = aws.europe
to = aws_instance.example["foo"]
id = "i-abcd1234"
}