Terraform Import Block Generator

Generate import blocks from resource blocks. The id cannot be derived from your configuration, because it identifies the object in your cloud account, so this names the format instead of guessing the value.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Generate. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A bucket and a queue

The queue is the interesting one: it imports by URL, not by name and not by ARN

resource "aws_s3_bucket" "logs" {
  bucket = "my-logs"
}

resource "aws_sqs_queue" "jobs" {
  name = "jobs"
}

A resource with for_each

One import block is not enough, and the error will not mention the missing key

resource "aws_subnet" "private" {
  for_each = var.subnets
  vpc_id   = var.vpc_id
}

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Using the resource name as the import id

    The id is whatever the provider uses to identify the object. A security group takes sg-..., not the group name, and the failure comes back from the cloud API as not-found.

    Instead:Check the Import section at the bottom of the provider's documentation page for that resource type.

  2. Writing one import block for a resource with for_each

    An import block targets a single instance, so an unindexed address refers to a resource that does not exist and the error does not mention the missing key.

    Instead:Write one block per key, with to = aws_subnet.private["that-key"].

  3. Reaching for terraform import instead

    It writes to state immediately with no plan to review, so a wrong id or a wrong address is discovered after the fact.

    Instead:Use import blocks on 1.5 or later. plan shows exactly what would be imported before anything changes.

Import blocks are planned before they are applied, unlike the old command

The difference is the whole reason to use them. terraform import mutates state immediately with nothing to review; an import block shows up in plan and changes nothing until apply.

The id is the provider's identifier, not the Terraform name

An S3 bucket imports by bucket name, an EC2 instance by i-0123..., a security group by sg-... rather than by group name, an IAM role by role name while an IAM policy takes an ARN, and an SQS queue by queue URL rather than by name or ARN. Getting it wrong produces a not-found from the cloud API rather than a Terraform error, so it reads like a permissions problem.

A resource with count or for_each needs one block per instance

An import block targets one object. to = aws_subnet.private with a for_each on the resource refers to something that does not exist, and the error names the address rather than the missing key. Write one block per key or index.

plan -generate-config-out writes the configuration for you

Point it at a file and Terraform emits resource blocks matching what it found, which saves transcribing forty arguments by hand. The output needs reconciling: it is exhaustive rather than idiomatic, and it includes computed values you do not want to declare.

Leaving the blocks in afterwards is harmless

A second apply sees the resource already in state and does nothing. Some teams remove them so the configuration describes only desired state; others keep them as a record. Both are fine, and drifting between the two is what causes arguments.

The to address includes the module path

A resource inside a module imports to module.network.aws_subnet.private, not to aws_subnet.private. Import blocks live in the root module and the address is absolute.

Terraform 1.5 is the floor

Before that, the only option is terraform import, one resource at a time, with no plan and no dry run. If you are importing more than a handful of resources, the upgrade pays for itself immediately.

More terraform tools

Terraform Validator & Formatter Does it parse, and is it formatted? Terraform dynamic Block Generator It is ingress.value, not each.value Terraform check and precondition Generator A failed check does not stop the apply Terraform variables.tf Generator From the var. references you already wrote Terraform Unused Declaration Linter Dead variables, locals and data sources Terraform Atlantis YAML Generator when_modified misses your modules Terraform Function Tester and HCL Console terraform console, in a tab Terraform for Expression Tester Where do the keys collide? Terraform Interpolation Tester null becomes an empty string Terraform templatefile Tester Render it before you apply it Terraform Resource Count Calculator How many objects, not how many blocks Terraform count to for_each Converter With the moved blocks it needs Terraform moved Block Generator Rename without destroying Terraform state mv Command Builder No plan, no undo Terraform target Flag Builder And why to stop using it Terraform outputs.tf Generator Outputs are not sensitive by default Terraform Remote State Data Source Generator It grants read of the whole state Terraform Provider Block Generator docker is not hashicorp/docker Terraform .gitignore Generator and Checker .terraform* eats the lock file Terraform to OpenTofu Migration Checker The state is the part to watch Terraform tfvars to JSON Converter The JSON file wins Terraform Version Constraint Parser What ~> actually allows Terraform Resource Address Parser Quote it before the shell eats it Terraform cidrsubnet Calculator newbits is added, not the target Terraform Lock File Viewer Why CI fails and your laptop does not Terraform Variables Checker A missing value hangs CI Terraform tfvars to Env Vars Converter Lists and maps have to be JSON Terraform Deprecated Syntax Checker What a current Terraform rejects Terraform State File Viewer Read it without uploading it Terraform Plan JSON Viewer It is not redacted Terraform HCL to JSON Converter And what the conversion loses Terraform Module Source Validator version only works for the registry Terraform Backend Config Decoder Is state actually locked? Terraform Naming Convention Validator A hyphen makes a resource unreferenceable

Elsewhere on the site