Importing Existing Resources

Bring resources created outside Terraform under management with an import block or terraform import.

Syntaximport { to = aws_s3_bucket.data id = "existing-bucket-name" }

Sometimes infrastructure already exists — created by hand or another tool — and you want Terraform to manage it going forward. That is what import is for.

Two ways to import

  • The declarative import block (Terraform 1.5+), which you can plan and apply like any change.
  • The older terraform import CLI command.

The process

  1. Write a matching resource block.
  2. Add an import block pointing at the real ID.
  3. Run plan and apply to bind them.

Example

Example · hcl
# The resource block you want to manage
resource "aws_s3_bucket" "data" {
  bucket = "legacy-soundscode-data"
}

# Bind it to the existing bucket in your account
import {
  to = aws_s3_bucket.data
  id = "legacy-soundscode-data"
}

# Then: terraform plan, terraform apply

When to use it

  • An infrastructure team imports a manually created production RDS instance into Terraform management so future changes go through the code-review workflow.
  • A developer uses an import block in Terraform 1.5+ to import an existing S3 bucket and immediately generate the matching resource configuration.
  • An SRE imports a batch of manually created security groups into state after the company decides to adopt Terraform for an existing environment.

More examples

CLI import command (Terraform < 1.5)

Maps an existing S3 bucket into the state file using the CLI import command, linking the HCL block to the real resource.

Example · bash
# First, write the matching resource block in main.tf:
# resource "aws_s3_bucket" "legacy" {
#   bucket = "my-existing-bucket"
# }

# Then import the real bucket into state:
terraform import aws_s3_bucket.legacy my-existing-bucket

Import block (Terraform 1.5+)

Uses the declarative import block introduced in Terraform 1.5, letting the import be version-controlled alongside the resource.

Example · hcl
import {
  to = aws_instance.web
  id = "i-0abc1234567890"
}

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  tags          = { Name = "web" }
}

Generate config during import

Uses -generate-config-out to have Terraform auto-write the resource block from the real object's attributes, then you review and commit it.

Example · bash
# Add only the import block, omit the resource block, then:
terraform plan -generate-config-out=generated.tf

# Terraform writes a resource block into generated.tf
cat generated.tf
# resource "aws_instance" "web" {
#   ami           = "ami-0c55b159cbfafe1f0"
#   instance_type = "t3.micro"
#   ...
# }

Discussion

  • Be the first to comment on this lesson.