Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Manage Complexity with Terraform

Avatar for Justin Justin
September 28, 2025

Manage Complexity with Terraform

A 25 minute introduction to Terraform and refactoring suitable for beginners to intermediate developers who are just getting started dealing with code complexity in a Terraform code base. The accompanying talk is currently available on YouTube at:

https://www.youtube.com/watch?v=-dMtaC5QaUk&t=283s

Avatar for Justin

Justin

September 28, 2025
Tweet

More Decks by Justin

Other Decks in Technology

Transcript

  1. What is Terraform? According to HashiCorp (IBM): • Terraform is

    an infrastructure as code tool that lets you build, change, and version infrastructure safely and efficiently. This includes low-level components like compute instances, storage, and networking; and high-level components like DNS entries and SaaS features. • Infrastructure as Code (IaC) Source: https://developer.hashicorp.com/terraform
  2. What is Terraform? According to HashiCorp (IBM): • Terraform is

    an infrastructure as code tool that lets you build, change, and version infrastructure safely and efficiently. This includes low-level components like compute instances, storage, and networking; and high-level components like DNS entries and SaaS features. • Infrastructure as Code (IaC) • Build, change, and version infrastructure Source: https://developer.hashicorp.com/terraform
  3. What is Terraform? Infrastructure as Code • Configuration of cloud

    infrastructure resources declared as code (an interpreted configuration language… HCL)
  4. What is Terraform? Infrastructure as Code • Configuration of cloud

    infrastructure resources declared as code (an interpreted configuration language… HCL) terraform { ... } Network Load Balancer Database Firewall Compartment Policy Compute Secret ./my-project/main.tf
  5. What is Terraform? Build, change, and version infrastructure • Write

    code and call terraform plan / apply terraform { ... } Network Load Balancer Compute Cloud Service $ terraform apply HTTPS
  6. What is Terraform? Build, change, and version infrastructure • Versioning

    is both state reconciliation and source control terraform { ... } Network Load Balancer Compute Cloud Service Version Control {tfstate} $ git commit –m ... HTTPS
  7. What is Terraform? Agnostic by design • Terraform providers deal

    with the nuances of each cloud terraform { ... } AWS GCP OCI Azure https://registry.terraform.io/browse/providers
  8. Examples of complexity • Complex expressions or repetitive parameter updates,

    and unrelated resource definitions (low cohesion), and inconsistent formatting • Add locals • Add variables • Split configurations within a module or the default module • Run `terraform fmt` on every commit
  9. Examples of complexity • Complex expressions or repetitive parameter updates,

    and unrelated resource definitions (low cohesion), and inconsistent formatting • Add locals • Add variables • Split configurations within a module or the default module • Run `terraform fmt` on every commit • Code duplication among groups of resources defined for similar purposes • Refactoring into modules
  10. Examples of complexity • Complex expressions or repetitive parameter updates,

    and unrelated resource definitions (low cohesion), and inconsistent formatting • Add locals • Add variables • Split configurations within a module or the default module • Run `terraform fmt` on every commit • Code duplication among groups of resources defined for similar purposes • Refactoring into modules • Requirements for configuration diverge - inclusion/exclusion of resources for a given stage (dev vs. prod) • Conditional resources
  11. Local variables Like variables or named constants in most other

    languages Pros: • Give semantic names to intermediate or constant values • Simplify or reuse expression results Cons: • Overuse can make configurations harder to read
  12. Local variables (before) resource "lb_listener" "some_listener" { … port =

    8443 } resource "firewall_rule" "ingress_rule" { … min = 8443 max = 8443 }
  13. Local variables (after) locals { service_port = 8443 } resource

    "lb_listener" "some_listener" { … port = local.service_port } resource "firewall_rule" "ingress_rule" { … min = local.service_port max = local.service_port } $ git checkout demo_locals
  14. String interpolation + variables Often paired with locals or variable

    blocks Pros: • Variables can be supplied as external inputs • Good for dynamic display names and string parameters • Very useful in the context of modules Cons: • Variables can increase complexity depending on context (i.e. conditional expressions) https://developer.hashicorp.com/terraform/language/parameterize
  15. String interpolation + variables (before) locals { stage = "dev"

    } ... resource "compute" "api_instance" { … # example: evaluates to api-instance-dev display_name = "api-instance-${local.stage}" }
  16. String interpolation + variables (after) variable "stage" { type =

    string description = "Deployment stage (dev or prod)" default = "dev" } resource "compute" "api_instance" { … # example: defaults to api-instance-dev display_name = "api-instance-${var.stage}" } $ git checkout demo_vars
  17. Conditional expressions Often paired with data, locals, or variable blocks

    Pros: • Useful for altering parameters based on input Cons: • Nesting expressions can be difficult to read
  18. Conditional expressions (before) resource "lb_listener" "some_listener" { … port =

    8443 } resource "firewall_rule" "ingress_rule" { … min = 8443 max = 8443 }
  19. Conditional expressions (after) locals { service_port = var.stage == "dev"

    ? 8080 : 8443 } resource "lb_listener" "some_listener" { … port = local.service_port } resource "firewall_rule" "ingress_rule" { … min = local.service_port max = local.service_port }
  20. Putting it all together # pass variable values at runtime

    (default is dev) $ terraform apply vcn-dev lb-dev api-dev Cloud Service http://dev.myapp.com:8080
  21. Putting it all together # pass variable values at runtime

    (default is dev) $ terraform apply $ terraform apply -var="stage=prod" vcn-dev lb-dev api-dev Cloud Service http://dev.myapp.com:8080 https://myapp.com:8443 vcn-prod lb-prod api-prod Cloud Service api-prod api-prod
  22. Modules Reusable chunks of configuration Pros: • Allows for reuse

    of groups of resource definitions • Reduces maintenance and simplifies large configurations Cons: • Harder to read without navigating multiple sources • Need to deal with address changes when refactoring
  23. Modules (before) resource "lb_listener" "dev_listener" { … } resource "firewall_rule"

    "dev_ingress_rule" { … } resource "lb_listener" "prd_listener" { … } resource "firewall_rule" "prd_ingress_rule" { … }
  24. Modules (before) resource "lb_listener" "dev_listener" { … } resource "firewall_rule"

    "dev_ingress_rule" { … } resource "lb_listener" "prd_listener" { … } resource "firewall_rule" "prd_ingress_rule" { … } stage = "dev" port = 8080 stage = "prd" port = 8443
  25. Modules (after) # in dev/main.tf module "service_network" { source =

    "./modules/network" stage = "dev" port = 8080 } # in prd/main.tf module "service_network" { source = "./modules/network" stage = "prd" port = 8443 } $ git checkout demo_modules
  26. Modules example One big config with duplication prod abc xyz

    dev xyz BEFORE AFTER ./modules/abc - main.tf - outputs.tf - variables.tf ./modules/xyz - main.tf - outputs.tf - variables.tf
  27. Conditional resources Conditional single resource or groups of resources (modules)

    Pros: • Enable or disable resource creation conditionally (different stages, based on data sources, variables, capabilities, etc.) Cons: • Can make configurations difficult to reason about • Non-zero chance that resources could be misconfigured (added or removed unintentionally)
  28. Conditional resources (after) locals { is_enabled = var.stage == "prod"

    } resource "some_resource" "abc" { count = local.is_enabled ? 1 : 0 … } module "xyz" { count = local.is_enabled ? 1 : 0 source = "./modules/xyz" … } $ git checkout demo_conditions
  29. Conditional resources example Some hypothetical requirements change • Add a

    load balancer and extra compute instances in production. • Development remains as a single compute with no load balancer.
  30. Conditional resources example vcn-dev api-dev Cloud Service # in dev

    is_enabled = false # in prod is_enabled = true ???
  31. Conditional resources example vcn-dev api-dev Cloud Service vcn-prod lb-prod api-prod

    Cloud Service api-prod api-prod # in dev is_enabled = false # in prod is_enabled = true ???
  32. Recap •What is Terraform? • IaC •Managing Complexity • Locals,

    variables, modules, expressions, conditional resources, … •Resources