100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
HCL

Importing Existing Infrastructure

Importing lets Terraform take ownership of resources that already exist in a cloud account, bringing them under state management without recreating them.

State ManagementIntermediate9 min readJul 9, 2026
Analogies

Importing Existing Infrastructure

Real organizations rarely start with a blank slate — resources are often created manually through a cloud console, by a legacy script, or by a different tool entirely, long before Terraform enters the picture. Importing is the process of associating one of these pre-existing resources with a resource block in configuration so that Terraform's state file records it, without Terraform ever having to create (or, worse, accidentally destroy and recreate) it. Import only populates state; it does not generate configuration for you, which means the corresponding resource block in your .tf files must already exist and its arguments must be written to accurately reflect the real object's current settings.

🏏

Cricket analogy: A franchise doesn't always draft players from scratch; sometimes a veteran already playing domestic cricket is added to the roster, and the team registry must record their existing stats without pretending they're a debutant.

The Two-Step Workflow

The classic workflow is: first write (or stub out) a resource block with the right type and a local name, then run terraform import <resource_address> <external_id>, where the external ID format is resource-type-specific (an AWS instance ID, an Azure resource ID, a GCP self-link, etc.). After the import command succeeds, running terraform plan will almost certainly show a diff, because your hand-written configuration rarely matches every real attribute exactly on the first try — you then iteratively adjust the configuration until plan reports no changes, confirming that configuration and real-world state now agree.

🏏

Cricket analogy: First a scorer writes a placeholder name on the sheet, then cross-checks the player's actual identity via the toss card; the first plan rarely matches perfectly, so the scorer amends it entry by entry until it's accurate.

The import Block (Terraform 1.5+)

Since Terraform 1.5, an import block can be declared directly in configuration as a declarative alternative to the imperative terraform import CLI command. This has the advantage of being reviewable in a pull request and repeatable across environments, and combined with terraform plan -generate-config-out=generated.tf, Terraform can even scaffold a starting resource configuration automatically from the real object's attributes, dramatically reducing the manual transcription work for large migrations.

🏏

Cricket analogy: Modern scoring apps let a scorer declare a player's stats directly from a structured template instead of writing longhand, and can even auto-fill career figures from the official database, cutting manual transcription drastically.

bash
# Classic imperative import
$ terraform import aws_s3_bucket.assets acme-prod-assets-bucket
aws_s3_bucket.assets: Importing from ID "acme-prod-assets-bucket"...
aws_s3_bucket.assets: Import prepared!
  Prepared aws_s3_bucket for import
aws_s3_bucket.assets: Refreshing state... [id=acme-prod-assets-bucket]

Import successful!
hcl
# Declarative import block (Terraform 1.5+)
import {
  to = aws_s3_bucket.assets
  id = "acme-prod-assets-bucket"
}

resource "aws_s3_bucket" "assets" {
  bucket = "acme-prod-assets-bucket"
}

# terraform plan -generate-config-out=generated.tf

Import is like retroactively filing paperwork for a building that was already constructed: the building doesn't change, but now it officially appears in the city's records and future permits (Terraform plans) will account for it correctly.

If the resource block's arguments don't match the real object closely enough after import, the very next apply can attempt to 'correct' the mismatch — potentially modifying or even replacing the resource in-place. Always run terraform plan immediately after an import and scrutinize every proposed change before applying.

  • Import associates a pre-existing real-world resource with a Terraform resource block, populating state without recreating the object.
  • Import does not generate configuration automatically in classic usage — the resource block must already exist and be written by hand.
  • The external ID format required for import is resource-type-specific and provider-documented.
  • After import, terraform plan almost always shows a diff until the configuration is manually reconciled to match reality.
  • Terraform 1.5+ import blocks provide a declarative, reviewable alternative to the imperative terraform import command.
  • -generate-config-out can scaffold starting configuration automatically from imported resource attributes.

Practice what you learned

Was this page helpful?

Topics covered

#HCL#TerraformInfrastructureAsCodeStudyNotes#DevOps#ImportingExistingInfrastructure#Importing#Existing#Infrastructure#Two#StudyNotes#SkillVeris