Skip to content

Instantly share code, notes, and snippets.

@magodo
Last active March 11, 2022 11:14
Show Gist options
  • Save magodo/1abf5973d8277c56be61f75282f73dfb to your computer and use it in GitHub Desktop.
Save magodo/1abf5973d8277c56be61f75282f73dfb to your computer and use it in GitHub Desktop.
Azure policy assginment/definition and mgmt group investigation

This gist is to demonstrate how to reproduce Azure policy related issues when creating definitions within or assigning into a newly created management group.

This can be used to reproduce issue: hashicorp/terraform-provider-azurerm#12478.

The configuration is split to two parts, which should be copied to two TF workspaces and run in sequence.

  • The first one (main1.tf) is to provision a parent mgmt group and create a custom policy definition within it
  • The second one (main2.tf) is to provision a child mgmt group and then assign the inherited policy definition to it

There is one thing worth mentioning in the main2.tf, the custom policy definition is retrieved from a data source, where you can either get it from the parent mgmt group or the child. Actually, each one ends up with the same definition (i.e. the same resource id).

If you try to retrieve it from the child mgmt group, and didn't specify a long enough (~5-6 min) delay after child mgmt group created, the returned definition list might not contain the inherited custom policy definition.

On the other hand, if you retrieve it from the parent mgmt group, it will always succeed. However, if you didn't specify a long enough delay, something bad still happens. In this time, the policy assignment PUT API will return you:

400

{
  "error": {
    "code": "InvalidCreatePolicyAssignmentRequest",
    "message": "The policy definition specified in policy assignment example-policy is out of scope. Policy definitions should be specified only at or above the policy assignment scope. If the management groups hierarchy changed recently or if assigning a management group policy to new subscription, please allow up to 30 minutes for the hierarchy changes to apply and try again."
  }
}

(which is what issue hashicorp/terraform-provider-azurerm#12478 is complaining about)

I've submit an issue for this: Azure/azure-policy#918

provider "azurerm" {
features {}
}
resource "azurerm_management_group" "example_parent" {
display_name = "ParentGroup"
}
resource "azurerm_policy_definition" "example" {
name = "only-deploy-in-westeurope"
policy_type = "Custom"
mode = "All"
management_group_id = azurerm_management_group.example_parent.group_id
display_name = "only-deploy-in-westeurope"
policy_rule = <<POLICY_RULE
{
"if": {
"not": {
"field": "location",
"equals": "westeurope"
}
},
"then": {
"effect": "Deny"
}
}
POLICY_RULE
}
provider "azurerm" {
features {}
}
locals {
n = 10
delay = "5m"
}
data "azurerm_management_group" "example_parent" {
display_name = "ParentGroup"
}
resource "azurerm_management_group" "example_child" {
count = local.n
display_name = "ChildGroup-${count.index}"
parent_management_group_id = data.azurerm_management_group.example_parent.id
}
resource "time_sleep" "wait" {
triggers = {
for i in range(local.n) :
i => azurerm_management_group.example_child[i].id
}
create_duration = local.delay
}
data "azurerm_policy_definition" "example" {
count = local.n
display_name = "only-deploy-in-westeurope"
management_group_name = azurerm_management_group.example_child[count.index].name
#management_group_name = data.azurerm_management_group.example_parent.name
depends_on = [time_sleep.wait]
}
resource "azurerm_management_group_policy_assignment" "example" {
count = local.n
name = "example-policy"
policy_definition_id = data.azurerm_policy_definition.example[count.index].id
management_group_id = azurerm_management_group.example_child[count.index].id
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment