Use archetype_config_overrides to set role assignments in Azure landing zones Terraform module

Changelog / Warnings

The below example does not work on the first plan/apply because it requires the object id of the AAD Group to be already known. The post has been updated to instead use data sources for the AAD Groups, and a new example has been added where outputs from terraform-azurerm-caf-enterprise-scale is used to assign permissions

Using terraform-azurerm-caf-enterprise-scale and custom landing zone archetypes makes it easy to modify role assignments by using the access_control block under parameters. To set role assignments for the built-in management groups is a bit different, and not very clearly documented in the repository wiki.

To override the role assignments for the built-in management groups you need to use the archetype_config_overrides block. The block requires you to set the archetype_id, parameters and acess_control:

1map(
2  object({
3    archetype_id   = string
4    parameters     = map(any)
5    access_control = map(list(string))
6  })
7)

A list of built-in archetype definitions can be found by in terraform-azurerm-caf-enterprise-scale/modules/archetypes/lib/archetype_definitions/. By selecting the definition relevant archetype definition we can add our own acess_control configuration like this:

 1data "azuread_group" "platform_owner" {
 2  display_name     = "Azure-Platform-Owner"
 3  description      = "Grant Owner role on Platform Management Group"
 4  security_enabled = true
 5}
 6
 7data "azuread_group" "platform_contributor" {
 8  display_name     = "Azure-Platform-Contributor"
 9  description      = "Grant Contributor role on Abyss IT Management Group"
10  security_enabled = true
11}
12
13data "azuread_group" "platform_reader" {
14  display_name     = "Azure-Platform-Reader"
15  description      = "Grant Reader role on Platform Management Group"
16  security_enabled = true
17}
18
19module "azure_landing_zones" {
20    source           = "Azure/caf-enterprise-scale/azurerm"
21    [...]
22    archetype_config_overrides = {
23        platform = {
24            archetype_id = "es_platform"
25            parameters   = {}
26            access_control = {
27                Owner = [
28                    data.azuread_group.platform_owner.object_id
29                ]
30                Contributor = [
31                    data.azuread_group.platform_contributor.object_id
32                ]
33                Reader = [
34                    data.azuread_group.platform_reader.object_id
35                ]
36            }
37        }
38    }
39}

The above example will add three separate groups with the Owner, Contributor and Reader role to the Platform management group (which contains the Connectivity, Identity and Management groups/subscriptions). I prefer to always assign permissions to groups to make administration easier. And then I can expand this example with access reviews for group memberships as well as combining it with Privileged Identity management for just-in-time membership/ownership (although it should be mentioned that the azuread-provider has no support for access reviews and privileged identity management)

Use module outputs to assign permissions

If role assignments are added before the landing zones architecture is deployed the first time running terraform plan or terraform apply will error with the following message: local.azurerm_role_assignment_enterprise_scale will be known only after apply. The cause of this error is described in #651.

A workaround is to instead combine the module outputs to get the Management Group id’s with azurerm_role_assignment

 1resource "azuread_group" "platform_owner" {
 2  display_name     = "Azure-Platform-Owner"
 3  description      = "Grant Owner role on Platform Management Group"
 4  security_enabled = true
 5}
 6
 7resource "azurerm_role_assignment" "platform_owner" {
 8  scope                = module.azure_landing_zones.azurerm_management_group.level_2["/providers/Microsoft.Management/managementGroups/${var.root_id}-platform"].id
 9  role_definition_name = "Owner"
10  principal_id         = azuread_group.owner.id
11}