Generating terraform configurations while reusing modules and values is not straightforward with just Terraform. It’s just not in the feature perimeter of Terraform and that’s fine: Kapitan to the rescue.

Photo by David Clode

Terraform let use define infrastructure using HCLlanguage and JSON. We started using modules as soon as we wanted to reuse some definitions of part of our infrastructure. So far so good, when we wanted to reuse composition of modules with different values in order to generate clones of the same infrastructure, the problems started.

How to avoid the copy/pasting/search and replace? How to manage hierarchies of values (inheritance, overriding) ? Sounds like a job for Kapitan and it turned out the Kapitan developers already had added an example of using Kapitan to generate Terraform json.

And here we go, Kapitan for Kubernetes and now for Terraform!

We’re able to reuse our existing module, simply by instantiating them from Jsonnet templates in Kapitan. And now we benefit from the full power of value hierarchies of Kapitan, refs and secret management. What’s not to like?

  • Define a target: infrastructure_model_M1 + values_for_deploiment_D2 + values_for_environment_DEV
  • Define inventory classes with values used by target
  • Define components templates

Structure

Target

Assemble classes and values in order to generate a specific infrastructure.

Example:

  • resource group and storage account for dev environment
  • computing cluster for qa environment including networking, virtual machines, dns record, …

Classes

  • environment (dev, staging, prod): define specifics for a target environment
  • provider (azure, gcp): describe terraform provider and backend

Templates

  • components (resource group, vm, dns record): describe individual resource used in simple or adhoc deployments
  • topology: describe complex deployment by composing components. Describe once, deploy multiple time just by changing values.
  • scripts: init, plan, apply to unify usage of terraform commands

Usage

kapitan compile --reveal --targets web_db_dev
./scripts/init.sh
./scripts/plan.sh
./scripts/apply.sh