PlatformEngr® Terraform course

Cheat notes · Module 01 · The loop

Write, plan, apply: a namespace from code

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

You write what should exist, plan shows the steps without changing anything, and apply runs them and records the result in state. The address (type plus name) is how Terraform knows an object; the last line of the plan is what you read first.

Remember

  • Address: kubernetes_namespace_v1.checkout. The type comes from the provider, the name is yours.
  • Plan symbols: + create, ~ update in place, -/+ destroy and create again (must be replaced).
  • # forces replacement marks the field that makes an update impossible, such as a namespace's name.
  • A reference (kubernetes_namespace_v1.checkout.metadata[0].name) passes a value and sets the order.
  • Apply is not a transaction: if the second action fails, the first stays done and recorded.
  • .terraform.lock.hcl is committed; .terraform/ and *.tfstate never are.

Pitfalls

  • Typing a namespace name by hand: namespaces "checkout-develop" not found at apply time, after the plan looked fine. Use a reference.
  • Applying a plan that says must be replaced on a namespace: everything inside it is deleted.
  • Reading the plan from the top. Read the last line first: Plan: X to add, Y to change, Z to destroy.

Commands

terraform fmtFormat the files
terraform validateValid HCL, known arguments, right types
terraform planThe steps an apply would take. Changes nothing
terraform applyPlan again, ask, change, record
terraform state listEvery address Terraform manages here
git ls-filesWhat is really in Git

envs/dev/main.tf (module 01)

resource "kubernetes_namespace_v1" "checkout" {
  metadata {
    name = "checkout-dev"
    labels = {
      team = "checkout"
    }
  }
}

resource "kubernetes_resource_quota_v1" "checkout" {
  metadata {
    name      = "team-quota"
    namespace = kubernetes_namespace_v1.checkout.metadata[0].name
  }
  spec {
    hard = {
      pods              = "10"
      "requests.cpu"    = "2"
      "requests.memory" = "2Gi"
    }
  }
}

Test yourself

Answer in your head first, then open the answer.

What is the difference between plan and apply?

plan only proposes; apply makes the changes and writes them to state.

Why use a reference instead of the namespace's name as a string?

It cannot be mistyped, and it tells Terraform to create the namespace first.

An apply fails halfway. What is in state?

Whatever succeeded. Run plan to see what is left.

Which file do you commit so everyone gets the same provider?

.terraform.lock.hcl.

Where module 01 leaves you: Namespace checkout-dev (label team=checkout) with ResourceQuota team-quota and LimitRange team-limits, all created by Terraform, and a ConfigMap team-contact. envs/dev has versions.tf, providers.tf, main.tf and a committed .terraform.lock.hcl. The state is a file on your laptop that is not in Git.