globalbao/terraform-azurerm-policy-exemptions

Expected behaviour for exempting resource groups of the same exact name but of different subscriptions

Closed this issue · 4 comments

Although it was mentioned in https://github.com/globalbao/terraform-azurerm-policy-exemptions#variables that resourceGroupName is the name of the Resource Group. I thought of trying to put the full resource group id but this error came up:
Error: "resource_group_name" may not exceed 90 characters in length

If an assignment is at tenant or management group level and the exemption needs to be applied to 2 or more resource groups of the same exact name but of different subscriptions, what is the expected behaviour? I would suggest to add the expected behaviour in the documentations if that's Ok.
Additionally, it would be good enhancement if the resourceGroupName field can accept resource group id which gives us ability to specify a specific resource group from a subscription to exempt.

Hi @tpidor

This module uses the AzureRM resource_group_template_deployment to deploy the exemption JSON as an ARM template so we're limited by the arguments available. So would recommend sticking with passing in a name, not an id, to the resourceGroupName variable.

I'm also interested in knowing what the expected behavior is when using this module in the scenario you mentioned. Will test that out myself 😄

If an assignment is at tenant or management group level and the exemption needs to be applied to 2 or more resource groups of the same exact name but of different subscriptions, what is the expected behaviour? I would suggest to add the expected behaviour in the documentations if that's Ok.

HI @jesseloudon,

This may not be directly related to this ticket but thought of asking you here.
We were applying our policy exemption automation at tenant management group level which consists of several subscriptions.
We have SPNs with all the required permissions. One SPN for nonprod at the subscription level only and another SPN for prod environment that has access at the tenant management group level. Nonprod policies are being deployed using the nonprod SPN to a nonprod subscription only. Deployment of nonprod policies and exemptions using the nonprod SPN are working well. However using prod SPN to deploy policy exemptions to multiple different resource group names under different subscriptions, for some reason automation is failing with this error:

Error: validating Template Deployment "PROD_ABC-Ex-123" (Resource Group "rg-name"): requesting validating: resources.DeploymentsClient#Validate: Failure sending request: StatusCode=404 -- Original Error: Code="ResourceGroupNotFound" Message="Resource group 'rg-name' could not be found."

We did looked at the prod SPN permissions but everything was configured correctly. All SPNs include the required permissions as you suggested in #6. Prod SPN does not have issues deploying assignments with scope to different subscriptions or resource groups from different subscriptions. Automation is only failing with the policy exemptions deployment with the above error.
Any idea or clue with the above error ResourceGroupNotFound?

HI @jesseloudon,

This may not be directly related to this ticket but thought of asking you here.

We were applying our policy exemption automation at tenant management group level which consists of several subscriptions.

We have SPNs with all the required permissions. One SPN for nonprod at the subscription level only and another SPN for prod environment that has access at the tenant management group level. Nonprod policies are being deployed using the nonprod SPN to a nonprod subscription only. Deployment of nonprod policies and exemptions using the nonprod SPN are working well. However using prod SPN to deploy policy exemptions to multiple different resource group names under different subscriptions, for some reason automation is failing with this error:

Error: validating Template Deployment "PROD_ABC-Ex-123" (Resource Group "rg-name"): requesting validating: resources.DeploymentsClient#Validate: Failure sending request: StatusCode=404 -- Original Error: Code="ResourceGroupNotFound" Message="Resource group 'rg-name' could not be found."

We did looked at the prod SPN permissions but everything was configured correctly. All SPNs include the required permissions as you suggested in #6. Prod SPN does not have issues deploying assignments with scope to different subscriptions or resource groups from different subscriptions. Automation is only failing with the policy exemptions deployment with the above error.

Any idea or clue with the above error ResourceGroupNotFound?

Hi @tpidor this sounds like the prod SPN needs to use the relevant subscription context. Because the error suggests the SPN can't find the RG in its current subscription context.

From your Terraform calling module can you give me more info of how are you switching/targeting multiple subscriptions and linking the exemption code (via this module) to the relevant subscriptions?

Hi @jesseloudon

We have one automation that deploys assignments, initiatives, policies and exemptions into Azure Tenant. The SPN used by this automation is configured and assigned at tenant level, which means it has access to all management groups, subscriptions and resource groups within the tenant. This automation can create assignments with scopes to different subscriptions or resource groups from different management groups. There's no issue from here.

With the exemption part, we have this main.tf with fields as per the readme here https://github.com/globalbao/terraform-azurerm-policy-exemptions. There are more RGs here but only give 2 examples. These 2 resource groups are from different subscriptions and could be from different management groups but all in the same tenant. This main.tf is called by a parent calling module (shown below) which passes multiple assignment ids list or map. This map contains the full assignment id created during the automation. This also means that the exemption module will wait for all assignments to be created first before the exemptions going to be deployed. During the automation, Terraform apply picks up all the assignment config and apply them into tenant root level, management group or subscription level depending on what assignment scope is defined.

policy/exemptions/main.tf

variable "assignment_ids_map" {
  type = map(any)
}

module "policy_exemptions" {
  source  = "globalbao/policy-exemptions/azurerm"
  version = "0.1.1"
  policyExemptions = {
    PROD_ABC-Ex-123_01 = {
      deploymentMode     = "Incremental"
      name               = "PROD_ABC-Ex-123_01"
      displayName        = "PROD_ABC-Ex-123_01 - Exemption for preventing ...."
      description        = "Exemption from blocking new ...."
      resourceGroupName  = "rg-name-01"
      policyAssignmentId = var.assignment_ids_map["PROD_ABC-As-123_00001"]
      policyDefinitionReferenceIds = []
      exemptionCategory = "Waiver"
      expiresOn         = "2021-11-30T23:59:00.0000000Z"
      metadata = {
        "requestedBy": "Requester",
        "approvedBy": "Approver",
        "ticketRef": "Ticket-01"
      }
    },PROD_ABC-Ex-123_02 = {
      deploymentMode     = "Incremental"
      name               = "PROD_ABC-Ex-123_02"
      displayName        = "PROD_ABC-Ex-123_02 - Exemption for preventing ...."
      description        = "Exemption from blocking new ...."
      resourceGroupName  = "rg-name-02"
      policyAssignmentId = var.assignment_ids_map["PROD_ABC-As-123_00001"]
      policyDefinitionReferenceIds = []
      exemptionCategory = "Waiver"
      expiresOn         = "2021-11-30T23:59:00.0000000Z"
      metadata = {
        "requestedBy": "Requester",
        "approvedBy": "Approver",
        "ticketRef": "Ticket-02"
      }
    }
  }
}

calling module

locals {
    assignment_ids_map = {
        for assignment in var.policy_assignment_map : "${assignment.name}" => assignment.id
    }
}

module "exemptions" {
  source = "../../../policy/exemptions"
  assignment_ids_map = local.assignment_ids_map
}

I did try to replicate the issue on another test tenant today. I setup the SPN at tenant level, put assignment config with scope at tenant root level, then add 2 exemptions on 2 different resource groups (1 exemption each group) from different subscriptions. The result is that, it successfully created the exemption on one RG while it failed on another RG with the same error - Error: Code="ResourceGroupNotFound" Message="Resource group 'rg-name' could not be found.". Then I thought maybe the exemption module picks-up first resource group and creates it successfully while the rest will fail since they're on a different subscription, so I tried switching over the RG names but still fail on the same RG name.

With creating exemption using az cli, it accepts scope with full resource group id containing subscription. How does this exemption Terraform module knows the subscription id? Do you get the subscription from the active session and dynamically generate the resource group id? If yes, what if the assignment id is scoped on a different subscription as per my above explanation? If not, how can we tell to the exemption module which subscription to create the exemption? Keen to hear your analysis on this ticket and what would be the behaviour looks like. Thanks for responding to my queries again, and good job on this exemption module.