Azure / terraform-azurerm-caf-enterprise-scale

Azure landing zones Terraform module
https://aka.ms/alz/tf
MIT License
872 stars 574 forks source link

Feature request: Working with Policy exemptions in Enterprise scale #277

Open johankardell opened 2 years ago

johankardell commented 2 years ago

Community Note

Description

I have several use cases where I need to use Policy exemptions for a single policy that's part of a policy initiative, and as far as I can see that's not possible using CAF-ES module. It looks like it's not possible in AzureRM ( https://github.com/hashicorp/terraform-provider-azurerm/issues/9197 ) but I was hoping for a crafty way around the problem.

Describe the solution you'd like

I would like to be able to assign NIST/CIS/ISO27001 to a management group, use the Deny effect on a number of policies for a number of things that are important to me (for example "Storage accounts should restrict network access") and then add an Exemption for a Resource Group in one Subscription where I don't feel that this is important (or applicable). The only way of doing this today use the CAF-ES module is to add an Exclusion of the entire NIST initiative for the resource group that can't have "Storage accounts should restrict network access", which feels a bit blunt.

I'm currently investigating if I could use an ARM template deployment in combination with the CAF-ES module, but this also feels like shoe horning a solution that will break sooner or later since it's hard to synchronise the lifecycle of the two. Since Terraform has a tendency to recreate policy assignments every now and then there's a risk of having many stale Exemptions when an assignments gets a new ID. It feels like the only proper solution is to add support to the AzureRM provider to create Exemptions, but I'm open for any good workarounds until that happens. This has got to be an issue for a lot of organisations using Enterprise Scale?

Besides using ARM deployments, the only workaround I see is to NOT use Deny effects in an Initiative (only Audit), and deploy separate assignments of each policy definition (not using Initiatives) to the Management group level with an Exclusion (NotScope) set the the Resource group where the policy shouldn't be applied. In my case there is a risk of running into the limit of number of allowed policy assignments per scope, so this doesn't feel like a good solution either (and I would lose the Expiration date functionality as well).

Additional context

krowlandson commented 2 years ago

Hi @johankardell... an interesting ask.

I don't believe this is a module-specific question, but a more general question around how best to apply exemptions for policies when using Policy Initiatives?

Just to check, do you expect there to be many scenarios where this is a requirement or just a couple of Policy Definitions which will need exemptions? The reason I ask this is it may be best to create a Policy Assignment for the Policy Initiative with the Policy Definitions needing exemptions set to Disabled in the Policy Assignment (via parameters on the Policy Assignment), and then creating dedicated assignments for just those Policy Definitions.

If the number of scopes needing an exemption is low, you may also choose to create an exemption for those scopes, and then create a new Policy Assignment at each of those scopes with the Policy Definitions needed to be excluded set to Disabled as mentioned above.

If different exemptions are likely to be needed across a large number of the Policy Definitions or large numbers of resources, the more granular approach you mention may be an easier option from an operational perspective.

Ultimately Policy Initiatives are really intended to simplify the creation of Policy Assignments, but the cost is reduced flexibility.

Let me also have a chat internally and see whether we have any guidance regarding this.

jtracey93 commented 2 years ago

Also just to chip in here. It's key to remember the differences between the multiple options for this:

  1. Exclusion (aka Not Scopes)
  2. Exemptions (preview)

If you are looking to just exclude some resources, or a scope, from a policy assignment and compliance reporting in it's entirety then option 1 (above) "exclusion (aka not scopes)" would be my recommendation here. Which are supported in the caf-enterprise-scale module today by specifying not scopes on assignments. (I'm sure @krowlandson can advise best ways to do this in the module but I believe today you need to do it in the policy assignment JSON template file in the lib folder.

Just wanted to call this out as it can be confusing as the options are similar and names even more so 😁

johankardell commented 2 years ago

Hi, when working with clients who have larger environments I expect the number of exemptions to be somewhere around 100 to 200 for a larger policy initiative such as NIST/CIS/ISO27001, so there is a definite need to handle this in a structured manner. I'm surprised to find that Azurerm still doesn't support this at all. The scenarios that I'm looking at would require a significant amount or work to achieve what I want in the way that you describe it, so I'm sincerely hoping there's another way. Recreating NIST initiative in 10 different versions with different policies disabled feels like the wrong way to go in my opinion.

Anything you can share publicly or in private (email in profile) is valuable.

Also - thanks @jtracey93 for chiming in - the names are confusingly similar, but in this case I'm looking for a structured way of doing Exemptions (which is not only confusingly similar to Exclusion, but also hard to spell). Excluding a subscription or resource group from all of NIST because one storage account can't use firewall settings is... well - blunt ;)

krowlandson commented 2 years ago

Agreed @johankardell and thank you for providing the additional details.

It definitely sounds like exemptions are what you are looking for, and as you mention the azurerm provider is currently unable to help with this.

@jtracey93, @matt-FFFFFF and myself are discussing whether we can raise a PR to add this to the provider, but this may take some time.

We will also see if there are any other options we can offer to help.

johankardell commented 2 years ago

Thanks for the attention on this. I know there are other major organisations that wants this as well, but apparently noone has asked for it in this repo. Reach out if I can do anything from my end. Happy to have a private discussion around this if needed.

matt-FFFFFF commented 2 years ago

After research, the policy exemption support in the azurerm provider is ready to go but waiting on feature GA.

krowlandson commented 2 years ago

After research, the policy exemption support in the azurerm provider is ready to go but waiting on feature GA.

Is there anything we can do on our side to encourage it's inclusion in preview state?

johankardell commented 2 years ago

After research, the policy exemption support in the azurerm provider is ready to go but waiting on feature GA.

That's great news! Hopefully the functionality will be GA soon, or like Kevin said - maybe the code can be merged while still in Preview.

sean-keane25 commented 2 years ago

Can you provide a link to code changes in the azurerm ?

matt-FFFFFF commented 2 years ago

Can you provide a link to code changes in the azurerm ?

My apologies for the errant replies earlier.

Here is the thread about policy exemptions. It links to a now closed PR and the thread explains that they are awaiting feature GA.

https://github.com/hashicorp/terraform-provider-azurerm/issues/9197#issuecomment-823124130

bubbletroubles commented 2 years ago

This feature is now in GA - see confirmation via this commit from the MS product group

https://github.com/MicrosoftDocs/azure-docs/commit/c6c17a79013d57e11558abac4f804088f180c9bb

krowlandson commented 2 years ago

Just a quick update to say that the provider team are looking into adding this. No confirmation of dates yet but I will try to keep an eye on this and provide updates as available.

One possible option in the meantime is to consider using the new the Generic provider (AzAPI) which should be published via the Terraform Registry very soon, and would allow you to declare an exemption using something like the following:

resource "azapi_resource" "policy_exception" {
  type      = "Microsoft.Authorization/policyExemptions@2020-07-01-preview"
  name      = "testing"
  parent_id = azurerm_management_group.test.id

  body = jsonencode({
    properties = {
      exemptionCategory  = "Waiver"
      policyAssignmentId = "123434556"
    }

  })
}
johankardell commented 2 years ago

Thanks Kevin, looks like a decent workaround until Exemptions roll out in AzureRM v3. Looking forward for it to stabilize so we can start migrating to it. Any timeline on when caf-es module will be migrated? (I would not guess on anytime soon)

krowlandson commented 2 years ago

Any timeline on when caf-es module will be migrated?

Do you mean to the Generic provider (AzAPI)? If so, we won't be doing this as that's not the purpose of this provider, but we may start to use this to fill some gaps in the current Azure provider for features we would like to add to the module but have been unable to do so previously.

We will more likely publish these capabilities as dedicated modules so anyone can use them, and then cross-reference them from this one.

johankardell commented 2 years ago

Any timeline on when caf-es module will be migrated?

Do you mean to the Generic provider (AzAPI)?

Sorry for the confusion - I mean this module (terraform-azurerm-caf-enterprise-scale). Wondering if there is a timeline for migrating to AzureRM v3?

krowlandson commented 2 years ago

Oh of course...! Right now, v3.0.0 of the provider doesn't bring any tangible benefits to functionality of the module so we have no "strong" motivation to do this, however we have been discussing this and will probably do this as a new release once we have shipped the vwan capability in v1.2.0.

That said, I realised today that the azurerm_firewall_policy resource type (which I'm also adding) includes a breaking change in v3.0.0 of the provider so I'm considering whether to bite the bullet and roll these updates together. This is on an optional input though, which won't be directly configurable within our module so low priority.

I will discuss with the team today and let you know the outcome.

krowlandson commented 2 years ago

AzAPI provider is now live: https://registry.terraform.io/providers/azure/azapi/latest

krowlandson commented 2 years ago

And official MS docs here: https://docs.microsoft.com/azure/developer/terraform/overview-azapi-provider

johankardell commented 2 years ago

AzAPI provider is now live: https://registry.terraform.io/providers/azure/azapi/latest

Thank you, this looks like a good workaround until there's actual support in Azurerm.

krowlandson commented 2 years ago

AzAPI provider is now live: https://registry.terraform.io/providers/azure/azapi/latest

Thank you, this looks like a good workaround until there's actual support in Azurerm.

Hold that thought... https://github.com/hashicorp/terraform-provider-azurerm/pull/16293

johankardell commented 2 years ago

AzAPI provider is now live: https://registry.terraform.io/providers/azure/azapi/latest

Thank you, this looks like a good workaround until there's actual support in Azurerm.

Hold that thought... hashicorp/terraform-provider-azurerm#16293

Fantastic!

krowlandson commented 2 years ago

@johankardell, now that we have this incoming on the provider, is there a way you think we could integrate this into the module to simplify management of exemptions based on your work in this area?

ghost commented 2 years ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 7 days of this comment.

johankardell commented 2 years ago

@johankardell, now that we have this incoming on the provider, is there a way you think we could integrate this into the module to simplify management of exemptions based on your work in this area?

Looks like we've found a way to work with this. Stills feels like a workaround, but it's a lot better than clicking in the portal. Decided to put all exemptions in a separate repo - the only relation between the exemption and the assignment is a copy-pasted assignment ID. This works well - but if an assignment is removed the exemptions will break during apply. Same if an assignments changes ID. It's good enough for now though.

krowlandson commented 2 years ago

Hi @johankardell - definitely one to give some more thought to, and I'm confident we can find a solution.

Let's keep this issue open for now to flash out some ideas for how we could implement this.

rfk-nc commented 2 years ago

Hi @krowlandson and all,

Is it possible to get an update on support for Policy Exemptions within the ES-CAF module?

Similarly to Johan, we have to implement the CIS initiative, but waiver a couple of overly intrusive policies.

Can look at implementing the azurerm_managment_group_policy_exemption resource ourselves, but have concerns about keeping both the code base and the deployed policies in sync if we start doing that.

Many thanks! Richard

matt-FFFFFF commented 2 years ago

Hi @rfk-nc

This is on our backlog but we haven't assigned it anyone to work on yet.

It would be great to understand how you would like to see this working son the module.

The exemption resource has a number of properties https://docs.microsoft.com/en-us/azure/governance/policy/concepts/exemption-structure

It would be useful to know which of these you would like to see surfaced in the module and how it could be implemented in terms of module inputs.

jtracey93 commented 2 years ago

Trigger ADO Sync

krowlandson commented 2 years ago

Trigger ADO Sync

archmangler commented 1 year ago

Hi we're now seeing a lot of requests for this as enterprise customer adoption picks up for the module. I'd like to check on the progress of this feature?

krowlandson commented 1 year ago

@archmangler,thank you for your interest in this feature.

We don't currently have this committed but your voice will help us to prioritise this for consideration.

I think our main concern is around how we integrate this into the module without adding complexity which would be avoidable by managing exemptions independently. Having optional() types now gives us more flexibility but we've not had a chance to consider how to implement this yet.

Do you have any thoughts on how you would like to see this implemented to best help your customers?

ghost commented 1 year ago

@krowlandson any news when we can receive this feature? about implementation we have folders for policy sets, policy assignments and policy rules inside lib folder. Why not to add 1 more folder policyExemptions?

krowlandson commented 1 year ago

@Dushelov, in short, I'm afraid we don't have this in the pipeline yet.

matt-FFFFFF commented 1 year ago

AB#26868

MISO-mgriffin commented 1 year ago

This has recently come up as a need for my organization. It is interesting to see the AzureRM Terraform Provider has 4 resources. My current need is specific to exempting a subscription from a single Policy Initiative; however, I could see a use in the future for all of them; I do believe the least likely one I'd need is the resource policy exemption level.

I think a good Minimum implementation with the CAF-Enterprise-Scale module would be to integrate a new lib folder for policy exemptions; and then have it defined in the Archetype Definition. I was hoping Microsoft Learn would have some guidance for implementing this as code; however, https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-as-code has no mention of the exemptions.

steph409 commented 1 year ago

Hi all,

I ran into this feature request during my current enterprise deployment. I basically see two ways to implement this:

  1. within the lib folder, allow for files looking similar to this: Microsoft exemption structure json
  2. in the overwrite_archetype_config, add some policy_exemption optional parameter, which accepts per policy a list of resources, resourcegroups and subscriptions, then creates either one [terraform azurerm*_policy_exemption](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_policy_exemption) resource for each entry. Potential configuration:
    locals {
    archetype_config_overrides = {
    escorp = {
      permanent_policy_exemption = {
        Deploy-MDFC-Config     = [
          "/subscriptions/00000000-0000-0000-000000000000/", # to exempt a complete subscription
          "/subscriptions/00000000-0000-0000-000000000222/resourceGroups/resGroup1", # to exempt a resource group
          "/subscriptions/00000000-0000-0000-000000000111/virtualNetwork/vnetame", # to exempt a specific resource
        ]
        Deploy-VM-Monitoring   = [
          "/subscriptions/00000000-0000-0000-000000000222/resourceGroups/resGroup1", # to exempt a resource group
        ]
      }
      permanent_policy_initiative_exemption = {
        PolicyInitiativeName = {
          PolicyName = [          
            "/subscriptions/00000000-0000-0000-000000000000/", # to exempt a complete subscription
            "/subscriptions/00000000-0000-0000-000000000222/resourceGroups/resGroup1", # to exempt a resource group
            "/subscriptions/00000000-0000-0000-000000000111/virtualNetwork/vnetame", # to exempt a specific resource
            ]
        }
      }
    }
    }
    }

I would tend towards the second one. I would not implement temporary waiver, only permanent?

cheers, stephi

matt-FFFFFF commented 1 year ago

Hi all,

The exemption resource is deployed at the scope of the exemption, not the assignment.

We could implement something akin to @steph409's second suggestion using AzAPI. AzureRM has different resources for different scopes which makes things more complex example.

tcharewicz commented 1 year ago

Any update with this FR?

I do some test with exemptions and for me good enough is apply scopes to exempt in notScopes in template body.

{
  "name": "Deny-Resource-Locations",
  "type": "Microsoft.Authorization/policyAssignments",
  "apiVersion": "2019-09-01",
  "properties": {
    "description": "Specifies the allowed locations (regions) where Resources can be deployed.",
    "displayName": "Limit allowed locations for Resources",
    "notScopes": [
        <add here list of scopes to exempt>
    ],
    "parameters": {
      "listOfAllowedLocations": {
        "value": [
          "uksouth",
          "ukwest"
        ]
      }
    },
    "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c",
    "nonComplianceMessages": [
      {
        "message": "Resources {enforcementMode} only be deployed to the allowed locations."
      }
    ],
    "scope": "${current_scope_resource_id}",
    "enforcementMode": null
  },
  "location": "${default_location}",
  "identity": {
    "type": "None"
  }
}
pcsprashanth commented 1 year ago

Any update on this FR? Actually, my Org is looking for policy exemption on a specific resource. Is it possible with this module??

Regards, Chandra

c4milo commented 5 months ago

We are also looking into this. FWIW.

qaiserali commented 1 week ago

Any updates on this? We are also looking into this feature.

matt-FFFFFF commented 1 week ago

Hi we would welcome contributions on this! We haven't been able to get around to this feature yet unfortunately.

@steph409's second suggestions looks workable