Flatiron Labs
Published in

Flatiron Labs

Building Dynamic Outputs with Terraform Expressions and Functions

How to DRY up your modules with for, for_each, and zipmap

The Static Approach

While building out a set of Terraform modules to define some AWS resources at The Flatiron School, we ran into an interesting challenge. We needed to be able to do the following:

  • Create an AWS ECS Task Definition resource with a container definition using those secrets.

Building Dynamic Resources with for_each

First we’ll solve our repetition problem. Instead of manually writing a new AWS Secrets Manager resource definition for every secret we want to create, we’ll define a reusable module that will take in an input of a list of secrets to establish. Our module will use Terraform’s for_each expression to iterate over that list and create a resource for each one.

  • The name of the application.
  • At such time as we want to build a set of AWS Secrets Manager resources for a new application, we can call on our secrets-module module with ease. All we need to do is define a new module my-other-app-application-secrets, with its own variable that lists the secrets to create. Easy!

Building Dynamic Resources with for

We need our secrets module to output the exact input our container definition requires. Before we discuss how we’ll do this, let me introduce the container definition module that our setup utilizes. This post assumes that we have a container definition module already set up that expects the following input:

Generating Dynamic Output with for and zipmap

We’ll define an output for our secrets module:

var.application_secrets
values(aws_secretsmanager_secret.application-secret)[*]["arn"]

Using Dynamic Outputs in the Container Definition

Remember that we have a container definition module that looks something like this:

  • We’ve made building out new applications and their resources into a relatively quick and painless process. We can call on our secrets module again and again to dynamically create the secrets resources for any new apps we want to spin up, and use the output from those module calls in each app’s corresponding container definitions with ease.

Conclusion

Terraform’s reusable modules and helpful expressions and functions allowed us to write DRY “infrastructure as code”. With the help of the for_each expression, we were able to define a module that dynamically creates AWS Secrets Manger resources with just a few lines of code. With the help of the for expression and zipmap function, we were able to take that module one step further. We defined dynamic module output that is formatted just right for our corresponding container definition input. As a result, we've given ourselves a sane and replicable approach to generating complex application infrastructure.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Sophie DeBenedetto

Sophie is a Senior Software Engineer at GitHub and co-author of Programming Phoenix LiveView