From 839503b742cbdaf2c72fef585661d4d7781fbbf6 Mon Sep 17 00:00:00 2001 From: Sadik Tekin Date: Tue, 15 Aug 2023 14:52:10 +0100 Subject: [PATCH] 2.8.3 (#92) --- .github/workflows/cd.yml | 5 ++--- examples/assignments_org.tf | 11 +++++++---- modules/definition/README.md | 2 +- modules/definition/variables.tf | 10 +++++----- modules/initiative/README.md | 7 ++++++- modules/initiative/TEMPLATE.md | 7 ++++++- modules/initiative/variables.tf | 2 +- modules/set_assignment/variables.tf | 8 ++++---- 8 files changed, 32 insertions(+), 20 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 6ac4c9b..02d187b 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -42,6 +42,8 @@ jobs: creds: ${{ secrets.AZURE_CREDENTIALS }} enable-AzPSSession: true + # Used by GitHub Workflows to clean deployed resources quicker than tf destroy + # Quicker during CD as remediation tasks must be in a terminal provisioning state (Succeeded, Canceled, Failed) before they can be deleted. - name: Clean Resources with PowerShell id: destroy uses: azure/powershell@v1 @@ -49,9 +51,6 @@ jobs: with: azPSVersion: "latest" inlineScript: | - # Used by GitHub Workflows to clean deployed resources quicker than tf destroy - # Quicker during CD as remediation tasks must be in a terminal provisioning state (Succeeded, Canceled, Failed) before they can be deleted. - Get-AzPolicyAssignment -Scope "/providers/Microsoft.Management/managementgroups/team_a" | Remove-AzPolicyAssignment -Verbose Get-AzPolicyAssignment -Scope "/providers/Microsoft.Management/managementgroups/policy_dev" | Remove-AzPolicyAssignment -Verbose Get-AzPolicySetDefinition -ManagementGroupName "policy_dev" -Custom | Remove-AzPolicySetDefinition -Force -Verbose diff --git a/examples/assignments_org.tf b/examples/assignments_org.tf index 4b2846e..6174ad5 100644 --- a/examples/assignments_org.tf +++ b/examples/assignments_org.tf @@ -12,10 +12,13 @@ module "org_mg_whitelist_regions" { } assignment_metadata = { - version = "1.0.0" - category = "Batch" - propertyA = "A" - propertyB = "B" + version = "1.0.0" + category = "Batch" + cloud_envs = [ + "AzureCloud", + "AzureChinaCloud", + "AzureUSGovernment" + ] } # optional resource selectors (preview) diff --git a/modules/definition/README.md b/modules/definition/README.md index b30c027..49112bf 100644 --- a/modules/definition/README.md +++ b/modules/definition/README.md @@ -108,7 +108,7 @@ No modules. | [policy\_category](#input\_policy\_category) | The category of the policy, when using the module library this should correspond to the correct category folder under /policies/var.policy\_category | `string` | `null` | no | | [policy\_description](#input\_policy\_description) | Policy definition description | `string` | `""` | no | | [policy\_metadata](#input\_policy\_metadata) | The metadata for the policy definition. This is a JSON object representing additional metadata that should be stored with the policy definition. Omitting this will fallback to meta in the definition or merge var.policy\_category and var.policy\_version | `any` | `null` | no | -| [policy\_mode](#input\_policy\_mode) | The policy mode that allows you to specify which resource types will be evaluated, defaults to All. Possible values are All and Indexed | `string` | `null` | no | +| [policy\_mode](#input\_policy\_mode) | Specify which Resource Provider modes will be evaluated, defaults to All. Possible values are All, Indexed, Microsoft.Kubernetes.Data, Microsoft.KeyVault.Data or Microsoft.Network.Data | `string` | `null` | no | | [policy\_name](#input\_policy\_name) | Name to be used for this policy, when using the module library this should correspond to the correct category folder under /policies/policy\_category/policy\_name. Changing this forces a new resource to be created. | `string` | `""` | no | | [policy\_parameters](#input\_policy\_parameters) | Parameters for the policy definition. This field is a JSON object that allows you to parameterise your policy definition. Omitting this assumes the parameters are located in /policies/var.policy\_category/var.policy\_name.json | `any` | `null` | no | | [policy\_rule](#input\_policy\_rule) | The policy rule for the policy definition. This is a JSON object representing the rule that contains an if and a then block. Omitting this assumes the rules are located in /policies/var.policy\_category/var.policy\_name.json | `any` | `null` | no | diff --git a/modules/definition/variables.tf b/modules/definition/variables.tf index ac605e9..b612e55 100644 --- a/modules/definition/variables.tf +++ b/modules/definition/variables.tf @@ -39,12 +39,12 @@ variable "policy_description" { variable "policy_mode" { type = string - description = "The policy mode that allows you to specify which resource types will be evaluated, defaults to All. Possible values are All and Indexed" + description = "Specify which Resource Provider modes will be evaluated, defaults to All. Possible values are All, Indexed, Microsoft.Kubernetes.Data, Microsoft.KeyVault.Data or Microsoft.Network.Data" default = null validation { - condition = var.policy_mode == null || var.policy_mode == "All" || var.policy_mode == "Indexed" || var.policy_mode == "Microsoft.Kubernetes.Data" - error_message = "Policy mode possible values are: All, Indexed or Microsoft.Kubernetes.Data (In Preview). Other modes are only allowed in built-in policy definitions, these include Microsoft.ContainerService.Data, Microsoft.CustomerLockbox.Data, Microsoft.DataCatalog.Data, Microsoft.KeyVault.Data, Microsoft.MachineLearningServices.Data, Microsoft.Network.Data and Microsoft.Synapse.Data" + condition = var.policy_mode == null || var.policy_mode == "All" || var.policy_mode == "Indexed" || var.policy_mode == "Microsoft.Kubernetes.Data" || var.policy_mode == "Microsoft.KeyVault.Data" || var.policy_mode == "Microsoft.Network.Data" + error_message = "Policy mode possible values are: All, Indexed, Microsoft.Kubernetes.Data, Microsoft.KeyVault.Data or Microsoft.Network.Data. Unless explicitly stated, Resource Provider modes only support built-in policy definitions, and exemptions are not supported at the component-level." } } @@ -105,8 +105,8 @@ locals { policy_name = coalesce(var.policy_name, try((local.policy_object).name, null)) display_name = coalesce(var.display_name, try((local.policy_object).properties.displayName, local.title)) description = coalesce(var.policy_description, try((local.policy_object).properties.description, local.title)) - metadata = coalesce(var.policy_metadata, try((local.policy_object).properties.metadata, merge({ category = local.category }, { version = local.version }))) - parameters = coalesce(var.policy_parameters, try((local.policy_object).properties.parameters, null)) + metadata = coalesce(null, var.policy_metadata, try((local.policy_object).properties.metadata, merge({ category = local.category }, { version = local.version }))) + parameters = coalesce(null, var.policy_parameters, try((local.policy_object).properties.parameters, {})) policy_rule = coalesce(var.policy_rule, try((local.policy_object).properties.policyRule, null)) # manually generate the definition Id to prevent "Invalid for_each argument" on set_assignment plan/apply diff --git a/modules/initiative/README.md b/modules/initiative/README.md index 285cc55..04b9550 100644 --- a/modules/initiative/README.md +++ b/modules/initiative/README.md @@ -4,7 +4,7 @@ Dynamically creates a policy set based on multiple custom or built-in policy def > ⚠️ **Warning:** To simplify assignments, if any `member_definitions` contain the same parameter names they will be [merged](https://www.terraform.io/language/functions/merge) unless you specify `merge_effects = false` or `merge_parameters = false` as described in the second example below. -> 💡 **Note:** Multiple entries of the same `member_definitions` are not currently supported, if you require the same definition to be present more than once you may use this module to create the initiative json which you can then edit to add unique parameter and definition references. +> 💡 **Note:** Multiple entries of the same `member_definitions` are not currently supported, if you require the same definition to be present more than once you may use this module to create the initiative json which you can then edit to add unique parameter and definition references. Some examples can be found in discussion [#67](https://github.com/gettek/terraform-azurerm-policy-as-code/discussions/67) ## Examples @@ -56,6 +56,11 @@ module configure_asc_initiative { data.azurerm_policy_definition.deploy_law_on_linux_vms, ] } + +# get all the generated parameter names so we know what to use during assignment +output "list_of_initiative_parameters" { + value = keys(module.configure_asc_initiative.parameters) +} ``` ### Populate member_definitions with a for loop (not explicit) diff --git a/modules/initiative/TEMPLATE.md b/modules/initiative/TEMPLATE.md index 0ab10be..130006d 100644 --- a/modules/initiative/TEMPLATE.md +++ b/modules/initiative/TEMPLATE.md @@ -4,7 +4,7 @@ Dynamically creates a policy set based on multiple custom or built-in policy def > ⚠️ **Warning:** To simplify assignments, if any `member_definitions` contain the same parameter names they will be [merged](https://www.terraform.io/language/functions/merge) unless you specify `merge_effects = false` or `merge_parameters = false` as described in the second example below. -> 💡 **Note:** Multiple entries of the same `member_definitions` are not currently supported, if you require the same definition to be present more than once you may use this module to create the initiative json which you can then edit to add unique parameter and definition references. +> 💡 **Note:** Multiple entries of the same `member_definitions` are not currently supported, if you require the same definition to be present more than once you may use this module to create the initiative json which you can then edit to add unique parameter and definition references. Some examples can be found in discussion [#67](https://github.com/gettek/terraform-azurerm-policy-as-code/discussions/67) ## Examples @@ -56,6 +56,11 @@ module configure_asc_initiative { data.azurerm_policy_definition.deploy_law_on_linux_vms, ] } + +# get all the generated parameter names so we know what to use during assignment +output "list_of_initiative_parameters" { + value = keys(module.configure_asc_initiative.parameters) +} ``` ### Populate member_definitions with a for loop (not explicit) diff --git a/modules/initiative/variables.tf b/modules/initiative/variables.tf index 048e082..d85581e 100644 --- a/modules/initiative/variables.tf +++ b/modules/initiative/variables.tf @@ -107,7 +107,7 @@ locals { # combine all discovered role definition IDs all_role_definition_ids = try(distinct([for v in flatten(values(local.role_definition_ids)) : lower(v)]), []) - metadata = coalesce(var.initiative_metadata, merge({ category = var.initiative_category }, { version = var.initiative_version })) + metadata = coalesce(null, var.initiative_metadata, merge({ category = var.initiative_category }, { version = var.initiative_version })) # manually generate the initiative Id to prevent "Invalid for_each argument" on potential consumer modules initiative_id = var.management_group_id != null ? "${var.management_group_id}/providers/Microsoft.Authorization/policySetDefinitions/${var.initiative_name}" : azurerm_policy_set_definition.set.id diff --git a/modules/set_assignment/variables.tf b/modules/set_assignment/variables.tf index acb44dc..85893a3 100644 --- a/modules/set_assignment/variables.tf +++ b/modules/set_assignment/variables.tf @@ -149,10 +149,10 @@ variable "skip_role_assignment" { locals { # assignment_name at MG scope will be trimmed if exceeds 24 characters assignment_name_trim = local.assignment_scope.mg > 0 ? 24 : 64 - assignment_name = try(lower(substr(coalesce(var.assignment_name, var.initiative.name), 0, local.assignment_name_trim)), "") - display_name = try(coalesce(var.assignment_display_name, var.initiative.display_name), "") - description = try(coalesce(var.assignment_description, var.initiative.description), "") - metadata = jsonencode(try(coalesce(var.assignment_metadata, jsondecode(var.initiative.metadata)), {})) + assignment_name = try(lower(substr(coalesce(var.assignment_name, var.initiative.name), 0, local.assignment_name_trim)), "") + display_name = try(coalesce(var.assignment_display_name, var.initiative.display_name), "") + description = try(coalesce(var.assignment_description, var.initiative.description), "") + metadata = jsonencode(try(coalesce(var.assignment_metadata, jsondecode(var.initiative.metadata)), {})) # convert assignment parameters to the required assignment structure parameter_values = var.assignment_parameters != null ? {