Course outline

Terraform / Modules and state-aware lifecycle / Lesson 11

Import, moved blocks, and ownership continuity

Distinguish adopting an existing identity from renaming an already managed address, and review both through state-aware change control.

About 4 min readContent reviewed
On this page

Lesson goals

  • Explain provider-specific import identifiers and matching configuration.
  • Use moved blocks to describe supported address continuity.

Import binds an identity; it does not reconstruct every design decision

Import brings a supported existing object identity into Terraform’s ownership model at a chosen address. The identifier format and imported attributes depend on the provider and resource. A label that looks like an id is not sufficient evidence. Configuration must describe the intended ongoing management, and the resulting proposed changes still need review. Import is not a backup, a configuration audit, or proof that every property will remain unchanged. Never bind the same real object to multiple managed addresses merely to make separate configurations appear complete.

A logical provider keeps the example synthetic

The Random provider supports importing random_id values using its documented URL-safe Base64 identifier. This independent root-module example declares the three-byte teaching value AQID and a matching byte_length. It does not contact a cloud service, but an actual import would still change state and is prohibited in this course. The provider version constraint is separate from Terraform’s CLI range and is intentionally local to this example. No provider installation or import is performed.

hcl Complete illustrative logical import
terraform {
  required_version = ">= 1.16.0, < 1.17.0"
  required_providers {
    random = {
      source  = "hashicorp/random"
      version = "~> 3.9.0"
    }
  }
}

resource "random_id" "catalog" {
  byte_length = 3
}

import {
  to = random_id.catalog
  id = "AQID"
}

AQID encodes the fixed bytes 01,02,03 under the provider’s import format. It is not a cloud id or a request to generate a new random value. The HCL is non-runnable and no imported state or Terraform success output is claimed.

A moved block declares address continuity

A moved block describes a supported transition from an old managed address to a new one. It is different from importing an unmanaged object. The separate fixture below assumes an existing binding at terraform_data.legacy and renames its configuration address to catalog. Without that continuity information, removal and creation can be inferred as separate identities. Retain refactoring history long enough for relevant callers or states to traverse supported upgrades, and inspect the actual plan instead of assuming a moved declaration automatically proves every surrounding change harmless.

hcl Independent address-refactoring fixture
terraform {
  required_version = ">= 1.16.0, < 1.17.0"
}

resource "terraform_data" "catalog" {
  input = "atlas-lab"
}

moved {
  from = terraform_data.legacy
  to   = terraform_data.catalog
}

The old address refers to prior state, not a second resource that should remain declared. This example is separate from the Random import root. State continuity must match the real intended object and supported address change; no state is inspected or edited here.

Verify a declared identifier without importing it

The offline decoding example verifies only the fixed three-byte identifier used above. It does not emulate provider import, prove ownership of any state, or read a Terraform snapshot. Such small models can clarify a format while preserving operational boundaries. For actual providers, consult the resource’s exact versioned import documentation, including composite ids, region or account context, and unsupported attributes. A successful string decoder cannot certify that a real remote object exists or that adopting it is authorized.

python Decode the fixed teaching id offline
import base64
value = base64.urlsafe_b64decode('AQID')
print(f'bytes={len(value)}')
print('hex=' + value.hex())
Expected output
bytes=3
hex=010203

The result is exactly three bytes with hexadecimal 010203. No credential, provider, backend, resource, or state file is involved. The result verifies a declared format example only.

Adoption and refactoring need distinct evidence

Before adoption, establish object identity, current owner, target state, resource support, and intended configuration. Before refactoring, establish the existing binding and the exact address transition. Both require protected state evidence, dependency review, authorization, and a recovery plan for unexpected proposals. Generated configuration, where supported, is a starting point for review rather than complete architectural intent. Do not run imperative state edits or repeated imports to silence an unexplained plan; preserve the evidence and reconcile the ownership model first.

Common errors and fixes

Resource Import Not Implemented.

Why it happens
The selected provider resource does not support the assumed adoption operation.
How to fix it
Read the exact resource-version documentation and choose an approved supported strategy.
Prevent it next time
Verify import support and id syntax before preparing adoption.

A rename proposes deletion and creation.

Why it happens
Managed address continuity was omitted or does not match the existing binding.
How to fix it
Review a supported moved declaration against the intended state identity.
Prevent it next time
Track address changes as explicit refactors, not cosmetic edits.

One object is managed from multiple addresses.

Why it happens
Adoption duplicated ownership instead of transferring it deliberately.
How to fix it
Reconcile ownership through the approved state-aware process before further changes.
Prevent it next time
Maintain one clear management contract for each real identity.

Check your understanding

1. Does decoding AQID prove that Terraform imported anything?

Show worked solution

No. It verifies bytes in a declared string fixture. Import requires the provider’s supported operation and a state transition under an authorized workspace. The offline calculation cannot establish an imported binding, provider compatibility, or any real object’s existence.

2. How does moving legacy to catalog differ from importing catalog?

Show worked solution

The moved block preserves an already managed object’s address continuity. Import adopts an identity into management according to provider support. Decide which ownership transition is intended before writing either construct; using the wrong mechanism can duplicate bindings or produce unintended removal and creation proposals.

Key takeaways

  • Import adopts supported identities; moved blocks preserve supported managed-address continuity.
  • Verify formats and ownership without confusing an offline model with state execution.

Official references