gettek / terraform-azurerm-policy-as-code

Terraform modules that simplify the workflow of custom and built-in Azure Policies

Home Page:https://learn.microsoft.com/en-us/azure/governance/policy/concepts/policy-as-code

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add functionality listed in #TODO in the Initiative module

NikolaiKleppe opened this issue · comments

Issue Template

Prerequisites

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Context

Hi, in the initiative module there's a todo list for parameter_value.metadata.displayName should also contain definition reference if merge_effects == false

https://github.com/gettek/terraform-azurerm-policy-as-code/blob/main/modules/initiative/variables.tf#L94

This is a functionality I have a need for at the moment, otherwise duplicate parameters have identical names in the Azure portal:
image

When editing parameters in the initiative assignment it looks like this:
image

So I need the reference ID (or in my case, DisplayName) to be added to the parameter metadata:
image

I've tried to implement a solution myself in the locals parameters block, but haven't figured it out yet.

Is this on the roadmap to add, if it's not too complicated to implement?

Thanks :) Really good module otherwise, by the way

Hi @NikolaiKleppe, I've also been struggling with this one for some time.

In the meantime you can output the policy_definition_reference.parameter_values to get the list of respective parameters that you can specify at assignment. Hope this helps

Hi, thanks :)

I've done that as well and it works fine - It's more because of my use case, where I'm looking to configure individual parameters in the Portal instead of through Terraform (probably sounds counter intuitive, but makes more sense for my specific use case)

I'll try some more to fix it in the meantime

Maybe a step closer, but doesn't quite work
Just added another locals block to test, an additional for loop, notice the in parameter_value.metadata

  parameter_display_name = merge(values({
    for definition, params in local.member_parameters :
    definition => {
      for parameter_name, parameter_value in params :
        parameter_name => {
          for metadata_name, metadata_value in parameter_value.metadata :
            var.merge_parameters == false ? format("%s_%s", replace(substr(title(replace(definition, "/-|_|\\s/", " ")), 0, 120), "/\\s/", ""), metadata_name) :
            metadata_name => metadata_value
    }}})...)

One problem is that it changes the value on the wrong side of the equal sign

image

For my case it should be the following on the right side of the equal sign: KubernetesClusterPodsAndContainersShouldOnlyRunWithApprovedUserAndGroupIDs_SupplementalGroupRule

Definition:
image

If you change in parameter_value.metadata to in parameter_value.metadata.displayName it fails on the for expression

And even if this did work you'd have to merge it with the parameters block too

Posting in case it gives you any additional ideas, I'm just kinda brute-forcing through tests

@gettek I have a solution for it now - The logic will replace only the displayName inside the metadata block.
See the "New" section

I think it works even if merge_parameters == true, but you can take a look at it if you want. There might be other scenarios I'm not aware of that can cause issues

  # combine all discovered definition parameters using interpolation
  parameters = merge(values({
    for definition, params in local.member_parameters :
    definition => {
      for parameter_name, parameter_value in params :
      # if do not merge effects -> suffix only effects with definition references
      parameter_name == "effect" && var.merge_effects == false ? format("%s_%s", replace(substr(title(replace(definition, "/-|_|\\s/", " ")), 0, 120), "/\\s/", ""), parameter_name) :
      # if do not merge parameters -> suffix all parameters with definition references
      var.merge_parameters == false ? format("%s_%s", replace(substr(title(replace(definition, "/-|_|\\s/", " ")), 0, 120), "/\\s/", ""), parameter_name) :

      # New:
      parameter_name => {
        for key_1, value_1 in parameter_value :
            key_1 => (key_1 == "metadata" ? merge(value_1, { displayName = format("%s_%s", replace(substr(title(replace(definition, "/-|_|\\s/", " ")), 0, 120), "/\\s/", ""), parameter_name) }) : value_1 )
      }
    }
  })...)

I'm using name instead of ID for my policies at the moment, so it looks a bit messy with the long variable names, but still:

image

Definition:
image

Assignment:
image

Edit assignment parameters:

image

Nice! Thanks @NikolaiKleppe, we can run further tests until the next release and please feel free to submit a pull request

This issue is stale because it has been open for 30 days with no activity.