Azure / terraform-azurerm-avm-ptn-alz

Terraform module to deploy Azure Landing Zones
https://registry.terraform.io/modules/Azure/avm-ptn-alz/azurerm
MIT License
62 stars 15 forks source link

[AVM Module Issue]: enable policy_assignments_to_modify to contain referenced resource outputs #36

Closed phx-tim-butters closed 6 months ago

phx-tim-butters commented 6 months ago

Check for previous/existing GitHub issues

Module specific issue

Issue Type?

Feature Request

(Optional) Module Version

0.5.0

(Optional) Correlation Id

No response

Description

The new work towards using the alzlib is great, and being able to reference policy assignment adjustments through HCL is fantastic.

However, I need to pull in referenced TF controlled resources (used within the same root module using the ptn alz module). However, when used on first run (nothing in state), the alz module will fail a plan. Only when the referenced resources exist in state, does it allow me the ability to specific referenced resources within the policy_assignments_to_modify. I'm circumventing this by using -target for now, to create the resources first.

Error Details Only errors when there are two Management Groups linked to the Root Group

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 3.74.0"
    }
  }
}

provider "azurerm" {
  features {
  }
tenant_id                    = "a41a5ab6-e484-4ea6-adcd-f90808559e04"
subscription_id      = "70743c4f-c37c-4d70-bdad-b06a14e2260d"
}

# This allows us to get the tenant id
data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "update_manager" {
  name = "rg_test"
  location = "uksouth"
}

resource "azurerm_maintenance_configuration" "this" {
    name = "ring1"
  resource_group_name = azurerm_resource_group.update_manager.name
  location            = azurerm_resource_group.update_manager.location
    scope = "InGuestPatch"

  window {
        start_date_time = "2024-01-03 00:00"
        duration = "03:55"
        time_zone = "GMT Standard Time"
        recur_every = "Week"
  }

  install_patches {
    windows {
        classifications_to_include = ["Critical", "Security", "Definition"]
    }
    reboot = "IfRequired"
  }
}

module "alz_archetype_root" {
  source  = "Azure/avm-ptn-alz/azurerm"
  version = "0.5.0"
  id                                 = "root"
  display_name                       = "root"
  parent_id                          = data.azurerm_client_config.current.tenant_id
  base_archetype                     = "root"
  default_location                   = "uksouth"

  policy_assignments_to_modify = {
    Update-Ring1 = {
      parameters = jsonencode({
        maintenanceConfigurationResourceId = azurerm_maintenance_configuration.this.id
      })
    }
  }
}

module "alz_archetype_platform" {
  source  = "Azure/avm-ptn-alz/azurerm"
  version = "0.5.0"
  id                                 = "plat"
  display_name                       = "plat"
  parent_id                          = module.alz_archetype_root.management_group_name
  base_archetype                     = "platform"
  default_location                   = "uksouth"
}

module "alz_archetype_landing_zones" {
  source  = "Azure/avm-ptn-alz/azurerm"
  version = "0.5.0"
  id                                 = "landing_zones"
  display_name                       = "landing_zones"
  parent_id                          = module.alz_archetype_root.management_group_name
  base_archetype                     = "landing_zones"
  default_location                   = "uksouth"
}
│ Error: Unable to add management group
│
│   with module.alz_archetype_landing_zones.data.alz_archetype.this,
│   on .terraform\modules\alz_archetype_landing_zones\main.tf line 5, in data "alz_archetype" "this":
│    5: data "alz_archetype" "this" {
│
│ multiple root management groups: plat and landing_zones

phx-tim-butters commented 6 months ago

Just fyi, I'm simplifying the config as per above - I'm actually using a custom lib to specify a policy assignment for applying the Azure Update Manager config as an example.

Further to example above for sake of testing; Override achetype =

{
  "base_archetype": "root",
  "name": "root_override",
  "policy_assignments_to_add": [
    "Update-Ring1"
  ]
}
{
  "name": "Update-Ring1",
  "type": "Microsoft.Authorization/policyAssignments",
  "apiVersion": "2019-09-01",
  "properties": {
    "description": "You can use Azure Update Manager in Azure to save recurring deployment schedules to install operating system updates for your Windows Server and Linux machines in Azure, in on-premises environments, and in other cloud environments connected using Azure Arc-enabled servers. This policy will also change the patch mode for the Azure Virtual Machine to 'AutomaticByPlatform'. See more: https://aka.ms/umc-scheduled-patching",
    "displayName": "Schedule recurring updates using Azure Update Manager - Ring 1 (Tuesday Midnight)",
    "notScopes": [],
    "parameters": {
      "maintenanceConfigurationResourceId": {
        "value": ""
      },
      "tagValues": {
        "value": [
          {
            "key": "Update Manager Policy",
            "value": "Ring1"
          }
        ]
      }
    },
    "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/ba0df93e-e4ac-479a-aac2-134bbae39a1a",
    "nonComplianceMessages": [
      {
        "message": "Azure Update Manager Update not applied"
      }
    ],
    "scope": "${current_scope_resource_id}",
    "enforcementMode": null
  },
  "location": "${default_location}",
  "identity": {
    "type": "SystemAssigned"
  }
}
matt-FFFFFF commented 6 months ago

Hi @phx-tim-butters thanks for reporting this

In our alzreference demo, we do supply defaults in from resources in the same root module and this works.

The error you are getting is strange and I will try to reproduce

matt-FFFFFF commented 6 months ago

I have managed to reproduce, it seems Terraform is trying to creating the plat and landing_zones before the root.

Because the provider can't find the root MG in its memory, it assumes that the plat and landing_zones MGs have external parents.

matt-FFFFFF commented 6 months ago

As a workaround, for now, if you remove the dependency between the policy assignment parameter and the resource, then it will work.

You can interpolate the resource id using locals, e.g.:

/subscriptions/${local.subscription_id}/resourceGroups/${local.resourceGroupName}/providers/...

matt-FFFFFF commented 6 months ago

Hi @phx-tim-butters

I have fixed this now, upcoming release of 0.6.0 should resolve - I also took your example and published it as a demonstration.

matt-FFFFFF commented 6 months ago

fixed by #35

phx-tim-butters commented 6 months ago

Awesome stuff Matt thank you.