PlatformEngr® Terraform course

Cheat notes · Module 04 · State, modules and environments

One module, two teams

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

A module packages resources behind inputs and outputs, so every team gets the same kit from a few lines. Moving a block changes its address; a moved block says it is the same object, and prevent_destroy turns a plan that would delete a namespace into an error.

Remember

  • Module call: module "checkout" { source = "../../modules/team-namespace" ... }; addresses become module.checkout.kubernetes_namespace_v1.this.
  • A module declares a provider version range (>= 3.0.0, < 4.0.0); the caller configures the provider and pins the exact version.
  • moved { from = ... to = ... }: old address, new address, nothing recreated.
  • lifecycle { prevent_destroy = true }: any plan that would destroy it fails with Instance cannot be destroyed, as long as the block is still in the code.
  • A default is every caller's value. A difference between teams is an input in the caller.
  • The kit: namespace, quota, limit range, a read-only binding for team-<name>, a deployer ServiceAccount with a Role that cannot read Secrets.

Pitfalls

  • Moving resources into a module without moved: the plan destroys and recreates them.
  • Changing a default in the module for one team: every caller that relies on it changes too. Read the plan of every caller.

Commands

terraform initAgain after adding a module call
terraform state listAddresses now start with module.<name>.
kubectl auth can-i list pods -n NS --as=jane --as-group=team-checkoutWould that group be allowed?

envs/dev/moved.tf

moved {
  from = kubernetes_namespace_v1.checkout
  to   = module.checkout.kubernetes_namespace_v1.this
}

Test yourself

Answer in your head first, then open the answer.

Why does moving a block into a module plan a destroy?

Terraform matches by address, and the address changed.

Where is the provider configured for a module's resources?

In the root module that calls it.

What does Instance cannot be destroyed tell you?

The plan would destroy a resource with prevent_destroy; find out why first.

Where module 04 leaves you: modules/team-namespace creates seven objects per team. envs/dev/main.tf calls it twice: module "checkout" and module "catalog". checkout-dev was never deleted. Both namespaces have team-quota, team-limits, a read-only binding for the team's group and a deployer ServiceAccount. catalog may run 20 pods.