Creating custom Initiatives from CIS 1.3.0 Initiatives via data source dynamically

What i am trying to achieve:
• Create custom policy initiative from existing built-in CIS 1.3.0 policies.
How:
• Fetch all the CIS policies which are part of CIS 1.3.0 initiatives via data source and create custom initiatives via terraform.

Problem statement:
• We want to have below structure in terraform as a prerequisite for Policy Initiative creation, we are finding it challenging to create the same structure in terraform.

Expected output:

[{
each_init_parameters = "Custom  initiative CIS_Azure_1.3.0_9"
detail = [
{
def_id = []
ref_id = []
group_name = []
param_value = []
}
]
},
{
each_init_parameters = "Custom  initiative CIS_Azure_1.3.0_10"
detail = [
{
def_id = ""
ref_id = ""
group_name = ""
param_value = ""
}
]
}]

Current output:


           + each_init_parameters           = "Custom initiative CIS_Azure_1.3.0_9"
          + each_init_policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/496ddjkdkjdkjdc3"
          + each_init_policy_group_names   = [
              + "CIS_Azure_1.3.0_9.8",
            ]
          + each_init_reference_id         = "49622dddkjsjh65-4ecd-878a-bae78737e9ed"
        },
      + {
          + each_init_parameter_values     = jsonencode(
                {
                  + effect = {
                      + value = "[parameters('effect-4ddhjhjdhjdh5e53-4a4f-a7f4')]"
                    }
                }
            )
          + each_init_parameters           = "Custom  initiative CIS_Azure_1.3.0_9"
          + each_init_policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/4dsjnjshjhsj"
          + each_init_policy_group_names   = [
              + "CIS_Azure_1.3.0_9.10",
            ]
          + each_init_reference_id         = "4d24b6hsjhhjhsjhsj"
        },
      + {
          + each_init_parameter_values     = jsonencode(
                {
                  + effect = {
                      + value = "[parameters('effect-5bb22jkhsjhjkhsjhjsjkh')]"
                    }
                }
            )

Code i am trying:

locals {

  custom_initiative_names = distinct(

    flatten([

      for each_group_name in data.azurerm_policy_set_definition.policysetdefinition.policy_definition_group : [

        "${var.custom_initiatives_prefix} ${regex("[^()@[:space:]]+[_][0-9]*",each_group_name.name)}"

      ]

    ])

  )

Above block return output as below which will be used to group the policy def id, paramters and policy refernce id.

custom_initiative_names           = [
"Custom  initiative CIS_Azure_1.3.0_1",
"Custom  initiative CIS_Azure_1.3.0_2",
Custom  initiative CIS_Azure_1.3.0_3",
"Custom  initiative CIS_Azure_1.3.0_4",
"Custom  initiative CIS_Azure_1.3.0_5",
"Custom  initiative CIS_Azure_1.3.0_6",
"Custom  initiative CIS_Azure_1.3.0_7",
"Custom  initiative CIS_Azure_1.3.0_8",
"Custom  initiative CIS_Azure_1.3.0_9",

Below block filters only the parameters which are present in both the data source to avoid duplication.


  complete_policy_def = flatten([

    for k,v in jsondecode(data.azurerm_policy_set_definition.policysetdefinition.parameters) : [

        for each_policy_def_ref in data.azurerm_policy_set_definition.policysetdefinition.policy_definition_reference : {

          policy_parameter_key = k

          policy_parameter_value = v

          "${k}" = v

          policy_def_ref = each_policy_def_ref

        } if (k == "effect-${each_policy_def_ref.reference_id}")

    ]

  ])

With below block we want to fetch all the details and group based on custom_intiative_names mentioned above. Then assign all the fetched details and create policy initiative dynamically based on custom_initiative_names.

 new_init_group = flatten([

    for each_init in local.custom_initiative_names : [

      for each_pol_defi in local.complete_policy_def : {

        each_init_parameters = each_init

        each_init_policy_definition_id = each_pol_defi.policy_def_ref.policy_definition_id

        each_init_reference_id = each_pol_defi.policy_def_ref.reference_id

        each_init_policy_group_names = each_pol_defi.policy_def_ref.policy_group_names

        each_init_parameter_values = each_pol_defi.policy_def_ref.parameter_values

       

      }

       

      if (length(regexall("${regex("[^()@[:space:]]+[_][0-9]*",each_pol_defi.policy_def_ref.policy_group_names[0])}", each_init)) > 0)

     

    ]

  ])

}

Could some one advice how to structure the whole data bases on custom_intiative_names via locals or any other means.

@apparentlymart Could you please help here.