Posts tagged terraform

Share common information between Terraform configurations

Suppose you have 2 or more applications which are sharing the same environment (datacenter, zone, subscription, network etc.) and you need to reflect environment changes in applications’ Terraform configuration files.

HasiCorp is not rushing to implement include functionality in Terraform but they propose to use Data-Only modules pattern.

You can create a shared module shared_constants which could look like this:

#
# Some Data sources
#

data "azurerm_subnet" "example" {
  name                 = "sn-backend"
  virtual_network_name = "vnet-production"
  resource_group_name  = "rg-networking"
}

#
# Some known constants
#

locals {
   firewall_public_ip = "205.10.107.10/32"
}

#
# Outputs
#

output "backend_subnet_id" {
    description = "Azure Subnet ID"
    value       = data.azurerm_subnet.example.id 
}

output "firewall_public_ip" {
    description = "Firewall Public IP"
    value       = local.firewall_public_ip 
}

In this case, application 1 and application 2 configuration files should look like this:

module "const" {
    source  = "../shared_constants"
}

resource "azurerm_network_interface" "example" {
  ...

  ip_configuration {
    ...
    subnet_id                     = module.const.backend_subnet_id
    ...
  }
}

The solution can be more powerful if variables are added to constants module, i.e.:

variable "scope" {
    description  = "Constants scope"
    type         = string 
}

locals {
   scopes = {
       "production" = {
          firewall_public_ip = "205.10.107.10/32"
       }
       "development" = {
          firewall_public_ip = "205.20.107.10/32"
       }
   }
}

output "firewall_public_ip" {
    description = "Firewall Public IP"
    value       = local.scopes[var.scope].firewall_public_ip 
}

Application configuration file:

module "const" {
    source  = "../shared_constants"
    scope   = "production"
}

resource "..." "..." {
  ...

  ... = module.const.firewall_public_ip
  ...
}

This solution can be used as in the case, when all configuration is saved in the same place as well for the cases when everything is split over different repositories.