Importing Existing Resources
Bring resources created outside Terraform under management with an import block or terraform import.
Syntax
import {
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
importblock (Terraform 1.5+), which you can plan and apply like any change. - The older
terraform importCLI command.
The process
- Write a matching
resourceblock. - Add an
importblock pointing at the real ID. - Run plan and apply to bind them.
Example
# 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 applyWhen 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.
# 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-bucketImport block (Terraform 1.5+)
Uses the declarative import block introduced in Terraform 1.5, letting the import be version-controlled alongside the resource.
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.
# 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