Free — no signup required

Importing Legacy Infrastructure

2 min read

The "Brownfield" Scenario

Most organizations don't start with Terraform. They start with manual clicks in the AWS console (sometimes called "ClickOps"), shell scripts, or older tools. When they adopt Terraform, they face a choice: destroy everything and recreate it with Terraform (risky and disruptive), or import the existing resources into Terraform's state.

Import is the process of bringing an existing real-world resource under Terraform management without destroying and recreating it. Terraform writes the resource into its state file and, from that point on, manages it like any other Terraform-managed resource.

The Old Way: CLI Import

Before Terraform 1.5, import was a two-step manual process: write the HCL resource block by hand, guessing at the correct attribute values to match the real resource, then run an import command to link that real resource to the HCL block. The problem: Terraform imports the resource into state, but if the hand-written HCL doesn't exactly match the real resource's configuration, the next terraform plan shows a diff and tries to modify the resource. Getting the HCL exactly right required reading the cloud console carefully and iterating.

The Modern Way: Import Blocks (Terraform 1.5+)

Terraform 1.5 introduced import blocks and a plan flag that generates the HCL automatically. Instead of guessing, you declare an import block naming the target resource address and its real-world ID, then ask Terraform to generate a complete, accurate HCL block from the live resource itself — reading its actual current configuration rather than requiring anyone to reconstruct it by hand. That generated code is a starting point: it still needs review and cleanup (removing read-only attributes Terraform doesn't need to manage) before the import is complete.

The import block approach is dramatically safer because Terraform generates the HCL from the real resource rather than requiring you to guess. The generated code is a starting point — review it carefully before applying.

Key Point: The resource ID format used in terraform import and import blocks is provider-specific and not always obvious. For aws_s3_bucket, the ID is the bucket name. For aws_iam_role_policy_attachment, the ID is role-name/policy-arn. Always check the Terraform provider documentation for the specific resource type to find the correct ID format before attempting an import.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free