Terraform Tutorial · State and Workflow · Lesson 19 of 25

Terraform import, moved and removed

Bring existing infrastructure under Terraform with import blocks, and rename or stop managing resources safely with moved and removed blocks.

Importing existing resources

Since Terraform 1.5, import is declared in code and shows up in the plan:

import {
  to = aws_s3_bucket.legacy
  id = "acme-legacy-uploads"
}

resource "aws_s3_bucket" "legacy" {
  bucket = "acme-legacy-uploads"
}

terraform plan -generate-config-out=generated.tf can even write the resource block for you. Since 1.16, import blocks also work inside modules.

Renaming without destroying: moved

Renaming aws_instance.web to aws_instance.frontend would normally destroy one and create the other. A moved block tells Terraform it is the same object:

moved {
  from = aws_instance.web
  to   = aws_instance.frontend
}

Stop managing without deleting: removed

removed {
  from = aws_instance.old_bastion
  lifecycle {
    destroy = false   # forget it in state, keep the real server
  }
}
A moved block in a plan (nothing to move yet, so it is just a create)
terraform {
  required_providers {
    local = { source = "hashicorp/local", version = "~> 2.5" }
  }
}

resource "local_file" "renamed" {
  filename = "${path.module}/notes.txt"
  content  = "kept"
}

moved {
  from = local_file.original
  to   = local_file.renamed
}

Output

Terraform will perform the following actions:

  # local_file.renamed will be created
  + resource "local_file" "renamed" {
      + content              = "kept"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./notes.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Run this on your computer — see “Get Started” for setup.

Test yourself

Which block renames a resource address without destroying it?

  1. import
  2. moved
  3. removed
  4. lifecycle
Show answer

Answer: moved