Terraform Import
Introduction to Terraform import
The Terraform import operation lets you add existing resources into your Terraform state. This is helpful if you have resources created outside of Terraform (using the cloud portal, or another tool) and want to manage them with Terraform. Importing these resources allows Terraform to track and manage their state, simplifying the management of your infrastructure.
The Terraform import operation can be done using two methods:
- Using the CLI command
- Using the import block
In the rest of this section we’ll go over each method and show the difference between them.
Terraform import CLI command
Introduced in Terraform 0.7, the terraform import
CLI command was the first way to bring existing resources under management by Terraform. The process has two main steps:
- Import the resource in the state file.
- Update the Terraform configuration file to define the newly imported resource.
Import steps
The first step is relatively simple: The command works by passing the resource address and resource ID as command line arguments. Once the command has completed successfully, the Terraform state file is updated with the imported resource.
The second step is more complex. It is an iterative process where the practitioner will run a terraform plan
command, identify the missing attribute values (by leveraging the provider’s documentation), and add those values to the resource block. This iterative process is repeated until the terraform plan
command returns that no changes are needed. At that point, the resource definition in the code matches the state of the resource as deployed.
Until that second step is completed, it is critical that no terraform apply
operation be attempted on this resource. If that was the case Terraform would at best attempt to reconfigure the resource in-place, and at worst delete the resource and re-create it based on the code. Both outcomes are not what you want.
An import example
Here is an example of an AWS EC2 instance import. Identify the EC2 instance to import, including its ID:
Then, write a Terraform configuration file with a resource block for the imported EC2 instance:
provider "aws" {
}
resource "aws_instance" "example" {
ami = "ami-0c101f26f147fa7fd"
instance_type = "t3.micro"
tags = {
Name = "HelloWorld"
}
}
Run the import command to add the EC2 instance into the state file:
terraform import aws_instance.example i-01ddb56f1c97a17e5
aws_instance.example: Importing from ID "i-01ddb56f1c97a17e5"...
aws_instance.example: Import prepared!
Prepared aws_instance for import
aws_instance.example: Refreshing state... [id=i-01ddb56f1c97a17e5]
Import successful!
The imported resources are shown above. These resources are now in the Terraform state and will be managed by Terraform going forward.
This simple example shows that there are many resource attributes that need to be accounted for before the EC2 instance can be considered fully manageable by Terraform. You will likely be dealing with more complex cases, where the attributes to configure will not be limited to the `instance_type`, `tags`, and `user_data_replace_on_change`.
## Terraform import block
The CLI import method, while simple to use, can be time-consuming and carries risk if not handled carefully. Terraform 1.5.0 introduced the `import` block to address these issues by:
* Allowing you to declare the resources to import in the Terraform configuration.
* Enabling you to import resources in bulk.
* Making the import process plannable, so you can see what will be imported before applying.
* Adding a subcommand to generate the configuration for imported resources.
### The import steps
The import steps when using the Terraform import block are documented in the following tutorial: [Import Terraform configuration](https://developer.hashicorp.com/terraform/tutorials/state/state-import).
After you’ve completed the import steps outlined in the tutorial, the once externally-managed resources are now managed by Terraform, and their resource blocks are configured accurately.
At that point, the only purpose of the import block in your codebase is as a record that Terraform imported the resource and did not create it. You may choose to remove the import block from your configuration if keeping a record of the import is not useful to you. If not then keeping it in the code is also fine.
## A comparison of the two methods
The table below provides a comparison of the two methods, helping you understand the differences:
| Characteristic | Terraform import command | Terraform import block |
| ---------------| ------------------------ | ---------------------- |
| How many resources can be imported at once? | One resource per command execution. | One or more resources per command execution. |
| Where is the resource ingested? | The resource is added to the Terraform state file | The resource is first added to the configuration and then added to the Terraform state (and marked as imported). |
| Is writing resource configuration required? | Yes | Yes, but the process is greatly sped up by the `-generate-config-out` subcommand. |
| Driven by? | The practitioner (manually). | Configuration and the Terraform workflow. |