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
}
}
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?
importmovedremovedlifecycle
Show answer
Answer: moved