Recently, some of our modules have required breaking changes and we didn’t have a good way to communicate the impacts to users and allow them to pin to a specific version. While an astute Terraform user could pin to a Git SHA, it is a less than ideal approach. As a result, I investigated how to version Terraform modules and ensure the approach is consistent…and hopefully automated.

Before delving into the approach and tooling, it is worth having a quick review of what semantic versioning is. defines semantic versioning as:

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version…

Gabs library

Developing unit tests for Terraform modules is critical to validating behavior and also doing regression testing.

Recently, I had to do regression testing on about 15 modules during a Terraform 0.14 migration and the tests were a life saver. However, I have found that validating outputs from modules using Terratest has become overly tedious as we expose the full objects and perform validations on various attributes, arrays, maps, nested objects, etc.

Terratest is a golang library that allows you to call a terraform module (init/apply), validate outputs, and then teardown the temporary infrastructure. The terraform module provides many OutputXXXX functions…

In my latest blog entry, I brought up details about the new feature in TF 0.14 where you can mark inputs and outputs as sensitive. This feature was also the cause of a panic issue found in 0.14.3. I am happy to announce this has been resolved in 0.14.4 which was released yesterday.

As I continued my module validation against Terraform 0.14, I ran into a new issue that stems from the usage of sensitive attributes.

Sensitive variable, or values derived from sensitive variables, cannot be used as for_each arguments. …

While things quiet down for the holidays, I figured I’d take a crack at validating our modules against Terraform 0.14. The goal of this article is to focus on the changes required to existing modules and less so about the full list of changes.

HashiCorp released the full changes at Upgrading to Terraform v0.14 — Terraform by HashiCorp.

In this blog entry, I go over the changes to the provider configuration, sensitive outputs (which is great but has a blocking bug), a more stringent linter, and new function named alltrue.

Provider Configuration

In Terraform 0.13, HashiCorp introduced a new way of defining…

Terragrunt — The multi-tool

Terragrunt, a small wrapper around Terraform, adds a ton of capabilities. In my previous posts, I focused on capabilities and using it in novel ways.

In this article, I focus on how Terragrunt behaves to accomplish the capabilities. I share some lessons learned and how to troubleshoot. To start with, I go over a sample hierarchical configuration structure, Terragrunt’s order of operation, caching, source path gotchas, and content generation.

Terragrunt Configuration Structure

Let’s start with a two-level…

In this blog entry, I will combine a few topics as they are related:

  • Multi-Account / Multi-Subscription support — Deploy parts of the environment to different subscriptions
  • Using different credentials for parts of the infrastructure — Allows to follow a least privilege approach when deploying parts of the environment

This blog expands upon a previous entry discussing dependency management.

Multi-Account / Multi-Subscription support

When managing an enterprise scale cloud environment, it is important to divide it into functional pieces that will allow segregation of duties and minimizing blast radius. …

Sample Terraform Graph

Terraform provides a graph engine that is rather smart. As you use attributes from one resource in another, it generates implied dependencies in the deployment graph. This is probably one of the best features of the language. If you have code ARM templates (Azure’s JSON DSL), you will remember vividly where you have to define all the dependencies by hand.

If you didn’t know about Terraform’s graphing approach, take your favorite module and run the following command. It will generate a graph you can open in the browser to see the dependencies.

terraform graph | dot -Tsvg > graph.svg


Remote State Management

In the introductory blog entry, I highlighted one of Terragrunt’s capabilities: generating remote state configurations on the fly. Before delving into how it works, let’s first see how you handle this in vanilla Terraform.

Terraform’s Approach

With Terraform, to have your state stored remotely, you need to create a back-end configuration as follows:

terraform {
backend "azurerm" {
tenant_id = "xxxxxxxx-84e2-4390-b0b9-c79fdf7323ea"
subscription_id = "xxxxxxxx-b1ee-41e4-8bd5-e4a04300b5c1"
resource_group_name = "rg-tfstates-prod"
storage_account_name = "stprod"
container_name = "prod"
key = "core-routing/terraform.tfstate"
snapshot = true

For each deployment, you will need the above configuration and modify the key and perhaps the resource group/storage account/container names. …

Terragrunt Logo

It’s been a while since I’ve posted and it is primarily because I have been super busy on a recent engagement. One the challenges we faced was orchestrating the deployments of multiple Terraform stacks.

Terraform excels as a Infrastructure as Code DSL. However, it lacks when it comes to building an environment where deployments are interdependent. This becomes very challenging when you want to manage all the infrastructure for a landing zone (foundational deployment of core infrastructure for a cloud platform).

Before going further, let me clarify some of the terms I will be using:

  • Module — Terraform modules encapsulate…

Terraform dynamic block

Many Azure resources such as Azure Container Registry (ACR), Storage and Key Vault support adding network level protections by granting certain IP ranges or Virtual Networks to access the resource. These controls are an important part in establishing a layered approach to controlling access to resources. While many resources are moving away from Virtual Network rules in favor of Private Endpoints, you will find my tribulations useful in learning some Terraform constructs.

This entry will focus on some of the challenges I faced trying to generate the list of network rules from an input list of subnet identifiers using Terraform…

Patrick Picard

Sr. Cloud Consultant

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