Search code examples
azurescopeterraformazure-policyazure-management-groups

How to define and assign an Azure Policy on a Management Group Scope using Terraform?


I want to assign one of the built-in policies of Azure to a management group using Terraform. The problem I'm facing is, while assigning policies with Terraform can be fairly easily done by setting the scope properly to the subscription id or resource group or specific resource that the policy is to be applied upon, changing it to management group gives rise to an error. This, I believe, is due to the fact that the policy definition location needs to be the management group is well, so that we may make the scope for azurerm_policy_assignment equal to the desired management group. Could I please get some help regarding this, so as to how to define the policy, the definition location being that of the management group in Terraform ? For instance, I've tried setting scope = the management group id, in the resource azurerm_policy_definition block preceeding the policy assignment block, but I get "scope" to be an unexpected keyword there. Neither does setting the "location" work.

I'll also share my current workaround.

As a result of the problem I'm facing, what I'm currently doing is duplicating the definition of the policy from the portal, changing the "definition location" to be equal to the management group id there, and then passing the new policy definition id and scope to be the management group in my subsequent Terraform code, which now works now that the policy is defined in the concerned location of the management group.

But I want to do away with this manual intervention and intend to complete it using Terraform script solely. Being relatively new to the field, is there a way I could assign the policy to a particular management group in Terraform, having duly defined it first in the same scope so as to not lead to any error ?

Alternatively posed, my question could also be interpreted how to assign a Azure policy to a specific management group scope using Terraform script only ( one may assume, management groups to be created using Terraform too, although that part is taken care of ).


Solution

  • To assign a Built-In policy, I would suggest referencing the desired Policy Definition as a data source. This way, you do not need to declare/create a new Policy Definition in your Terraform code. (Although alternatively, you could just place the Definition ID for the Built-In Policy as the value for policy_definition_id in the azurerm_policy_assignment resource block).

    Here is an example of referencing a Built-In Policy Definition as a Data source in Terraform.

    Below is an example of what your Terraform would look like to take a Built-In Policy Definition from the Portal and assign to a management group.

    # Pull in built-in definition as a data source
    # Link to definition: https://portal.azure.com/#blade/Microsoft_Azure_Policy/PolicyDetailBlade/definitionId/%2Fproviders%2FMicrosoft.Authorization%2FpolicyDefinitions%2Fa451c1ef-c6ca-483d-87ed-f49761e3ffb5
    data "azurerm_policy_definition" "example" {
      display_name = "Audit usage of custom RBAC rules"
    }
    
    # Reference the definition data source in the policy assignment resource
    resource "azurerm_policy_assignment" "example" {
      name = "assign-audit-rbac"
      policy_definition_id = data.azurerm_policy_definition.example.id
      scope = "/providers/Microsoft.Management/managementGroups/MyManagementGroup"
    }