top of page

Terramate: Conditional Code Generation With tm_try

Jānis Orlovs

At CWISE we use Terraform in conjunction with Terramate (https://terramate.io) very extensively

Terramate is being used to do the following things:

  • Scale and orchestrate large Terraform workflows, to avoid Terralith

  • Auto generate Terraform code

There are alternative solutions like Terragrunt. But based on our experience with TM since 2022 we have found that it's much more easier and faster to use than Terragrunt.


One of the main features of Terramate is code generation. For example, generating common backend or data source configurations everywhere in the code base provides consistency.


The Terramate code generation feature is very straightforward:

  1. You define a code block to generate with the "generate_hcl" function. For example, backend generation for all code base from global terramate.tm.hcl configuration:

generate_hcl "backend.tf" {
  content {
    terraform {
      required_version = "1.5.1"
      backend "s3" {
        bucket         = "terraform-state-example"
        key            = "tf${terramate.path}"
        region         = "eu-north-1"
        dynamodb_table = "terraform-state-example"
        encrypt        = true
      }
    }
  }
}
  1. Execute "terramate create" or "terramate generate" and code will be generated everywhere as "backend.tf"


Terramate Conditional Generation using tm_try

There are cases, when basic Terramate general code generation falls short. For example, scenarios where you need to create Terraform provider configuration with different providers.

To tackle these cases, we use tm_try function, to generate code conditionally.

How does it work? tm_try to find the first true condition. In most cases, we are using boolean.

For example, in main terramate.tm.cl we set conditional up data source generation:

terramate {
  config {
    git {
      default_branch = "main"
    }
  }
}

globals {
  generate_data_source_google_ip = true
  generate_data_source_facebook_ip = false
}

generate_hcl "terramate_data.tf" {
  condition = tm_try(global.generate_data_source_google_ip, true)
  content {
    data "dns_a_record_set" "domain" {
      host = "google.com"
    }
  }
}

generate_hcl "terramate_data.tf" {
  condition = tm_try(global.generate_data_source_facebook_ip, true)
  content {
    data "dns_a_record_set" "domain" {
      host = "facebook.com"
    }
  }
}

And in Terramate stack level in for where to obtain the Facebook dns record we will set in the globals:

globals {
  generate_data_source_google_ip = false
  generate_data_source_facebook_ip = true
}

This will ensure that the desired outcome is generated.


Update from Terramate Team to use tm_dynamic


Soren from Terramate suggested to use tm_dynamic


globals {
  generate_data_source_google_ip = true
}

generate_hcl "terramate_data.tf" {
  lets {
    condition = tm_try(global.generate_data_source_google_ip, true)
  }

  content {
    tm_dynamic "resource" {
      for_each = tm_toset(["domain"])
      iterator = value
      labels   = ["dns_a_record_set", value.value]

      content {
        host = tm_ternary(true, "google.com", "facebook.com")
      }
    }
  }
}


Limitations of tm_try


Main limitation of tm_try is that you need to define two separate conditions:


generate_hcl "terramate_data.tf" {
  condition = tm_try(global.generate_data_source_google_ip, true)
  content {
    data "dns_a_record_set" "domain" {
      host = "google.com"
    }
  }
}

generate_hcl "terramate_data.tf" {
  condition = tm_try(global.generate_data_source_google_ip, false)
  content {
    data "dns_a_record_set" "domain" {
      host = "facebook.com"
    }
  }
}

Will not work and will generate the error of code generation



Summary

Terramate with tm_try makes code generation much more flexible for Terraform, allowing you to scale workflows.

There are some limitations, but in general it's very useful tool


 

Recent Posts

See All

CWISE

Address

SIA CWISE, EU VAT ID: LV40203251662
Biekensalas iela 26, Riga, Latvia, LV1004

Contact

+37126699329

©2024 CWISE SIA

bottom of page