Featured image of post Day 54: Terraform ESLZ Customization

Day 54: Terraform ESLZ Customization

A guide to assist with configuring for your environment.

Welcome to this overview on customizing ESLZ using Terraform.

Customizing Terraform Landing Zones Deployments

Inside archetype definitions our custom landing zones fall (e.g archetype_definition_es_name_abc.tmpl.json), these JSON files contain all the configuration settings for the landing zones that are specific to that LZ, for example a certain dns policy might be applied to this LZ, we can specify this here instead of bloating out the main.tf file which can also contain all these controls, for example:

Inside a HR JSON:

{
    "es_HR": {
        "policy_assignments": [
            "Deny-IP-Forwarding",
            "Deny-RDP-From-Internet",
            "Deny-Storage-http",
            "Deny-Subnet-Without-Nsg",
            "Deploy-AKS-Policy",
            "Deploy-SQL-DB-Auditing",
            "Deploy-SQL-Threat",
            "Deploy-VM-Backup",
            "Deny-Priv-Escalation-AKS",
            "Deny-Priv-Containers-AKS",
            "Enable-DDoS-VNET",
            "Enforce-AKS-HTTPS",
            "Enforce-TLS-SSL"
        ],
        "policy_definitions": [],
        "policy_set_definitions": [],
        "role_definitions": [],
        "archetype_config": {
            "parameters": {},
            "access_control": {}
        }
    }
}

Inside the main.tf

    "${var.root_id}-hr" = {
      display_name               = "Human Resources"
      parent_management_group_id = "${var.root_id}-landing-zones"
      subscription_ids           = []
      archetype_config = {
        archetype_id   = "es_HR"
        parameters     = {}
        access_control = {}
      }
    }

So you can see in the above examples, you have similar configurations but limit the bloat. You can populate this folder (.terraform\modules\enterprise_scale\modules\archetypes\lib\archetype_definitions) with as many of these JSON files as you want but I believe they need to be referenced within the main.tf file for them to actually come through. Just be aware this folder as mentioned in previous blog will get overwritten so a process needs to be put in place to ensure any custom files are copied across. If anyone is aware of a way to re-route the custom files into perhaps the root folder for example, this would help but as all this is relatively new I have not found a way so far.

The var.root variables themselves are obtained from the variables.tf file in the root, and is generally referred to throughout most of the module.

locals.management_groups.tf

Inside .terraform there is a file called locals.management_groups.tf, this file is also referred to by the above and allows some customisation, for example landing zones can be modified to something like business units or similar friendly name. You can also modify the ${local.root_id} to shift some of the parent groups around, the same goes for values like display name as previously mentioned, for example:

locals {
  # Mandatory core Enterprise-scale Management Groups
  es_core_landing_zones = {
    (local.root_id) = {
      display_name               = "Company Name Here"
      parent_management_group_id = local.root_parent_id
      subscription_ids           = local.es_subscription_ids_map[local.root_id]
      archetype_config           = local.es_archetype_config_map[local.root_id]
    }
    "${local.root_id}-decommissioned" = {
      display_name               = "Decommissioned"
      parent_management_group_id = local.root_id
      subscription_ids           = local.es_subscription_ids_map["${local.root_id}-decommissioned"]
      archetype_config           = local.es_archetype_config_map["${local.root_id}-decommissioned"]
    }
    "${local.root_id}-sandboxes" = {
      display_name               = "Sandboxes"
      parent_management_group_id = local.root_id
      subscription_ids           = local.es_subscription_ids_map["${local.root_id}-sandboxes"]
      archetype_config           = local.es_archetype_config_map["${local.root_id}-sandboxes"]
    }
    "${local.root_id}-landing-zones" = {
      display_name               = "Business Units"
      parent_management_group_id = local.root_id
      subscription_ids           = local.es_subscription_ids_map["${local.root_id}-landing-zones"]
      archetype_config           = local.es_archetype_config_map["${local.root_id}-landing-zones"]
    }
    "${local.root_id}-platform" = {
      display_name               = "Platform"
      parent_management_group_id = local.root_id
      subscription_ids           = local.es_subscription_ids_map["${local.root_id}-platform"]
      archetype_config           = local.es_archetype_config_map["${local.root_id}-platform"]
    }
    "${local.root_id}-connectivity" = {
      display_name               = "Connectivity"
      parent_management_group_id = "${local.root_id}-platform"
      subscription_ids           = local.subscription_ids_connectivity
      archetype_config           = local.es_archetype_config_map["${local.root_id}-connectivity"]
    }
    "${local.root_id}-management" = {
      display_name               = "Management"
      parent_management_group_id = "${local.root_id}-platform"
      subscription_ids           = local.subscription_ids_management
      archetype_config           = local.es_archetype_config_map["${local.root_id}-management"]
    }
    "${local.root_id}-identity" = {
      display_name               = "Identity"
      parent_management_group_id = "${local.root_id}-platform"
      subscription_ids           = local.subscription_ids_identity
      archetype_config           = local.es_archetype_config_map["${local.root_id}-identity"]
    }
  }

Its worth noting this file lives within a folder that can be overwritten when someone performs a git init or terraform init for the first time, this would easily be resolved we either don’t make any changes to the file or we deploy a method to ensure the correct file is copied across each time, which we can cover in a CICD pipeline or through various other methods.

In the next blog I am going to look into policies in greater detail and write up how these get applied and how these can also be customized.