Terraform
Import an existing resource
You can import existing infrastructure resources into your Terraform state so that you can begin managing them using Terraform. This page describes how to write Terraform configuration for importing resources, which lets you import multiple resources at the same time and review the import as part of your Terraform workflow.
Hands-on: Try the State Import tutorial.
Overview
When you import existing infrastructure into state, you must also define the Terraform configuration corresponding to that resource to manage the rest of its lifecycle. You can manually write all of the configuration or use the Terraform CLI to generate configuration for resources your are importing. When you import resources, Terraform pulls all of the resource's attributes into the state file, but you do not need to define all of them in the resource
block.
We recommend manually writing the resource
block when you know how to configure all or most of the resource's arguments. Use generated configuration when importing multiple resources or a single complex resource that you do not already have the configuration for.
This page describes how to manually write all of your import configuration. Refer to Generate configuration for instructions on how to generate the configuration.
Complete the following steps to import resources:
- Define a destination resource configuration for each resource you want to import.
- Add a corresponding
import
block for each existing resource you want to import. - Run
terraform plan
and verify that the import plan meets your needs. - Apply the configuration to import the resources and update your Terraform state.
You can remove import
blocks from your configuration after importing resources, but we recommend keeping them as an historical artifact. Refer to Post import tasks for more information.
Define a destination resource
Terraform reconciles your configuration and state to create an execution plan. As a result, you must define a resource
block for any resource in state to prevent Terraform from destroying it. The only required arguments to the resource
block for an imported resource are the inline resource type and resource label, which form the Terraform state address.
The following example resource is the destination for an AWS instance with a resource address of aws_instance.example
:
resource "aws_instance" "example" {
name = "renderer"
}
You should include provider-specific resource arguments that have non-default values to prevent Terraform from destroying the imported resource on the next apply operation. Terraform uses default values for arguments you do not include in the resource
block. If Terraform assigns default values, but the existing resource has non-default attributes, the resource in state will not match the actual infrastructure, and Terraform will plan to update the resource on the next apply operation. Refer to the provider documentation for information about which arguments the resource you are importing supports.
Configure Terraform arguments
You can include meta-arguments to modify how Terraform manages your resources once imported into state. Meta-arguments are Terraform-specific arguments that establish explicit dependencies between resources and prevent destructive operations. Refer the resource
block reference for details about Terraform meta-arguments you can define.
Define an import
block
Add an import
block and specify the ID of an existing resource and destination resource address to import to. Cloud providers use different methods of identifying resources. As a result, the ID depends on your cloud vendor and the kind of resource you are importing. Refer to the provider documentation for the resource you want to import for details.
Use the following syntax to configure the import
block:
import {
to = TYPE.LABEL
id = "<RESOURCE-ID>"
}
resource "<TYPE>" "<LABEL>" {
# ...
}
The to
argument is the destination resource address, which is formed from the resource type and label.
The id
argument is an identifier specific to your cloud provider.
Refer to the import
block reference for details.
Import multiple instances
You can configure the destination resource
block to manage multiple instances of resource using the count
and for_each
meta-arguments. You can add a parameter to the value of the to
argument to specify which instance of the destination resource to import to.
For example, the count
block in the destination resource
block configuration instructs Terraform to import a set number of resource instances. As a result, you can include an index to the to
argument value to specify which instance to import the resource to.
In the following example, Terraform imports the resource into the instance at the 0
index:
import {
to = aws_instance.example[0]
id = "i-abcd1234"
}
resource "aws_instance" "example {
count = 2
#. . .
}
When the destination resource
block contains a for_each
argument, Terraform loops through a set of key-value pairs and imports an instance for each pair. In the following example, Terraform imports the resource into the instance with a env
key:
import {
to = aws_instance.example["env"]
id = "i-abcd1234"
}
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
for_each = {
env = "staging"
geo = "us"
}
# . . .
}
Import using a custom resource provider
By default, Terraform automatically selects the default provider configuration based on the resource type, but you can configure multiple instances of the same provider with aliases and use a non-default provider configuration to import specific resources. In the following example, Terraform imports to a destination resource
block that contains multiple instances according to the europe
provider configuration:
provider "aws" {
alias = "europe"
region = "eu-west-1"
}
import {
provider = aws.europe
to = aws_instance.example["env"]
id = "i-abcd1234"
}
resource "aws_instance" "example" {
provider = aws.europe
for_each = {
env = "staging"
geo = "us"
}
}
Import to a module
When the destination resource
block is in another module, add the module.<MODULE-NAME>
prefix to the resource address. In the following example, Terraform imports a resource into a resource
block in the instances
module:
main.tf
import {
to = module.instances.aws_instance.example
id = "i-abcd1234"
}
The following resource appears in the module address specified with the to
argument in the import
block:
instances/main.tf
resource "aws_instance" "example" {
# . . .
}
Plan and apply an import
After configuring the destination resource
block and the import
block, run terraform plan
and review the proposed plan. If Terraform proposes any unexpected changes to the resource, update its configuration until it matches your intended settings. When satisfied with the plan, run terraform apply
to import the resources and update your state.
When you apply a configuration with import
blocks, Terraform records that it imported the resources and that it did not create them.
Because the import
block is idempotent, applying an import action and running another plan does not generate another import action as long as that resource remains in your state. Furthermore, attempting to import a resource into the same address more than once has no impact.
Post import tasks
You can either remove import
blocks after you've imported them or 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, refer to Refactoring.