The DevOps Jedi

Taking the cloud by storm one line of code at a time....

How I Minimise Terraform Admin Effort & Manage The Constant Change

2023-01-202 min readDarren Johnson

In a previous post I explained why I don’t advocate the use of child modules, but I wanted to quickly explain how I keep Terraform admin overhead to a minimum when creating standard resources whilst also working with the constant rate of change that cloud brings.

When writing a terraform configuration I am specifying how I want the resources to be configured at that point in time. Between major versions of the providers there are few changes to how the resources are configured so I want to be able to reuse all code where possible. I do this by having some standard template code to define resources, and then copying this code using a PowerShell wrapper and substituting in all parts that need to be unique.

This approach allows me to have self-contained ’execution folders’ that do not affect other services outside of my environment but ensures I use a consistent approach to deploying resources.

When there are major version changes, I am able to fully test the template code to ensure its compatibility and update the template accordingly without affecting any existing resources that have been deployed.

To illustrate this, here is some template code for a resource group within a file named resource-group.tf:

resource "azurerm_resource_group" "zzservice_zzenvironment" {
  name     = "zzservice-zzenvironment-rg"
  location = zzlocation
  tags     = var.tags
}

Here is a snippet from the PowerShell script I use to update the template code:

$location = "westeurope"
$service = "blog"
$environment = "msdn"

(Get-Content -Path ./resource-group.tf).Replace("zzservice", $service) | Set-Content -Path ./resource-group.tf -Force
(Get-Content -Path ./resource-group.tf).Replace("zzenvironment", $environment) | Set-Content -Path ./resource-group.tf -Force
(Get-Content -Path ./resource-group.tf).Replace("zzlocation", $location) | Set-Content -Path ./resource-group.tf -Force

This would then update the template code, so it reads:

resource "azurerm_resource_group" "blog_msdn" {
  name     = "blog-msdn-rg"
  location = westeurope
  tags     = var.tags
}

Key Takeaway: Using template code with a PowerShell wrapper allows me to deploy standard configurations for every service I build whilst not depending on any code outside my execution folder.