Terraform Import: What it is and how to use it

Terraform Import: What it is and how to use it blog post

Introduction

In this blog post, we will learn about the Terraform import command. There may have been times when someone from your team or you have created infrastructure manually outside of Terraform. The import command allows you to bring existing infrastructure resources under Terraform’s management.

We’ll start by understanding the basics of the terraform import command, including how to use it and the typical situations where it is functional. Then, we’ll compare terraform import with the terraform state mv command and discuss when to use each approach.

Next, we’ll do a hands-on example,by importing resources from an existing EC2 instance into a Terraform configuration and other AWS resources like VPC and IAM roles. We’ll also explore how to check the state file after the import process and analyze the plan output.

Finally, we’ll discuss how the terraform import command can be used to import everything in a Terrateam pipeline, making it a valuable tool for infrastructure management workflows.

Typical Scenarios for Using Terraform Import

  • Existing Infrastructure: You have resources created outside of Terraform and want to start managing them using Terraform.
  • Migrating from Other Tools: You’re moving from a different infrastructure-as-code tool (like CloudFormation) to Terraform, and you must import your existing resources.
  • Proof of Concept (POC) Resources: Your team has created some infrastructure resources directly in the UI or using other tools as part of a POC. Now, you want to bring those resources under Terraform’s state.
  • Legacy Systems: Before Terraform was adopted, your organization had an existing infrastructure created using Python scripts, Powershell, manual processes, or other tools. Importing these resources allows you to start managing them with Terraform.

Introduction to Terraform Import Command

In this section, we’ll explore the terraform import command. This command brings existing infrastructure resources under Terraform’s management. This is a handy feature because it allows you to use Terraform to manage resources created outside of Terraform, such as importing existing infrastructure resources such as those created manually.

The terraform import command lets you add an existing resource to your Terraform configuration. This is helpful when you want to start managing your entire infrastructure using Terraform and sync every resource block in your state file with your current infrastructure, even if some of your resources were created in other ways.

The basic syntax for the terraform import command is:

terraform import <address> <id>

Here’s what each part means:

  • address: This is the address of the resource in your Terraform configuration. This tells Terraform where to put the imported resource.
  • id: This is the unique identifier for the resource in your cloud provider. For example, if importing an AWS EC2 instance, thewould be the instance ID.

Let’s take an example of importing an existing S3 bucket into Terraform. Suppose you have an S3 bucket, “terrateam-bucket-test-import” created manually via the UI. You now want to start managing this bucket using Terraform.

Buckets

How would you import this bucket into your existing state?

First, let’s create a Terraform configuration file (e.g., main.tf) that defines the S3 bucket we want to import:

provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "terrateam-bucket-test-import" {
bucket = "terrateam-bucket-test-import"
}

Now, if we try to run terraform apply, Terraform will throw an error because the bucket “terrateam-bucket-test-import” already exists:

Bucket already exists

Terraform cannot create a new bucket with the same name as the existing one. We will now use the terraform import command to bring the existing bucket under Terraform’s management.

terraform import aws_s3_bucket.terrateam-bucket-test terrateam-bucket-test-import

This command will import the existing S3 bucket named “terrateam-bucket-test-import” into your Terraform state, associating it with the aws_s3_bucket.terrateam-bucket-test resource in your configuration.

After running the import command, you can run terraform apply to verify that Terraform now recognizes the existing bucket and doesn’t plan to create a new one.

Terraform Apply

Another approach is to import one more existing S3 bucket, “terraform-import-block-bucket”, using the terraform import block in our Terraform configuration.

Buckets 2

Start by creating a new Terraform configuration file (e.g., main.tf) that defines the S3 bucket you want to import, but without specifying the bucket name:

provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "terrateam-block-import" {
}
import {
id = "terraform-import-block-bucket"
to = aws_s3_bucket.terrateam-block-import
}

Execute the terraform plan command to preview the import operation:

Terraform Plan

This will show you the changes Terraform plans to make, including the import of the existing S3 bucket code.

If you’re satisfied with the plan, run terraform apply to execute the import operation:

Terraform Apply 2

Using the import block in your Terraform configuration lets you preview the import operation during the terraform plan step and execute it using terraform apply. This approach can be convenient, especially when you need to import resources from multiple resources or want to have a clear record of the import operation in your configuration.

Remember, the terraform import command and the import block achieve the same result of bringing an existing S3 bucket under Terraform’s management. Choose the approach that best fits your workflow and preferences.

Terraform import flags

The terraform import command supports several flags that can be used to customize the Terraform import process. Let’s explore three commonly used flags:

  • -config=path

This flag specifies the path to the directory containing your Terraform configuration files. It is useful when your main configuration files is in a directory other than the current working directory.

Example:

terraform import -config=/path/to/config aws_s3_bucket.terrateam-bucket-001 terrateam-bucket-02
  • -input=false

This flag disables interactive commands and input prompts during the import process. This can be useful when running the import in a non-interactive environment, such as a CI/CD pipeline.

Example:

terraform import -input=false aws_s3_bucket.terrateam-bucket-001 terrateam-bucket-02
  • -ignore-remote-version

This flag is a rare option used for the remote backend only. It allows you to ignore the remote backend’s version check during the import operation.

Example:

terraform import -ignore-remote-version aws_s3_bucket.terrateam-bucket-001 terrateam-bucket-02

Let’s try importing an existing S3 bucket using these three flags:

Create a Terraform configuration file (e.g., main.tf) with the following code:

provider "aws" {
region = "us-west-2"
}
resource "aws_s3_bucket" "terrateam-bucket-01" {
bucket = "terrateam-bucket-import-01"
}

Run the terraform import command with the —provider, —state, and —backup flags:

terraform import -config=. -input=false -ignore-remote-version aws_s3_bucket.terrateam-bucket-001 terrateam-bucket-02

Importing Buckets

Terraform Import vs Terraform state mv

Here is a comparison of terraform import and terraform state mv:

Terraform Import

  1. The terraform import command adds existing infrastructure resources into Terraform’s management. This allows you to bring resources created outside of Terraform under Terraform’s control.
  2. The primary purpose of Terraform import is to gradually transition infrastructure to Terraform’s management or to bring resources under Terraform’s management that it may not have supported initially.
  3. Terraform import is applicable when you have an existing infrastructure created outside of Terraform and want to start managing it using Terraform.

Terraform state mv

  1. The terraform state mv command changes the bindings in the Terraform state, associating an existing remote object with a new resource instance address in your configuration.
  2. The primary purpose of Terraform state mv is to handle situations where you have renamed a resource block in your configuration or moved it into a child module while still retaining the existing object.
  3. Terraform state mv is more commonly used for code refactoring purposes, such as when you have renamed a resource or moved it to a different module and want to update the state to match the new configuration without destroying and recreating the resource.

Inspecting the State File After Import

After using the terraform import command to bring existing infrastructure resources under Terraform’s management, inspect the state file to understand how the imported resources are represented and what changes, if any, need to be made to your Terraform configuration.

Identifying Changes and Additions in the State File

When you import a resource, Terraform will update the state file to include the imported resource. You can use the terraform state list command to see the resources that have been added to the state file:

Before importing: Terraform state list

After importing: Terraform state list 2

This shows that the aws_s3_bucket.terrateam-block-import, aws_s3_bucket.terrateam-bucket-001, and aws_s3_bucket.terrateam-bucket-01 resources have been added to the state file due to the import operation.

To see the details of the imported resource, you can use the terraform state show command: Terraform state show

This will display the imported resource’s attributes, which you can then compare to your Terraform configuration to identify any differences.

Updating State Files

It’s important to note that the terraform import command only updates the Terraform state file to reflect the existing infrastructure. It does not automatically update your Terraform configuration to match the imported resource.

After importing a resource, you should review the Terraform plan output to see what changes Terraform plans to make. This will help you identify discrepancies between your configuration and the imported resource, and allow you to update your configuration accordingly.

Analyzing the Plan Output

Once you’ve imported a resource, you can run terraform plan to see how Terraform plans to manage the imported resource: Terraform plan 2

The plan output shows that Terraform plans to update the aws_s3_bucket.terrateam-import resource in place. Specifically, it plans to update the S3 bucket’s tags and tags_all attributes.

This shows the imported S3 bucket has tags that are different from those defined in your Terraform configuration. Terraform has detected this difference and plans to update the tags to match your configuration.

Terraform Import Resource using Terrateam

Terrateam is a powerful Terraform and OpenTofu GitOps CI/CD solution that seamlessly integrates with GitHub, enabling teams to deliver infrastructure faster and more efficiently. With Terrateam, you can easily manage your infrastructure as code, collaborate with your team, and automate your deployment processes.

After the Terrateam setup is done, let’s start by creating a Terraform configuration file (e.g., main.tf) that will import an existing S3 bucket named “terraform-import-block-bucket” and add two tags to it:

  • name = “terrateam-bucket”
  • key = “z3”

In the main.tf file, we define an aws_s3_bucket resource block without specifying the bucket name. This is because we will be importing an existing bucket.

We add a tags block to the aws_s3_bucket resource, defining the two tags we want to apply to the imported bucket.

provider "aws" {
region = "us-east-1"
access_key = "<your access key>"
secret_key = "<your secret access key>"
}
resource "aws_s3_bucket" "terrateam_bucket" {
# Don't specify the bucket name here
tags = {
name = "terrateam-bucket"
key = "z3"
}
}
import {
id = "terraform-import-block-bucket"
to = aws_s3_bucket.terrateam_bucket
}

Finally, we use the import block to specify the ID of the existing S3 bucket we want to import (id = “terraform-import-block-bucket”), and the resource address in our Terraform configuration where it should be imported (to = aws_s3_bucket.terrateam_bucket).

Using the import block, we can quickly bring the existing S3 bucket under Terraform’s management and apply the desired configurations, such as the tags, to the imported resource.

After creating the Terraform configuration, Terrateam will run the terraform plan and terraform apply commands to execute the Import operation. Terrateam Action

After Terrateam executes the terraform apply command, we can see our bucket is updated with the tags: Tags

Frequently Asked Questions

1. How do I import a resource created by a Terraform module?

You need to use the terraform import command to import a resource created by a module. This command allows you to bring existing infrastructure resources under Terraform’s management, even if they were created outside of Terraform. When importing a resource created by a module, you must import each resource individually, as Terraform requires a specific resource address to perform the import.

2. What is the import function in Terraform?

The Terraform import function adds existing infrastructure resources to your Terraform state. This is useful when you have resources created outside of Terraform and want to start managing them using Terraform. The terraform import command allows you to map an existing resource to a resource block in your Terraform configuration so that Terraform can manage it in the future.

3. Does Terraform import generate code?

No, the terraform import command does not generate code. It simply adds the existing infrastructure resource to your Terraform state, allowing you to manage it using your existing Terraform configuration. After importing a resource, you may need to update your Terraform configuration to match the imported resource, but the import command itself does not generate any new code.

4. How do I import an s3 bucket into my Terraform state?

You can use the import command to import an existing S3 bucket into your Terraform state. First, you must create a Terraform resource block for the S3 bucket in your configuration. Then, you can run the import command, specifying the resource address and the bucket’s ID (the bucket name). This will add the existing S3 bucket to your Terraform state, allowing you to manage it going forward.

5. What is the difference between import and load?

The import command maps an existing resource to a resource block in your Terraform configuration. At the same time, load reads and parses Terraform configuration files, allowing you to work with them in your Terraform workflow.

Infrastructure as Code. Optimized.

Ready to get started?

Experience powerful infrastructure orchestration, seamlessly integrated with GitHub.