PlatformEngr® Terraform course

Cheat notes · Module 07 · Safe change

Import, drift and provider upgrades

A five-minute review for when you have done this module and want it back in your head. Open the full module for the steps and the lab, or the full text to print.

The idea

Code, state and world drift apart in three ways: something exists that state does not know (import it), something was changed by hand (see it with a refresh-only plan, then decide), and the provider moves on (constraint, init -upgrade, empty plan). Objects Terraform never managed are in no plan.

Remember

  • import { to = ADDRESS id = "search-dev" }: adopt on the next apply; the plan says 1 to import.
  • Import only writes state. The code must already describe the object; the plan then changes it to match.
  • plan -refresh-only: shows what changed outside Terraform; proposes updating state, never the objects.
  • Drift has two honest outcomes: put the hand change in code, or apply to undo it.
  • Upgrade: change the version, init refuses, init -upgrade, read the lock diff and the changelog, then a plan where every line is explained and 0 to destroy; after the apply, No changes.
  • providers lock -platform=... adds checksums for other machines; CI's -lockfile=readonly needs Linux ones.
  • name_override: an optional input for a namespace that predates the naming rule.

Pitfalls

  • Deleting an object so Terraform can create it: import it instead.
  • Deleting .terraform.lock.hcl to get past a version error: the upgrade becomes invisible in review.
  • An import whose plan destroys: the module computes a different name. The bar for an import is 0 to destroy.
  • Trusting No changes.: a RoleBinding made by hand is outside every plan.

Commands

terraform plan -refresh-onlyOnly what changed outside Terraform
terraform init -upgradeNewest allowed versions; rewrites the lock file
terraform providers lock -platform=linux_amd64 -platform=linux_arm64 -platform=darwin_amd64 -platform=darwin_arm64Checksums for every platform
git diff .terraform.lock.hclWhat the upgrade changed: version, constraints, hashes
kubectl -n NS patch resourcequota team-quota --type merge -p '{...}'A hand change, for practice

envs/dev/imports.tf

import {
  to = module.search.kubernetes_namespace_v1.this
  id = "search-dev"
}

Test yourself

Answer in your head first, then open the answer.

What does an import block do on apply?

It records an existing object at the address; nothing is created.

How do you see only the hand changes?

terraform plan -refresh-only.

What is the proof that a provider upgrade is safe here?

An empty plan after init -upgrade, with the changelog read.

Where module 07 leaves you: search-dev is managed by module "search" and was never recreated. envs/dev/imports.tf holds the import block. Both environments are on provider 3.5.0 with lock files that carry checksums for Linux and macOS. .github/dependabot.yml proposes future upgrades. Every plan says No changes.