GithubHelp home page GithubHelp logo

gettek / terraform-azurerm-policy-as-code Goto Github PK

View Code? Open in Web Editor NEW
140.0 8.0 63.0 595 KB

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

License: MIT License

HCL 75.80% PowerShell 24.20%
builtin-policies azurerm-policy azure remediation-tasks custom-policy azure-policy terraform-azurerm-policy terraform-module guest-configuration dsc

terraform-azurerm-policy-as-code's People

Contributors

gettek avatar pmatthews05 avatar thecomalley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-azurerm-policy-as-code's Issues

azurerm_subscription_policy_remediation issue

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

  • Module Version:
  • master branch
  • Terraform Version:
  • terraform version
    Terraform v1.3.1
  • AzureRM Provider Version:
    version = ">=3.23.0"
 on ../modules/def_assignment/main.tf line 139, in resource "azurerm_subscription_policy_remediation" "rem"

139 resource azurerm_subscription_policy_remediation rem {
140   count                   = local.create_remediation + local.remediate.sub > 1 ? 1 : 0
141   name                    = lower("${var.definition.name}-${formatdate("DD-MM-YYYY-hh:mm:ss", timestamp())}")
142   subscription_id         = local.remediation_scope
143   policy_assignment_id    = local.assignment.id
144   resource_discovery_mode = var.resource_discovery_mode
145   location_filters        = var.location_filters
146   failure_percentage      = var.failure_percentage
147   parallel_deployments    = var.parallel_deployments
148   resource_count          = var.resource_count
149 }

Expected Behavior

try to perform a testing for example

Current Behavior

make example works for testing

Possible Solution

Failure Information (for bugs)

Steps to Reproduce

  1. git clone https://github.com/gettek/
  2. cd terraform-azurerm-policy-as-code/example
  3. terraform init
  4. terraform plan -out=./myplan
  5. terraform apply "./myplan"

Failure Logs

module.org_mg_configure_az_monitor_and_security_vm_initiative.azurerm_management_group_policy_remediation.rem["ASC_AMA_DefaultPipeline_Deploy"]: Creation complete after 4s [id=/providers/Microsoft.Management/managementGroups/policy_dev/providers/Microsoft.PolicyInsights/remediations/asc_ama_defaultpipeline_deploy-20-10-2022-01:32:03]

│ Error: creating/updating /subscriptions/7996451c-728c-4b55-87f3-dfa8aeac980e/providers/Microsoft.PolicyInsights/remediations/inherit_resource_group_tags_modify-20-10-2022-01:32:00: remediations.RemediationsClient#RemediationsCreateOrUpdateAtSubscription: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidCreateRemediationRequest" Message="The policy assignment specified in remediation 'inherit_resource_group_tags_modify-20-10-2022-01:32:00' is out of scope. Policy assignments should be specified only at or above the remediation scope."

│ with module.team_a_mg_inherit_resource_group_tags_modify.azurerm_subscription_policy_remediation.rem[0],
│ on ../modules/def_assignment/main.tf line 139, in resource "azurerm_subscription_policy_remediation" "rem":
│ 139: resource azurerm_subscription_policy_remediation rem {

set_assignment - every apply trigger azurerm_role_assignment.rem_role delete/create

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

  • Module Version: 2.8.3
  • Terraform Version: [v1.6.3]
module "configure_policy_data_assigment_to_sub" {
  for_each = toset(var.policy_data.assignment.scope_sub_ids)

  source                      = "gettek/policy-as-code/azurerm//modules/set_assignment"
  version                     = "2.8.3"
  initiative                  = module.configure_policy_data_initiative
  assignment_scope            = data.azurerm_subscription.initiative_assign_to_sub[each.key].id
  assignment_location         = var.policy_data.assignment.location
  assignment_enforcement_mode = true
  skip_role_assignment        = false
  skip_remediation            = false
  assignment_parameters       = local.parameter_list_for_assignment
}

I guess this is the code which causes the issue. This in from submodule of the initiative.

  # get role definition IDs
  role_definition_ids = {
    for d in var.member_definitions :
    d.name => try(jsondecode(d.policy_rule).then.details.roleDefinitionIds, [])
  }

  # combine all discovered role definition IDs
  all_role_definition_ids = try(distinct([for v in flatten(values(local.role_definition_ids)) : lower(v)]), [])

Expected Behavior

I expecte that the Azure initiative will be assigned to the given subscription. The assignment works fine as I can tell.

Current Behavior

I discovered, that each time I run a terraform plan/apply it will recreate the azurerm_role_assignment.rem_role.
image

Terraform detects a difference in the role_definition_id. Looks like some informations are missing in the

"/subscriptions/aae7c2ce-523b-4715-b8ec-c4848196c981/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"

Would it be possible to generate the correct ids?

"/providers/microsoft.authorization/roledefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"

I also have tried to do this: https://registry.terraform.io/modules/gettek/policy-as-code/azurerm/2.2.0#error-invalid-for_each-argument

Not sure if this is a new issue of can be solved by myself.

Thank you for taking a look into this one.

Role Definitions are not assigned to System Managed Identities

Role Definitions are not assigned to System Managed Identities

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

  • Module Version: 2.7.0
  • Terraform Version: 1.3.7
  • AzureRM Provider Version: 3.37.0

Expected Behavior

Policy Assignment has a Managed Identity and Permissions assigned.

Current Behavior

Policy Assignment has a Managed Identity that does not have any permissions.
image

Possible Root Cause

role_definition_ids = var.skip_role_assignment == false && local.identity_type == { type = "SystemAssigned" } ? try(coalescelist(var.role_definition_ids, lookup(jsondecode(var.definition.policy_rule).then.details, "roleDefinitionIds", [])), []) : []

local.identity_type == { type = "SystemAssigned" } is always evaluates to false and therefore local.role_definition_ids is always an empty list.

Possibly related: hashicorp/terraform#27643

Possible Solution

role_definition_ids = var.skip_role_assignment == false && local.identity_type.type == "SystemAssigned" ? try(coalescelist(var.role_definition_ids, lookup(jsondecode(var.definition.policy_rule).then.details, "roleDefinitionIds", [])), []) : []

Steps to Reproduce

Create any policy assignment with definition that contains roleDefinitionIds.

Option to use user-assigned managed identity

Hello

Would it be possible to add the ability to pass in the ID of a user-assigned managed identity for policy remediation, instead of only using the system-managed identity?

We have some use cases where we may split some policy assignments across hub & spoke components of a landing zone - but the result would create two different MSI's that may not have the cross-subscription permissions.

An example - automatic vNet peering. The MSI must have permission on both the hub & spoke subscriptions. In this case it would be easier to pass a user-assigned identity so we can manually assign the permissions across subscriptions.

Specifying a role assignment scope doesn't allow the deployment to be created if it is elsewhere

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

  • Module Version: today!
  • Terraform Version: 1.5.0
  • AzureRM Provider Version: latest
# add code here

Expected Behavior

Private DNS zone 'privatelink.blob.core.windows.net' for private endpoint dns. Private DNS zone is in a separate subscription to storage account and private endpoint. Managed System Identity being used to create / delete DNS records in that zone so the 'Private DNS Zone Contributor' role is being used.
The role_assignment_scope has to be set to the private DNS zone itself (or above) so that it has the 'action' to create / delete records.

The def_assignment module performs all this perfectly but the deployment fails

This is a DINE policy

Current Behavior

As above but Azure attempts to create the actual deployment in the policy scoped location and doesn't have permissions because the role_assignment_scope is set to the private DNS Zone in another subscription.

Possible Solution

role_assignment_scope could be a list ???

Failure Information (for bugs)

Steps to Reproduce

  1. Create a private DNS zone in another subscription / resource group
  2. Scope the policy to the DNS zone itself using Private DNS Zone Contributor (which does have deployment/* permissions)
  3. Wait :-)

Failure Logs

Feature Request: Create an initiative where the policy parameters are not transformed into initiative parameters

Thanks very much for the module.

When creating an initiative with policies that have parameters, it appears that all policy parameters are transformed into initiative parameters, and then we need to fill out these parameters in assignments. Is it possible to define the policy parameters directly on the initiative without transforming them into initiative parameters?

image

I'm referring to the "Set Value" option in the Policy Parameters tab when creating an initiative.

Consider using lifecycle for Policy Set Definition updates

Issue

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

When updating Policy Set Definitions I often have problems like:

│ Error: updating Policy Set Definition "corp_monitoring": policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidPolicySetParameterUpdate" Message="The existing policy has '68' parameter(s) which is greater than the count of parameter(s) '3' in the policy being added. Policy parameters cannot be removed during policy update."

│ Error: updating Policy Set Definition "corp_monitoring": policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidPolicySetParameterUpdate" Message="The existing policy set parameter(s) 'logsEnabled' type is being updated which is not allowed."

Error: updating Policy Set Definition "corp_monitoring_diagnostic_settings": policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidPolicySetParameterUpdate" Message="The policy contains new parameter(s) 'rgName,storagePrefix' which are not present in the existing policy and have no default value. New parameters may be added to a policy only if they have a default value."

Expected Behavior

If update of the Policy Set Definition is not possible, it should be replaced.

Current Behavior

Errors mentioned above.

Possible Solution

Consider adding replace_triggered_by lifecycle meta-argument to module:
https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle?optInFrom=terraform-io#replace_triggered_by

The only hesitation I have is that maybe this should be solved on azurerm provider level.

Set Assignment - Display Name and Description Variables are ignored

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

The assignment_display_name and assignment_description parameters are ignored and always default to " "

  • Module Version: 2.7.2
  • Terraform Version: 1.4.2
  • AzureRM Provider Version: 3.49.0
data "azurerm_role_definition" "log_analytics_contributor" {
  name = "Log Analytics Contributor"
}

data "azurerm_role_definition" "monitoring_contributor" {
  name = "Monitoring Contributor"
}

module "diagnostics_assignment" {
  source     = "gettek/policy-as-code/azurerm//modules/set_assignment"
  initiative = module.diagnostics_initiative

  assignment_scope        = "/subscriptions/GUID"
  assignment_effect       = "DeployIfNotExists"
  assignment_display_name = "DIAGNOSTICS - Deploy Diagnostic Settings to Azure Services"
  assignment_description  = "This policy set deploys the configurations of application Azure resources to forward diagnostic logs and metrics to an Azure Log Analytics workspace. See the list of policies of the services that are included"
  assignment_parameters = {
    "logAnalytics" = "/subscriptions/GUID/resourceGroups/RG-NAME/providers/Microsoft.OperationalInsights/workspaces/ala01"
  }

  role_definition_ids = [
    "/subscriptions/GUID${data.azurerm_role_definition.log_analytics_contributor.role_definition_id}",
    "/subscriptions/GUID${data.azurerm_role_definition.monitoring_contributor.role_definition_id}"
  ]

  depends_on = [
    module.diagnostics_initiative
  ]
}

Expected Behavior

These values should be honoured

Current Behavior

Defaults to ""

Failure Information (for bugs)

the coelsce logic in https://github.com/gettek/terraform-azurerm-policy-as-code/blob/2.7.2/modules/set_assignment/variables.tf doesnt seem to work, always defaults to "".

image

image

Defining initiative

I Am really confuse while defining initiative for given below

{
"type": "Microsoft.Authorization/policySetDefinitions",
"name": "Azure-Tags",
"properties": {
"displayName": "Append and Inherit Tags from Resource Group",
"description": "Append and Inherit Tags from Resource Group",
"metadata": {
"category": "Tags"
},
"parameters": {
"Add-mandatory-tags-on-Resource-Groups_tagName": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "serviceprovider"
},
"Add-mandatory-tags-on-Resource-Groups_tagValue": {
"type": "string",
"metadata": {
"displayName": "Tag Value (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "tbd"
},
"Add-mandatory-tags-on-Resource-Groups_tagName1": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "environment"
},
"Add-mandatory-tags-on-Resource-Groups_tagValue1": {
"type": "string",
"metadata": {
"displayName": "Tag Value (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "tbd"
},
"Add-mandatory-tags-on-Resource-Groups_tagName2": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "project number"
},
"Add-mandatory-tags-on-Resource-Groups_tagValue2": {
"type": "string",
"metadata": {
"displayName": "Tag Value (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "tbd"
},
"Add-mandatory-tags-on-Resource-Groups_tagName3": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "guid"
},
"Add-mandatory-tags-on-Resource-Groups_tagValue3": {
"type": "string",
"metadata": {
"displayName": "Tag Value (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "tbd"
},
"Append-Patching-tag-with-default-value-for-VMs_tagName": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Append Patching tag with default value for VMs)"
},
"defaultValue": "patching"
},
"Append-Patching-tag-with-default-value-for-VMs_tagValue": {
"type": "string",
"metadata": {
"displayName": "Tag Value (Policy: Append Patching tag with default value for VMs)"
},
"defaultValue": "default"
},
"Inherit-tags-from-the-resource-group_tagName": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "serviceprovider"
},
"Inherit-tags-from-the-resource-group_tagName1": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "environment"
},
"Inherit-tags-from-the-resource-group_tagName2": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "project number"
},
"Inherit-tags-from-the-resource-group_tagName3": {
"type": "string",
"metadata": {
"displayName": "Tag Name (Policy: Add mandatory tags on Resource Groups)"
},
"defaultValue": "guid"
}
},
"policyDefinitions": [
{
"policyDefinitionId": "{policyLocationResourceId1}/providers/Microsoft.Authorization/policyDefinitions/Add-mandatory-tags-on-Resource-Groups",
"parameters": {
"tagName": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagName')]"
},
"tagValue": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagValue')]"
},
"tagName1": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagName1')]"
},
"tagValue1": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagValue1')]"
},
"tagName2": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagName2')]"
},
"tagValue2": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagValue2')]"
},
"tagName3": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagName3')]"
},
"tagValue3": {
"value": "[parameters('Add-mandatory-tags-on-Resource-Groups_tagValue3')]"
}
},
"groupNames": []
},
{
"policyDefinitionId": "{policyLocationResourceId1}/providers/Microsoft.Authorization/policyDefinitions/Append-Patching-tag-with-default-value-for-VMs",
"parameters": {
"tagName": {
"value": "[parameters('Append-Patching-tag-with-default-value-for-VMs_tagName')]"
},
"tagValue": {
"value": "[parameters('Append-Patching-tag-with-default-value-for-VMs_tagValue')]"
}
},
"groupNames": []
},
{
"policyDefinitionId": "{policyLocationResourceId1}/providers/Microsoft.Authorization/policyDefinitions/Inherit-tags-from-the-resource-group",
"parameters": {
"tagName": {
"value": "[parameters('Inherit-tags-from-the-resource-group_tagName')]"
},
"tagName1": {
"value": "[parameters('Inherit-tags-from-the-resource-group_tagName1')]"
},
"tagName2": {
"value": "[parameters('Inherit-tags-from-the-resource-group_tagName2')]"
},
"tagName3": {
"value": "[parameters('Inherit-tags-from-the-resource-group_tagName3')]"
}
},
"groupNames": []
}
],
"policyDefinitionGroups": []
}
}

definition mode not read from the custom policy object?

Hi @gettek

Is there any reason why the definitions mode value is not being read from the custom policy object as other parameters such as name, display name ?

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)) policy_rule = coalesce(var.policy_rule, try((local.policy_object).properties.policyRule, null))

Thanks a lot !

Terraform apply not working with different policy_mode

{
    "type": "Microsoft.Authorization/policyDefinitions",
    "name": "Key-Vault-secrets-should-have-expiration-date",
    "properties": {
      "displayName": "Key Vault secrets should have an expiration date",
      "policyType": "Custom",
      "mode": "Microsoft.KeyVault.Data",
      "description": "Secrets should have a defined expiration date and not be permanent. Secrets that are valid forever provide a potential attacker with more time to compromise them. It is a recommended security practice to set expiration dates on secrets.",
      "metadata": {
        "version": "1.0.2",
        "category": "Key Vault"
      },
      "parameters": {
        "effect": {
          "type": "String",
          "metadata": {
            "displayName": "Effect",
            "description": "'Audit' allows a non-compliant resource to be created, but flags it as non-compliant. 'Deny' blocks the resource creation. 'Disable' turns off the policy."
          },
          "allowedValues": [
            "Audit",
            "Deny",
            "Disabled"
          ],
          "defaultValue": "Audit"
        }
      },
      "policyRule": {
        "if": {
          "allOf": [
            {
              "field": "type",
              "equals": "Microsoft.KeyVault.Data/vaults/secrets"
            },
            {
              "field": "Microsoft.KeyVault.Data/vaults/secrets/attributes.expiresOn",
              "exists": false
            }
          ]
        },
        "then": {
          "effect": "[parameters('effect')]"
        }
      }
    }
  }

This is the policy with different mode.Plan is successful. But during apply getting below error
Error: creating/updating Policy Definition "Key-Vault-secrets-should-have-expiration-date": policy.DefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidProviderNameInPolicyAlias" Message="The policy definition 'Key-Vault-secrets-should-have-expiration-date' rule is invalid. The provider 'Microsoft.KeyVault.Data' referenced by the 'field' property 'Microsoft.KeyVault.Data/vaults/secrets/attributes.expiresOn' of the policy rule doesn't exist."

│ with module.Key-Vault["Key-Vault-secrets-should-have-expiration-date"].azurerm_policy_definition.def,
│ on ....\modules\definition\main.tf line 1, in resource "azurerm_policy_definition" "def":
│ 1: resource azurerm_policy_definition def {



│ Error: creating/updating Policy Definition "Key-Vault-keys-should-have-expiration-date": policy.DefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidProviderNameInPolicyAlias" Message="The policy definition 'Key-Vault-keys-should-have-expiration-date' rule is invalid. The provider 'Microsoft.KeyVault.Data' referenced by the 'field' property 'Microsoft.KeyVault.Data/vaults/keys/attributes.expiresOn' of the policy rule doesn't exist."

│ with module.Key-Vault["Key-Vault-keys-should-have-expiration-date"].azurerm_policy_definition.def,
│ on ....\modules\definition\main.tf line 1, in resource "azurerm_policy_definition" "def":
│ 1: resource azurerm_policy_definition def {

Not able to resolve

Support for custom policies not defined in policies directory

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

  • Module Version: 2.5.1
  • Terraform Version: 1.2.2
  • AzureRM Provider Version: 3.2.0

Expected Behavior

Ability to create custom policies that are not declared in policies directory.

Current Behavior

Custom policies requires a file with definition to be present in policies directory:

  policy_object = jsondecode(file("${path.module}/../../policies/${title(var.policy_category)}/${var.policy_name}.json"))

This limits options of available custom policies.

Possible Solution

  1. Add a variable defining path to a file containing custom policy definition. Therefore I could reference custom policies outside of module.
  2. Or add a special dummy policy that can be used as a template. Then just replace all parameters using variables: policy_metadata, policy_rule, policy_parameters, policy_name.

Failure Information (for bugs)

Steps to Reproduce

  1. Create custom policy that is not defined in policies directory
  2. Run terraform plan

Failure Logs

Support metadata argument for policy assignments

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

  • Module Version: 2.60
  • Terraform Version: 1.2.3
  • AzureRM Provider Version: 3.10.0

Expected Behavior

The def_assignment should be able to set the 'metadata' field on a policy assignment

Current Behavior

There is no variable for metadata, so it doesn't get set.

Some context: In our situation, we are planning on adding logic to policy rules to cover waiver scenarios instead of using exemptions (e.g. for stuff where the entire estate will be affected, like allowing direct routes to Azure control plane destinations). In these cases, we would like to track the waiver metadata in the policy assignment since we won't be using exemptions. Putting the metadata in the policy definition is also an option, but assignment should support it as well.

Add policy to existing Initiative error with parameters

Hello

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

Thank you for this module. Not sure if I have discovered an issue. Maybe you can have a look at this as well.

My problem is the following:

If I run the below code, the initiative is created successfully and everything is good.

When I change the order and first deploy the first two policies and then the third in another run, I run into an error:

Error: updating Policy Set Definition "Initiative-ManagementGroup-Root-intg": policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidPolicySetParameterUpdate" Message="The policy contains new parameter(s) 'logAnalytics_B79fa14e238a4c2dB376442ce508fc84' which are not present in the existing policy and have no default value. New parameters may be added to a policy only if they have a default value."
with module.configure_cpm_mgmt_root_initiative.azurerm_policy_set_definition.set
on .terraform/modules/configure_cpm_mgmt_root_initiative/modules/initiative/main.tf line 1, in resource "azurerm_policy_set_definition" "set":
resource "azurerm_policy_set_definition" "set" {

locals {
  initiative_management_group_root = {
    "Configure Azure Defender for DNS to be enabled" = {
      type : "BuiltIn"
    },
    "Configure Azure Defender for Key Vaults to be enabled" = {
      type : "BuiltIn"
    },
    "Deploy - Configure diagnostic settings for SQL Databases to Log Analytics workspace" = {
      type : "BuiltIn"
    },
    }
}

data "azurerm_policy_definition_built_in" "cpm_mgmt_root_policies_built_in" {
  for_each     = { for k, v in local.initiative_management_group_root : k => v if v.type == "BuiltIn" }
  display_name = each.key
}

module "configure_cpm_mgmt_root_initiative" {
  source                  = "gettek/policy-as-code/azurerm//modules/initiative"
  version                 = "2.8.3"
  initiative_name         = "Initiative-ManagementGroup-Root-${var.environment_shortcut}"
  initiative_display_name = "[CPM]: Initiative-ManagementGroup-Root-${var.environment_shortcut}"
  initiative_description  = "Deploys and configures Azure Security Center settings and defines exports"
  initiative_category     = "CPM"
  management_group_id     = data.azurerm_management_group.cmp_management_test.id
  merge_effects           = false
  merge_parameters        = false

  member_definitions = concat([for builtin_policy in data.azurerm_policy_definition_built_in.cpm_mgmt_root_policies_built_in : builtin_policy], [for custom_policy in module.configure_cpm_mgmt_root_policies : custom_policy.definition])
}

It would be nice if you can help. For us, it is important to add/remove policies from Initiatives.

Kind Regards

supply object properties at runtime broken

Issue Template

supply object properties at runtime broken

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

  • Module Version: 2.8.0
  • Terraform Version: v1.4.6
  • AzureRM Provider Version: v3.56.0

Example from readme modules/definition/README.md "You will also be able to supply object properties at runtime such as:"

provider "azurerm" {
  features {}
}

data "azurerm_management_group" "org" {
  name = "00000000-0000-0000-0000-000000000000"
}

locals {
  policy_file = jsondecode(file("onboard_to_automation_dsc_linux.json"))
}

module "parameterised_test" {
  source              = "gettek/policy-as-code/azurerm//modules/definition"
  policy_name         = "Custom Name"
  display_name        = "Custom Display Name"
  policy_description  = "Custom Description"
  policy_category     = "Custom Category"
  policy_version      = "Custom Version"
  management_group_id = data.azurerm_management_group.org.id

  policy_rule       = (local.policy_file).properties.policyRule
  policy_parameters = (local.policy_file).properties.parameters
  policy_metadata   = (local.policy_file).properties.metadata
}

Expected Behavior

Current Behavior

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: Error in function call
│ 
│   on .terraform/modules/parameterised_test/modules/definition/variables.tf line 89, in locals:
│   89:   policy_object = jsondecode(coalesce(try(
│   90:     file(var.file_path),
│   91:     file("${path.cwd}/policies/${title(var.policy_category)}/${var.policy_name}.json"),
│   92:     file("${path.root}/policies/${title(var.policy_category)}/${var.policy_name}.json"),
│   93:     file("${path.root}/../policies/${title(var.policy_category)}/${var.policy_name}.json"),
│   94:     file("${path.module}/../../policies/${title(var.policy_category)}/${var.policy_name}.json")
│   95:   )))

Possible Solution

Failure Information (for bugs)

Steps to Reproduce

Failure Logs

Role Assignment behavior with User Assigned Managed Identity

Hi @gettek ,

I would like to know if the behavior below is intended with regards to the variable skip_role_assignment.
When we specify identity_ids (User Assigned Managed Identity), Role Assignments are never made.

identity_type = length(try(coalescelist(var.role_definition_ids, lookup(jsondecode(var.definition.policy_rule).then.details, "roleDefinitionIds", [])), [])) > 0 ? length(var.identity_ids) > 0 ? { type = "UserAssigned" } : { type = "SystemAssigned" } : {}
# try to use policy definition roles if explicit roles are ommitted
role_definition_ids = var.skip_role_assignment == false && try(values(local.identity_type)[0], "") == "SystemAssigned" ? try(coalescelist(var.role_definition_ids, lookup(jsondecode(var.definition.policy_rule).then.details, "roleDefinitionIds", [])), []) : []

In this piece of code, local.role_definition_ids is always [] as local.identity_type == UserAssigned.

Should the Role Assignments be independent of Identity Type used?

Multiple identical Policy Definitions in Initiative

Hello,

I am pursuing a scenario where a custom initiative can have the same policy definition added multiple times. This gives unique policyDefinitionReferenceId (reference) which later allows assignment of multiple parameters.

For example, below is an initiative which uses 2 built-in policy definitions to require a tag on resource group:

{
  "properties": {
    "displayName": "Test Initiative",
    "policyType": "Custom",
    "metadata": {
      "category": "Tags",
      "version": "1.0.0"
    },
    "parameters": {
      "tag_1": {
        "type": "string",
        "metadata": {
          "displayName": "Tag 1"
        }
      },
      "tag_2": {
        "type": "string",
        "metadata": {
          "displayName": "Tag 2"
        }
      }
    },
    "policyDefinitions": [
      {
        "policyDefinitionReferenceId": "Require a tag on resource groups_1",
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/96670d01-0a4d-4649-9c89-2d3abc0a5025",
        "parameters": {
          "tagName": {
            "value": "[parameters('tag_1')]"
          }
        },
        "groupNames": []
      },
      {
        "policyDefinitionReferenceId": "Require a tag on resource groups_2",
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/96670d01-0a4d-4649-9c89-2d3abc0a5025",
        "parameters": {
          "tagName": {
            "value": "[parameters('tag_2')]"
          }
        },
        "groupNames": []
      }
    ],
    "policyDefinitionGroups": []
  },
  "type": "Microsoft.Authorization/policySetDefinitions",
  "name": "0077d380911646ceb173ba21"
}

At the first glance, according to the documentation we can only pass a list of policy definitions and nothing else.

Can you suggest if this scenario is supported?

Thank you.

Location argument isn't being set when creating a policy assignment

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

  • Module Version: 2.8.1
  • Terraform Version: 1.4.6
  • AzureRM Provider Version: 3.60.0
module "service_bus_policy_test" {
  source            = "gettek/policy-as-code/azurerm//modules/def_assignment"
  version           = "2.8.1"
  definition        = data.azurerm_policy_definition.example
  assignment_scope  = data.azurerm_management_group.example.id
  assignment_name   = data.azurerm_policy_definition.example.name
  assignment_effect = "Deny"
  assignment_location = local.assignment_location
}

locals {
   assignment_location = "uksouth"
}

Expected Behavior

The Location of the policy assignment should be set to uksouth.

Current Behavior

The location argument isn't set when I run a plan/apply. I tried creating the assignment without the assignment_location input originally to use "uksouth" set in the module but this fails to set the location when a plan is run. This behaviour also exists in version 2.8.0. When I revert back to 2.7.2 the location is set correctly. I've tried using previous AzureRM versions but get the same results as above.

Thanks in advance,
C.

Getting error for Private link DNS

{
  "type": "Microsoft.Authorization/policyDefinitions",
  "name": "PrivateLinkAzureServiceBusArecordtoprivateDNSZone",
  "properties": {
    "displayName": "Private Link Azure IoT Hubdev servicebus A-record to private DNS Zone",
    "policyType": "Custom",
    "mode": "Indexed",
    "description": "DeployIfNotExists policy to automatically create the required DNS record in the central private DNS zone.\nhttps://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale#configuration-required-by-platform-team",
    "metadata": {
      "category": "Private Link"
    },
    "parameters": {
      "effect": {
        "type": "String",
        "defaultValue": "DeployIfNotExists",
        "allowedValues": [
          "DeployIfNotExists",
          "Disabled"
        ],
        "metadata": {
          "displayName": "Effect",
          "description": "Enable or disable the execution of the policy"
        }
      },
      "PrivateLinkAzureServiceBusArecordtoprivateDNSZone_privateDnsZoneId": {
        "type": "String",
        "metadata": {
          "displayName": "privateDnsZoneId",
          "description": null,
          "strongType": "Microsoft.Network/privateDnsZones"
        }
      }
    },
    "policyRule": {
      "if": {
        "allOf": [
          {
            "field": "type",
            "equals": "Microsoft.Network/privateEndpoints"
          },
          {
            "count": {
              "field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].groupIds[*]",
              "where": {
                "field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].groupIds[*]",
                "equals": "iotHub"
              }
            },
            "greaterOrEquals": 1
          }
        ]
      },
      "then": {
        "effect": "[parameters('effect')]",
        "details": {
          "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
          "existenceCondition": {
            "count": {
              "field": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups.privateDnsZoneConfigs[*]",
              "where": {
                "field": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups.privateDnsZoneConfigs[*].privateDnsZoneId",
                "equals": "[parameters('PrivateLinkAzureServiceBusArecordtoprivateDNSZone_privateDnsZoneId')]"
              }
            },
            "greater": 0
          },
          "roleDefinitionIds": [
            "/providers/Microsoft.Authorization/roleDefinitions/befefa01-2a29-4197-83a8-272ff33ce314",
            "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
          ],
          "deployment": {
            "properties": {
              "mode": "incremental",
              "template": {
                "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {
                  "PrivateLinkAzureServiceBusArecordtoprivateDNSZone_privateDnsZoneId": {
                    "type": "string"
                  },
                  "privateEndpointName": {
                    "type": "string"
                  },
                  "location": {
                    "type": "string"
                  }
                },
                "resources": [
                  {
                    "name": "[concat(parameters('privateEndpointName'), '/deployedByPolicy1')]",
                    "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
                    "apiVersion": "2020-03-01",
                    "location": "[parameters('location')]",
                    "properties": {
                      "privateDnsZoneConfigs": [
                        {
                          "name": "iotHub-privateDnsZone",
                          "properties": {
                            "privateDnsZoneId": "[parameters('PrivateLinkAzureServiceBusArecordtoprivateDNSZone_privateDnsZoneId')]"
                          }
                        }
                      ]
                    }
                  }
                ]
              },
              "parameters": {
                "PrivateLinkAzureServiceBusArecordtoprivateDNSZone_privateDnsZoneId": {
                  "value": "[parameters('PrivateLinkAzureServiceBusArecordtoprivateDNSZone_privateDnsZoneId')]"
                },
                "privateEndpointName": {
                  "value": "[field('name')]"
                },
                "location": {
                  "value": "[field('location')]"
                }
              }
            }
          }
        }
      }
    }
  }
}

For above policy i am getting error as below

 Error: updating Policy Set Definition "Private-link_initiative": policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidPolicySetParameterUpdate" Message="The policy contains new parameter(s) 'PrivateLinkAzureServiceBusArecordtoprivateDNSZone_privateDnsZoneId' which are not present in the existing policy and have no default value. New parameters may be added to a policy only if they have a default value."
│ 
│   with module.Private-link_initiative.azurerm_policy_set_definition.set,
│   on ..\..\modules\initiative\main.tf line 1, in resource "azurerm_policy_set_definition" "set":
│    1: resource azurerm_policy_set_definition set {

No idea why for 2-3 private link policies giving same error.
For others it is working finr in initiative

Support discovery of policy file in local file path

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

  • Module Version: 2.6.0
  • Terraform Version: 1.2.3
  • AzureRM Provider Version: 3.10.0
# add code here

Expected Behavior

The definition module should be able to find the policy file using the category and policy name if you are using the modules from the registry and have your own policy definition files.

Also, if the consuming repo has a policy definition of the same name as one in this repo, it will use the the one in this repo.

Current Behavior

You need to provide a file path if your policy definition files aren't part of the module in the remote registry

Possible Solution

Add another argument to this coalesce function to check the root module path on the local disk using the same logic (policies/category/policy_name.json). Would suggest it first checks in the local repo for the existence of the policy file, then the file path argument, and finally this module.

This way we don't have to provide a file path for local policy definitions and can take advantage of the file discovery logic included in this module.

'managed identity' Issue with initiatives

Issue Template

data "azurerm_policy_set_definition" "vm_monitoring" {
  display_name = "Legacy - Enable Azure Monitor for VMs"
}

module "org_mg_vm_monitoring" {
  source           = "../../azure-tfmodule/azure-policy-tfmodule/modules/set_assignment"
  initiative       = data.azurerm_policy_set_definition.vm_monitoring
  assignment_scope = data.azurerm_management_group.org.id
  re_evaluate_compliance  = false
  skip_remediation        = false
  skip_role_assignment    = false
  assignment_parameters = {
    logAnalytics_1 = "/subscriptions/${var.resources.logs.law_subscription_id}/resourceGroups/${var.resources.logs.resource_group_name}/providers/Microsoft.OperationalInsights/workspaces/${var.resources.logs.log_analytics_workspace}",
  }
}

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

  • Module Version:
  • Terraform Version:
  • AzureRM Provider Version:
# add code here

Expected Behavior

Current Behavior

Possible Solution

Failure Information (for bugs)

│ Error: creating Scoped Policy Assignment (Scope: "/providers/Microsoft.Management/managementGroups/968a4da8-609a-4c94-bf6e-35a85b64f927"
│ Policy Assignment Name: "55f3eceb-5573-4f18-9695-"): policyassignments.PolicyAssignmentsClient#Create: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="ResourceIdentityRequired" Message="The policy assignment '55f3eceb-5573-4f18-9695-' request is invalid. Policy assignments must include a 'managed identity' when assigning 'DeployIfNotExists' policy definitions. Please see https://aka.ms/azurepolicyremediation for usage information."
│
│   with module.org_mg_vm_monitoring.azurerm_management_group_policy_assignment.set[0],
│   on ..\..\azure-tfmodule\azure-policy-tfmodule\modules\set_assignment\main.tf line 1, in resource "azurerm_management_group_policy_assignment" "set":
│    1: resource "azurerm_management_group_policy_assignment" "set" {
│
│ creating Scoped Policy Assignment (Scope: "/providers/Microsoft.Management/managementGroups/968a4da8-609a-4c94-bf6e-35a85b64f927"
│ Policy Assignment Name: "55f3eceb-5573-4f18-9695-"): policyassignments.PolicyAssignmentsClient#Create: Failure responding to
│ request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="ResourceIdentityRequired"
│ Message="The policy assignment '55f3eceb-5573-4f18-9695-' request is invalid. Policy assignments must include a 'managed identity'
│ when assigning 'DeployIfNotExists' policy definitions. Please see https://aka.ms/azurepolicyremediation for usage information."

Steps to Reproduce

Failure Logs

Support policy-specific non-compliance messages in initiative assignments

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

  • Module Version: 2.60
  • Terraform Version: 1.2.1
  • AzureRM Provider Version: 3.10.0

Expected Behavior

When assigning a policy initiative with the set_assignment module, you should be able to include a policy reference ID with each non-compliance message so the message only applies to a specific policy:

.

This is the default Terraform functionality: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_group_policy_assignment#non_compliance_message

Current Behavior

The non-compliance message applies to every policy in the initiative

Policy initiative set effect per policy definition

Hello,

I'm unable to figure out how could I set the effects for each single policy definition inside a policy set when assigning that policy set to a scope. Right now, it looks that I can set one for the entire policy set.

This is what I'm looking for

Example Built-In Policy Initiative Assignment fails

Issue Template

I'm getting the below issue when running the example: Built-In Policy Initiative Assignment

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

  • Module Version: 2.6.1
  • Terraform Version: v1.2.9
  • AzureRM Provider Version: v3.21.1
data "azurerm_policy_set_definition" "cis_1_3_0" {
  display_name = "CIS Microsoft Azure Foundations Benchmark v1.3.0"
}

module org_mg_cis_1_3_0_benchmark {
  source           = "gettek/policy-as-code/azurerm//modules/set_assignment"
  initiative       = data.azurerm_policy_set_definition.cis_1_3_0
  assignment_scope = var.management_group_ids.core

  assignment_parameters = {
    "effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftSql-servers-firewallRules-delete" = "Disabled"
  }
}

Expected Behavior

Successful terraform plan

Current Behavior

Possible Solution

Failure Information (for bugs)

│ Error: Error in function call

│   on .terraform/modules/org_mg_cis_1_3_0_benchmark/modules/set_assignment/variables.tf line 144, in locals:
│  144:   role_definition_ids = var.skip_role_assignment == false ? coalescelist(var.role_definition_ids, try(var.initiative.role_definition_ids, [])) : []
│     ├────────────────
│     │ var.initiative is object with 12 attributes
│     │ var.role_definition_ids is empty list of string

│ Call to function "coalescelist" failed: no non-null arguments.

Steps to Reproduce

Failure Logs

Add functionality listed in #TODO in the Initiative module

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

Additional policy metadata not saved

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

  • Module Version: 2.6.0
  • Terraform Version: 1.2.3
  • AzureRM Provider Version: 3.10.0
    "metadata": {
      "version": "1.0.0",
      "category": "Batch",
      "propertyA": "A",
      "propertyB": "B
    },

Expected Behavior

Anything included in the 'metadata' object should be saved to the policy definition

Current Behavior

Any additional metadata besides 'version' and 'category' won't be saved in the policy definition. In the above snippet, 'propertyA' and 'propertyB' won't be saved.

Possible Solution

I think the problem lies here:

metadata = coalesce(var.policy_metadata, merge({ category = local.category },{ version = local.version }), try((local.policy_object).properties.metadata))

local.category and local.version will always be populated due to the logic on lines 91 and 92. Since they will be populated, the coalesce function on line 100 will always return the 2nd argument, which is the merge of category and version. The 3rd argument (the metadata in the policy file itself) will never get used. This is assuming you don't provide a var.policy_metadata variable.

Also, I tried putting all the metadata into the var.policy_metadata variable instead, but then got an error about not all objects being the same type in the coalesce function, I guess because category and version are strings and policy_metadata is an object.

Failure Information (for bugs)

Steps to Reproduce

  1. Write a policy definition with additional metadata
  2. Deploy it using the 'definitions' module
  3. observe that only 'category' and 'version' fields of the metadata are present in the policy definition when viewed in the Azure portal.

Policy Definition Module Does Not Allow for Null Attributes in JSON Policy Code

Issue Template

Prerequisites

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

Context

  • Module Version: 2.8.2
    Terraform v1.4.6
    on darwin_amd64
  • provider registry.terraform.io/hashicorp/azuread v2.41.0
  • provider registry.terraform.io/hashicorp/azurerm v3.67.0
  • provider registry.terraform.io/hashicorp/local v2.4.0
{
    "description": "Customer-managed key based encryption should be configured for Databricks's managed services.",
    "displayName": "Audit - Databricks should use customer-managed key for encrypting managed services",
    "properties": {
        "metadata": {
            "category": "Azure Databricks",
            "version": "1.0.0"
        },
        "mode": "All",
        "policyRule": {
            "if": {
                "allOf": [
                    {
                        "equals": "Microsoft.Databricks/workspaces",
                        "field": "type"
                    },
                    {
                        "exists": false,
                        "field": "Microsoft.Databricks/workspaces/encryption.entities.managedServices.keySource"
                    }
                ]
            },
            "then": {
                "effect": "Audit"
            }
        }
    }
}
locals {
  # import the custom policy object from a library or specified file path
  policy_object = jsondecode(coalesce(try(
    file(var.file_path),
    file("${path.cwd}/Policiy Definitions/${title(var.policy_category)}/${var.policy_name}.json"),
    file("${path.root}/Policy Definitions/Custom Policies/${title(var.policy_category)}/${var.policy_name}.json"),
    file("${path.root}/../Policy Definitions/Custom Policies/${title(var.policy_category)}/${var.policy_name}.json"),
    file("${path.module}/../../Policy Definitions/Custom Policies/${title(var.policy_category)}/${var.policy_name}.json"),
    "{}" # return empty object if no policy is found
  )))

  # fallbacks
  title    = title(replace(local.policy_name, "/-|_|\\s/", " "))
  category = coalesce(var.policy_category, try((local.policy_object).properties.metadata.category, "General"))
  version  = coalesce(var.policy_version, try((local.policy_object).properties.metadata.version, "1.0.0"))
  mode     = coalesce(var.policy_mode, try((local.policy_object).properties.mode, "All"))

  # use local library attributes if runtime inputs are omitted
  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))
  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
  definition_id = var.management_group_id != null ? "${var.management_group_id}/providers/Microsoft.Authorization/policyDefinitions/${local.policy_name}" : azurerm_policy_definition.def.id
}

Expected Behavior

Module should be able to handle null values for certain fields in policy JSON
Ex: not all policies have a parameters attribute, the module should not break if this is missing.

Current Behavior

policy definition module variables.tf currently does not have a way to properly handle null values (coalesce errors out on null)
if you introduce a try block that results in null around the parameters locals value try(coalesce(var.policy_parameters, try((local.policy_object).properties.parameters, null)), null) , it results in a further error that APPEARS to attempt to allow null values, but is not functioning as expected

│ Error: Invalid function argument

│ on Modules/Policy/main.tf line 11, in resource "azurerm_policy_definition" "def":
│ 11: parameters = length(local.parameters) > 0 ? jsonencode(local.parameters) : null
│ ├────────────────
│ │ while calling length(value)
│ │ local.parameters is null

│ Invalid value for "value" parameter: argument must not be null.

Possible Solution

introduce the necessary null value handlers throughout the code to allow for null values, especially in the parameters field.

Failure Information (for bugs)

Steps to Reproduce

  1. use policy definition module call on various policies with undefined attributes
  2. terraform apply

Failure Logs

│ Error: Error in function call

│ on Modules/Policy/variables.tf line 109, in locals:
│ 109: parameters = coalesce(var.policy_parameters, try((local.policy_object).properties.parameters, null))
│ ├────────────────
│ │ while calling coalesce(vals...)
│ │ local.policy_object is object with 3 attributes
│ │ var.policy_parameters is null

│ Call to function "coalesce" failed: no non-null, non-empty-string arguments.

│ Error: Invalid function argument

│ on Modules/Policy/main.tf line 11, in resource "azurerm_policy_definition" "def":
│ 11: parameters = length(local.parameters) > 0 ? jsonencode(local.parameters) : null
│ ├────────────────
│ │ while calling length(value)
│ │ local.parameters is null

│ Invalid value for "value" parameter: argument must not be null.

Custom policy definition metadata with different data types

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

When custom policy definition metadata contain different data types, module failes on coealesce function.

  • Module Version: 2.8.2
  • Terraform Version:
  • AzureRM Provider Version:
# add code here
  policy_metadata = {
    version  = "1.0.0"
    category = "Network"
    owner    = "Security"
    alzCloudEnvironments = [
      "AzureCloud",
      "AzureChinaCloud",
      "AzureUSGovernment"
    ]
  }

Expected Behavior

Definition module should handle metadata with different data types correctly.

Current Behavior

Failing on error
Call to function "coalesce" failed: all arguments must have the same type.

Possible Solution

Use try() function instead coelesce() on https://github.com/gettek/terraform-azurerm-policy-as-code/blob/main/modules/definition/variables.tf#L108

Failure Information (for bugs)

Steps to Reproduce

Failure Logs

Policy assignment does not create systemassigned identity

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

  • Module Version: 2.8.3
  • Terraform Version: v1.7.0
  • AzureRM Provider Version: v3.88.0
module "audit_default_windows_settings" {
  source              = "./modules/definition"
  policy_name         = "default_DeployIfNotExists"
  display_name        = "Default Windows settings"
  policy_category     = "Desired State Configuration"
  management_group_id = data.azurerm_management_group.root_mg.id
}

module "default_windows_settings-assign" {
  definition             = module.audit_default_windows_settings
  assignment_description = "test"
  assignment_scope       = data.azurerm_subscription.test.id
  skip_remediation       = false
  skip_role_assignment   = false
  role_definition_ids    = [data.azurerm_role_definition.guest_configuration_contributor.id]
  assignment_parameters = {
    IncludeArcMachines = "true"
  }

}```

## Expected Behavior
Policy should create a system assigned identity with the assignment and create remediation tasks

## Current Behavior
Errors saying that it does not have an assigned identity.


## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->

## Failure Information (for bugs)

│ Policy Assignment Name: "default_deployifnotexists"): unexpected
│ status 400 with error: ResourceIdentityRequired: The policy assignment
│ 'default_deployifnotexists' request is invalid. Policy assignments
│ must include a 'managed identity' when assigning 'DeployIfNotExists' policy
│ definitions. Please see https://aka.ms/azurepolicyremediation for usage
│ information.

If I try to output module.audit_default_windows_settings.policy_rule

 output "test2" {
 value = module.audit_default_windows_settings.policy_rule
}
It tells me that policy_rule doesn't exist.

Initiative module adds 'effect' parameter

Issue Template

When using the initiative module with a policy without 'effect' parameter (like "Enable Microsoft Defender for Cloud on your subscription") an error appears.

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

  • Module Version:
  • Terraform Version: 1.2.9
  • AzureRM Provider Version: 3.23.0

Expected Behavior

No 'effect' parameter is added, no error.

Current Behavior

terraform apply fails with the above message

Possible Solution

Handling parameters in a different way

Failure Logs

│ Error: creating Policy Set Definition "corp_initiative": policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="UndefinedPolicyParameter" Message="The policy set definition 'corp_initiative' is attempting to assign the parameter(s) 'effect' which are not defined in the policy definition 'ac076320-ddcf-4066-b451-6154267e8ad2'."

Suppose i have one initiative in which Deny,Audit and AuditifNotexists effects are there for policies.How to pass in assignment_effect in assignment.org??

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

  • Module Version:
  • Terraform Version:
  • AzureRM Provider Version:

Expected Behavior

Current Behavior

Possible Solution

Failure Information (for bugs)

Steps to Reproduce

Failure Logs

Invalid value for "str" parameter: string required.

Reporting issue whereby I recieve error "Invalid value for "str" parameter: string required." whenever trying to create a initiative with built-in policies included.

Data sources

data "azurerm_policy_definition" "azure_defender_sql_opensource" {
display_name = "Configure Azure Defender for open-source relational databases to be enabled"
}
data "azurerm_policy_definition" "azure_defender_servers" {
display_name = "Configure Azure Defender for servers to be enabled"
}
data "azurerm_policy_definition" "azure_defender_sql_vms" {
display_name = "Configure Azure Defender for SQL servers on machines to be enabled"
}
data "azurerm_policy_definition" "azure_defender_app_service" {
display_name = "Configure Azure Defender for App Service to be enabled"
}
data "azurerm_policy_definition" "azure_defender_storage" {
display_name = "Configure Azure Defender for Storage to be enabled"
}
data "azurerm_policy_definition" "azure_defender_aks" {
display_name = "[Preview]: Configure Azure Kubernetes Service clusters to enable Defender profile"
}
data "azurerm_policy_definition" "azure_defender_key_vault" {
display_name = "Configure Azure Defender for Key Vaults to be enabled"
}
data "azurerm_policy_definition" "azure_defender_dns" {
display_name = "Configure Azure Defender for DNS to be enabled"
}
data "azurerm_policy_definition" "azure_defender_resource_manager" {
display_name = "Configure Azure Defender for Resource Manager to be enabled"
}
data "azurerm_policy_definition" "azure_defender_sql_paas" {
display_name = "Configure Azure Defender for Azure SQL database to be enabled"
}
data "azurerm_policy_definition" "azure_defender_la_export" {
display_name = "Deploy export to Log Analytics workspace for Azure Security Center data"
}

Initiative creation

module "configure_asc_initiative" {
source = "../modules/initiative"
initiative_name = "configure_asc_initiative"
initiative_display_name = "Deploy Azure Security Center configuration"
initiative_description = "Deploys and configures Azure Security Center settings and defines exports"
initiative_category = "Security Center"
management_group_name = data.azurerm_management_group.root.name

member_definitions = [
data.azurerm_policy_definition.azure_defender_sql_opensource,
data.azurerm_policy_definition.azure_defender_servers,
data.azurerm_policy_definition.azure_defender_sql_vms,
data.azurerm_policy_definition.azure_defender_app_service,
data.azurerm_policy_definition.azure_defender_storage,
data.azurerm_policy_definition.azure_defender_aks,
data.azurerm_policy_definition.azure_defender_key_vault,
data.azurerm_policy_definition.azure_defender_dns,
data.azurerm_policy_definition.azure_defender_resource_manager,
data.azurerm_policy_definition.azure_defender_sql_paas,
data.azurerm_policy_definition.azure_defender_la_export,
module.policy_definition_es_deploy_asc_securitycontacts,
]
}

Error
Error: Invalid function argument

│ on ..\modules\initiative\main.tf line 16, in resource "azurerm_policy_set_definition" "set":
│ 16: parameters = jsondecode(d.parameters)
│ ├────────────────
│ │ d.parameters is object with 2 attributes

│ Invalid value for "str" parameter: string required.

remediation task not working as expected

Used this code in assignmemt.org

module "org_mg_Network-Watcher_initiative" {
source = "..//modules/set_assignment"
initiative = module.Network-Watcher_initiative.initiative
assignment_scope = data.azurerm_management_group.org.id
assignment_effect = "DeployIfNotExists"
skip_remediation = false
skip_role_assignment = false
role_definition_ids = module.Network-Watcher_initiative.role_definition_ids
assignment_parameters = {
effect1 = "AuditIfNotExists"
listOfLocations = [
"WestEurope",
"NorthEurope",
"EastUS"
]
}
}

Policy is getting assigned properly but remediation not as expected.
Capture

Remediation Tasks naming

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

I have a question about timestamp in name for remeditation tasks.
In what cases they would not be created? I can't understand it.
Now on every apply all remeditation tasks are always recreated.

TODO: Error: Invalid for_each argument

For next release

You may experience plan/apply issues when running an initial deployment of the set_assignment module. This is because azurerm_role_assignment.rem_role and azurerm_*_policy_remediation.rem depend on resources to exist before producing a successful continuos deployment. To overcome this, set skip_remediation=true and omit for consecutive builds. This may also be required for destroy tasks.

Getting stuck in remidiation

In assignments_org

module "org_mg_Network-Watcher_initiative" {
  source               = "..//modules/set_assignment"
  initiative           = module.Network-Watcher_initiative.initiative
  assignment_scope     = data.azurerm_management_group.org.id
  assignment_effect    = "DeployIfNotExists"
  skip_remediation     = true
  skip_role_assignment = false
  role_definition_ids = [
    data.azurerm_role_definition.Network_Contributor.id
  ]
  assignment_parameters = {
    effect1 = "AuditIfNotExists"
    listOfLocations = [
      "WestEurope",
      "NorthEurope",
      "EastUS"
    ]
  }
}

....................................................
In initiative.tf

module "Network-Watcher_initiative" {
  source                  = "..//modules/initiative"
  initiative_name         = "Network-Watcher_initiative"
  initiative_display_name = "[Network Watcher]: Network-Watcher"
  initiative_description  = "This initiative is used for Network Watcher should be enabled ."
  initiative_category     = "Network-Watcher"
  management_group        = data.azurerm_management_group.org.id
  member_definitions = [
    module.Network-Watcher["Network-Watcher-should-be-enabled"].definition,
    module.Network-Watcher["Deploy-network-watcher-when-VNET-are-created"].definition,
  ]
}

While running terraform plan getting below error

 Error: Invalid for_each argument
│
│   on ..\modules\set_assignment\main.tf line 122, in resource "azurerm_management_group_policy_remediation" "rem":
│  122:   for_each                = { for dr in local.definition_reference.mg : basename(dr.reference_id) => dr }
│     ├────────────────
│     │ local.definition_reference.mg will be known only after apply
│
│ The "for_each" value depends on resource attributes that cannot be determined until apply, 
│ so Terraform cannot predict how many instances will be created. To work around this, use   
│ the -target argument to first apply only the resources that the for_each depends on.  

Support 'merge = false' for all parameters not just effects

@gettek I was looking at #20 again, and I initially thought that the functionality for the 'effect' parameter was implemented for all parameters. However it isn't. Is that something you'd consider doing?

Here's my use-case - I want to implement all the built-in policies that create the DNS zone group for private endpoints in a single initiative (e.g. 'Configure Key Vault to use private DNS zone', 'Configure a private DNS Zone ID for blob groupID'), etc. These all take 'effect' and 'privateDnsZoneId' as parameters. Your module will create policy-specific parameters for 'effect' but not 'privateDnsZoneId', as that needs to be different for each policy.

I could use the native TF resource for initiative definition, but it's far more verbose that your module would be (i.e. loads of JSON for the policy definitions and parameters). With your module, it would just look like this:

module "customer_mg_configure_dns_private_endpoints" {
  source                  = "gettek/policy-as-code/azurerm//modules/initiative"
  version                 = "2.6.1"
  initiative_name         = "pe_dns"
  initiative_display_name = "[Platform]: Configure DNS for Private Endpoints"
  initiative_description  = "Automatically creates A records in private DNS zones for private endpoints"
  initiative_category     = "Network"
  merge_effects           = false # will not merge any parameters
  management_group_id     = data.azurerm_management_group.env.id

  member_definitions = [
    data.azurerm_policy_definition.storage_accounts_configure_dns_blob,
    data.azurerm_policy_definition.storage_accounts_configure_dns_queue,
   ... # etc.
  ]
}

New azure_rm hashicorp latest version issue

resource "azurerm_resource_policy_remediation" "example" {
name = "remediation1"
resource_id = azurerm_virtual_network.example.id
policy_assignment_id = azurerm_resource_group_policy_assignment.test.id
}

hashicorp azure_rm(latest) has replaced azurerm_policy_remediation to above azurerm_resource_policy_remediation which requires resource_id as mandatory parameter .
Can you please suggest what should be the value used here?

Role Definition Ids are not visible in assignments

Hi

We are are trying to assign role definition during assignment but we are not able to achieve required result.
We tried in both ways
#role_definition_ids = module.PrivateLinkAzureAutomationArecordtoprivateDNSZone.role_definition_ids
/*
role_definition_ids = [
data.azurerm_role_definition.DNS_Zone_Contributor.id,
data.azurerm_role_definition.Network_Contributor.id
]
*/

By trying both the ways we are able to see role definition in
This identity will also be given the following permissions:

refer attach image
role_def_id

Facing below issue during remidiation


│ Error: Invalid for_each argument

│ on ..\modules\set_assignment\main.tf line 36, in resource "azurerm_management_group_policy_remediation" "rem":
│ 36: for_each = { for dr in local.definition_reference.mg : basename(dr.reference_id) => dr }
│ ├────────────────
│ │ local.definition_reference.mg will be known only after apply

│ The "for_each" value depends on resource attributes that cannot be determined until apply, so Terraform
│ cannot predict how many instances will be created. To work around this, use the -target argument to first
│ apply only the resources that the for_each depends on.

assignment_location has no effect?

When using the def_assignment module, and setting assignment_location to say westeurope seams not to have any effect on the location of the system assigned managed identity. It always gets created in uksouth. Was looking at code but can't see a reason why it wouldn't let me override the default value ?

Thank you !

When setting merge_effects = false definition effect parameter issue?

  • 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

Using the initiative module to create initiative with built-in policy definitions

  • Module Version: latest
  • Terraform Version: v1.3.1
  • AzureRM Provider Version: >=3.34.0
data "azurerm_policy_definition" "configure_azure_cache_for_redis_to_use_private_dns_zones" {
  display_name = "Configure Azure Cache for Redis to use private DNS zones"
}

data "azurerm_policy_definition" "configure_azure_key_vaults_to_use_private_dns_zones" {
  display_name = "[Preview]: Configure Azure Key Vaults to use private DNS zones"
}

data "azurerm_policy_definition" "configure_container_registries_to_use_private_dns_zones" {
  display_name = "Configure Container registries to use private DNS zones"
}


module "configure_private_dns_zones_for_private_endpoints" {
  source                  = "../modules/initiative"
  initiative_name         = "TF Configure Azure PaaS services to use private DNS zones"
  initiative_display_name = "[Network]: TF Configure Azure PaaS services to use private DNS zones"
  initiative_description  = "This policy initiative is a group of policies that ensures private endpoints to Azure PaaS services are integrated with Azure Private DNS zones"
  initiative_category     = "Network"
  merge_effects           = false
  merge_parameters        = false

  member_definitions = [
    data.azurerm_policy_definition.configure_azure_cache_for_redis_to_use_private_dns_zones,
    data.azurerm_policy_definition.configure_azure_key_vaults_to_use_private_dns_zones,
    data.azurerm_policy_definition.configure_container_registries_to_use_private_dns_zones
  ]
}

Expected Behavior

merge_effects = false and merge_parameters = false because I'd like to have the ability to set the effect per policy definition rather than once for all, merge parametes disabled as each policy definition needs to link to a private DNS zone that matches the given Azure service. Following the logic from documentation When setting merge_effects = false each definition effect parameter will be suffixed with its respective policy definition reference Id e.g. "effect_AutoEnrollSubscriptions". I would assume the same would happen with the above code.

Current Behavior

However, looks like what is being used instead is the definition ID guid:
image

image

Possible Solution

Steps to Reproduce

  1. Run the above code?

Assignments with remediation Applied - Timestamp

Hi @gettek ,

I would like to know if the behavior for remediation tasks in the module set_assignment is intended with naming the resource with a timestamp? As running a plan/apply will see the resources as net new each time it is applied. Wanting to destroying the existing with older time stamp and replaced with newer one / new timestamp. Thanks for your time, great job on the module/repo.

How to do custom metadata?

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

  • Module Version: 2.6.1
  • Terraform Version: 1.2.7
  • AzureRM Provider Version: 3.19.1

I need to add custom metadata fields. In this case, it's:

"owner": "security"

but there may be more in the future. However the default variable handling gets in the way here, causing the coalesce function to fail.

How do I simply add a new metadata field?

image

Expected Behavior

The custom metadata field should be applied.

Current Behavior

Terraform errors with this message:

image

Possible Solution

The default values for category and version are messing up the metadata handling in the coalesce function. I need a way to specify new metadata fields without those getting in the way. Perhaps the defaults can be removed - it's fine by me if Azure throws an error if we forget to include it.

Definition creation fails

  • Module Version:
  • Terraform Version: 3.3.1
  • AzureRM Provider Version: 3.34.0
#  Error: Error in function call
│
│   on ..\modules\definition\variables.tf line 107, in locals:107:   parameters = coalesce(var.policy_parameters, try((local.policy_object).properties.parameters, null))
│     ├────────────────
│     │ while calling coalesce(vals...)
│     │ local.policy_object is object with 5 attributes
│     │ var.policy_parameters is "../policies/Network/deny_private_dns_zones.json"
│
│ Call to function "coalesce" failed: all arguments must have the same type.

Expected Behavior

Definition gets created.

Current Behavior

Terraform deployment fails with the above code.

Link to the private dns policy from Azure Enterprise Scale that I'm trying to deploy https://raw.githubusercontent.com/Azure/Enterprise-Scale/main/src/resources/Microsoft.Authorization/policyDefinitions/Deny-Private-DNS-Zones.json

The definition.tf I'm using:

module "deny_nic_public_ip" {
  source            = "../modules/definition"
  policy_name       = "deny-private-dns-zones"
  display_name      = "Deny the creation of private DNS"
  policy_category   = "Network"
  file_path         = "../policies/Network/deny_private_dns_zones.json"
  policy_parameters = "../policies/Network/deny_private_dns_zones.json"
  policy_rule       = "../policies/Network/deny_private_dns_zones.json"
}

I've tested the same with one of the included policies in the repo, and got the same results.

Any advice please ? Thank you.

Remediation issue

│ Error: creating/updating /providers/Microsoft.Management/managementGroups/Platform-Pre-Production/providers/Microsoft.PolicyInsights/remediations/cdnendpointsworkflowdiagnosticsettingspolicydef-22-09-2022-08:32:39: remediations.RemediationsClient#RemediationsCreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidCreateRemediationRequest" Message="The request to create remediation 'cdnendpointsworkflowdiagnosticsettingspolicydef-22-09-2022-08:32:39' is invalid. The policy assignment '/providers/microsoft.management/managementgroups/platform-pre-production/providers/microsoft.authorization/policyassignments/resource-diagnostic-sett' assigns a policy set definition. Remediations must specify a single policy definition reference ID within the policy set definition."

│ with module.org_mg_resource-diagnostic-settings-la-policySet_initiative.azurerm_management_group_policy_remediation.rem["CdnEndpointsWorkflowDiagnosticSettingsPolicyDef"],
│ on ....\modules\set_assignment\main.tf line 121, in resource "azurerm_management_group_policy_remediation" "rem":
│ 121: resource "azurerm_management_group_policy_remediation" "rem" {

Everything was going fine but suddenly from today getting this error.
Not sure whats wrong

Using default effects and default parameters causes configuration change each time.

  • Terraform Version: Terraform v1.3.5 on windows_amd64

I have the following file, for the purpose of the issue, I am creating 2 assignments based on the same azure policy definition. The only difference is the first one I'm expecting it to use the default effect and default parameters. The second assignment I am defining the effect.

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=3.23.0"
    }
  }
}

provider "azurerm" {
  features {}
}

data azurerm_client_config current {}

data azurerm_subscription current {}

data "azurerm_management_group" "management_group" {
  display_name = "beispm5-es"
}

data "azurerm_policy_definition" "key_vault_disable_public_network_access" {
  display_name = "Azure Key Vault should disable public network access"
}

/*Uses default assignment and parameters */
module "key_vault_disable_public_network_access_assignment" {
  source               = "..//modules/def_assignment"
  assignment_name = "kv_message"
  definition                  = data.azurerm_policy_definition.key_vault_disable_public_network_access
  assignment_scope            = data.azurerm_management_group.management_group.id
  assignment_enforcement_mode = true
  /*assignment_effect = "Deny"*/
}

/* Assignment effect is entered */
module "key_vault_disable_public_network_access_assignment_no_message" {
  source               = "..//modules/def_assignment"
  assignment_name = "kv_nomessage"
  definition                  = data.azurerm_policy_definition.key_vault_disable_public_network_access
  assignment_scope            = data.azurerm_management_group.management_group.id
  assignment_enforcement_mode = true
  assignment_effect = "Deny"
}

I have run terraform apply once.

Expected Behavior

When I run 'terraform apply' the second time without any changes made, I expect to see no configuration changes required.

Current Behavior

However, it thinks it need to add parameters = "null" each time it run on the first assignment.
image

Possible Solution

Line 7 of def_assignment.tf

resource azurerm_management_group_policy_assignment def {
  count                = local.assignment_scope.mg
  name                 = local.assignment_name
  display_name         = local.display_name
  description          = local.description
  metadata             = local.metadata
  parameters           = local.parameters == "null" ? "" : local.parameters  //<-This is line 7

I believe you would need to do that for all the assignments, resources, resource groups etc. Unless there is a way of doing this on local.parameters.

Steps to Reproduce

Run the above code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.