Terraform: keeping your code dry

October 31, 2023
Sergio Rua

Introduction

We extensively use Terraform for managing lots of things, not just the classic cloud providers but all sorts: Cloudflare, Rundeck jobs, Bitbucket repositories, Kubernetes resources, ArgoCD applications, [very long etc]

On some occasions, the deployments to the different environments may contain code that is not yet ready for prime time, code that is very much a work in progress.

I needed a way of conditionally applying the code to some environments but not others while the code was being worked out.

Many options

There are lots of different ways to do this. I probably used the top 5 at one time or another. One of the most popular is to use a git branch strategy where each deployable environment is a branch (develop, staging, production, etc).

I don’t particularly like this because branches will get very out of sync over time and merging becomes an absolute nightmare.

Terragrunt offers some options but neither of the examples provided was a good match for my needs. Therefore, I came up with my own Terragrunt based solution that I’m going to share below with you.

What’s Terragrunt?

Terragrunt is a thin wrapper that provides extra tools for keeping your configurations DRY, working with multiple Terraform modules, and managing remote state.

Terragrunt in-progress

What I’ve done is I have an inprogress folder where I keep any terraform resources I’m not intending on deploying to production. Then, my terragrunt.hcl configuration includes the directory contents using:

locals {
  env        = get_env("ENVIRONMENT")
}

generate "inprogress" {
  path      = "inprogress.tf"
  if_exists = "overwrite"
  contents = templatefile("inprogress/includes.tmpl", {
    files = fileset("inprogress", "*.tf"),
    env   = local.env,
  })
}

As you can read from the snippet above, the generateresource will read all the .tf files from the inprogress directory and apply the template includes.tmpl (see below):

%{ if env != "prd" }
%{ for f in files ~}
${file("inprogress/${f}")}
%{~ endfor }
%{ endif }

The result is an inprogress.tf file that will be picked up by Terraform to apply only if the environment variable ENVIRONMENT is set to a value other than prd.

The idea is pretty simple and you can do quite a lot with the template adding more conditions, loops, etc if you need.

️A final note, just remember to add the inprogress.tf to your .gitignore as you don’t want this file to be committed to git by mistake.

As always, if you need help, get in touch.

Subscribe to newsletter

Subscribe to receive the latest blog posts to your inbox every week.

By subscribing you agree to with our Privacy Policy.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Ready to Transform 

Your Business?