Techdecline's Blog

Dependency Management in Infrastructure as Code - Part Two

Intro

This is the second part in a series of two posts outlining alternatives when managing dependencies between different Infrastructure as Code (IaC) configurations. In this part, we'll be covering managing dependencies between two Terraform configurations using Pulumi ESC as central configuration service.

Scenario

In most Hub-Spoke-architectures, responsibilities for managing DNS zones and records are separated between platform and application teams. Therefore, we create two Terraform configurations, one to deploy a Private DNS Zone on Azure and another one registering a record within the created zone.

The required information about the Private DNS Zone (Azure Resource Manager ID) will be written to a central environment after deployment from where it will be read from the application configuration.

Pasted image 20250316220016

Components

Repository

All configuration and script files are stored in the companion repository available at Github.

Terraform/Terragrunt Configurations

TF-DNS

The DNS Zone will be deployed from a Terraform configuration that is wrapped within a Terragrunt Project.

The Terragrunt Project contains an after_hook that triggers the Python solution stored within the esc-mod directory that will be explained in just a minute. Basically, it loads the terraform output and stores the result within a pre-defined Pulumi ESC environment for later retrieval.

TF-APP

The second configuration is called tf-app to mimic a real application configuration (remember, the scenario's emphasis lies on the separation of concerns between platform and application teams).

All it contains is a variable asking for the DNS Zone's resource id and a resource definition to deploy a DNS record within the zone.

The variable will then be populated from the ESC environment.

ESC-MOD

The directory esc-mod contains a Python project that handles the modification of a given ESC environment. It allows creation and update of values within an environment and provides switches to include environment variables including optional Prefixes (TF_VAR_ for our example).

Process

Prerequisites

For easier consumption, we're going to make the following assumptions:

Apply TF-DNS

First, we're applying the configuration using Terragrunt from the CLI: terragrunt apply. This both deploys the DNS Zone as well as sets or updates the configuration value within the environment.

Pasted image 20250316222714

Pasted image 20250316222740

Apply TF-APP

Let's switch to tf-app directory and invoke the second configuration. This time, we'll stick to the Terraform integration guide from Pulumi and invoke the configuration with the following command esc run $PULUMI_PROJECT/$PULUMI_ENVIRONMENT -i -- terraform apply.

Pasted image 20250316223238

If done right, no prompt should ask for the required variable as the value should be fetched from the ESC environment.

Summary

Using a central configuration service like Pulumi ESC allows to de-couple configuration variables from the configuration logic and, as proven within this post, even allows to model dependencies between disconnected configurations way better than the other solutions laid out in part one:

To fulfill the complete vision, the following topics would need some attention going forward (maybe room for another post or two in this series):

#devops #esc #opentofu #platformengineering #pulumi #research #terraform #terragrunt