linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/how/tf-moved-removed-import-blocks

how/state

moved, removed, import: the same operations, but in HCL

Declarative blocks for renaming, dropping, and pulling in resources. What they give you beyond the CLI, which Terraform versions added them, and why they live in git.

The imperative commands state mv, state rm, and import solve specific problems (see tf-state-mv-rm-import), but they share one issue: they are not reproducible.

  • git does not show who renamed a resource, when, or why.
  • In CI you cannot "replay the history": it was never recorded.
  • If the repo is cloned into a new environment, you have to repeat the operations by hand.

That is why Terraform gradually gained declarative counterparts:

  • the moved block, since Terraform 1.1 (December 2021).
  • the import block, since Terraform 1.5 (June 2023).
  • the removed block, since Terraform 1.7 (January 2024).

All three are written directly in HCL, land in git, and run through terraform apply as part of a normal plan. Press ▶.

step 1/5·00 · baseline position
MAIN.TFresource "aws_s3_bucket" "old" {bucket = "linuxlab-3f4a"}TERRAFORM.TFSTATEпосле applyaws_s3_bucket.oldid: linuxlab-3f4aAWSфизический бакетlinuxlab-3f4aбазовая позиция: один ресурс под управлением Terraform

§ steps

  1. One resource in HCL, one entry in state, one bucket in the cloud.

    hcl
    resource "aws_s3_bucket" "old" {
      bucket = "linuxlab-3f4a"
    }

    The same starting setup as in tf-state-mv-rm-import. Now you will change it declaratively, through blocks in HCL rather than through the CLI.

recap

When blocks beat the CLI:

  • any prod pipeline. The changes show up in the pull request, can be discussed and rolled back.
  • any repo that deploys to several environments (dev/staging/prod). One block runs in all of them.
  • any situation that needs history. The CLI is a trail in one person's terminal, a block is a record in git.

When the CLI is still the right tool:

  • a one-off edit of local state in a learning project.
  • quick diagnostics: terraform state list, terraform state show <addr>.
  • scenarios that blocks do not cover yet (for example, state replace-provider).

Lifecycle of moved/removed/import blocks:

All three are transient. Once a block has run during apply, you can delete it from HCL: the state is already changed, and running the block again does nothing. In practice teams often keep them for a couple of sprints in case of a rollback, then remove them.

If you forget to delete a moved block and then delete the target resource (aws_s3_bucket.primary), Terraform starts to complain: "the moved block references an address that does not exist." That is a sign the block is stale and it is time to clean up.

Next: tf-state-anatomy on how state is built, tf-drift on what happens between applies.

§ dig into the knowledge base

  • tf-moved-blockthe moved block: a detailed walkthrough
  • tf-removed-blockthe removed block: take a resource out of management
  • tf-import-blockthe import block: declarative import
  • tf-state-manipulationterraform state mv/rm/list: the imperative commands
  • tf-generate-config-outplan -generate-config-out: auto-generating HCL

§ try it hands-on

  • ›tf-intermediate-07-state-manipulation- State operations: mv, rm, list
  • ›tf-intermediate-08-import- Import: pulling in an existing bucket
  • ›tf-intermediate-09-moved- The moved block: renaming without destroy
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies