terraform-provider-azurerm: azurerm_policy_set_definition update behaviour broken in 2.19 using policy_definition_reference
Community Note
- Please vote on this issue by adding a š reaction to the original issue to help the community and maintainers prioritize this request
- Please do not leave ā+1ā or āme tooā comments, they generate extra noise for issue followers and do not help prioritize the request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Terraform (and AzureRM Provider) Version
Terraform v0.12.28
- provider.azurerm v2.19.0
Affected Resource(s)
azure_policy_set_definition
Terraform Configuration Files
Iām unable to provide all the relevant code due to restrictions on releasing code from the end client.
resource "azurerm_policy_set_definition" "diags" {
name = "diagnostics-initiative"
policy_type = "Custom"
display_name = "Apply Default Diagnostic Settings"
management_group_name = var.definition_management_group_name
parameters = file("${path.module}/json/diagnostics/_globals/initiative_parameters.json")
dynamic "policy_definition_reference" {
for_each = [for item in var.diagnostic_settings: {
name = item.resource_name
}
if item.include_in_initiative==true && item.policy_type =="logs"
]
content {
policy_definition_id = azurerm_policy_definition.definition["${policy_definition_reference.value.name}_logs"].id
parameters = {
eventHubAuthorizationRuleId = "[parameters('eventHubAuthorizationRuleId')]"
eventHubName = "[parameters('eventHubName')]"
logsEnabled = "[parameters('logsEnabled')]"
profileName = "[parameters('profileName')]"
storageAccountId = "[parameters('storageAccountId')]"
workspace = "[parameters('workspace')]"
retentionInDays = "[parameters('retentionInDays')]"
}
}
}
dynamic "policy_definition_reference" {
for_each = [for item in var.diagnostic_settings: {
name = item.resource_name
}
if item.include_in_initiative==true && item.policy_type =="metrics"
]
content {
policy_definition_id = azurerm_policy_definition.definition["${policy_definition_reference.value.name}_metrics"].id
parameters = {
eventHubAuthorizationRuleId = "[parameters('eventHubAuthorizationRuleId')]"
eventHubName = "[parameters('eventHubName')]"
metricsEnabled = "[parameters('metricsEnabled')]"
profileName = "[parameters('profileName')]"
workspace = "[parameters('workspace')]"
}
}
}
}
The input consists of input files containing the following which are created using a for_each against the azurerm_policy_definition resource.
variable "diagnostic_settings" {
default = {
# Azure Firewall
firewall_logs = {
resource_name = "firewall"
resource_type = "Microsoft.Network/azureFirewalls"
display_name = "Azure Firewall Logs"
policy_type = "logs"
include_in_initiative = true
}
firewall_metrics = {
resource_name = "firewall"
resource_type = "Microsoft.Network/azureFirewalls"
display_name = "Azure Firewall Metrics"
policy_type = "metrics"
include_in_initiative = true
}
}
}
Expected Behavior
Policy Initiative should have been amended with additional or removal of a policy.
Actual Behavior
When adding/removing items it throws errors on the resource_id as it tries to re-map the resource_ids between different policies.
azurerm_policy_set_definition.diags: Modifying⦠[id=/providers/Microsoft.Management/managementgroups/sandbox/providers/Microsoft.Authorization/policySetDefinitions/diagnostics-initiative]
Error: creating/updating Policy Set Definition ādiagnostics-initiativeā: policy.SetDefinitionsClient#CreateOrUpdateAtManagementGroup: Failure responding to request: StatusCode=400 ā Original Error: autorest/azure: Service returned an error. Status=400 Code=āDuplicateReferencesInPolicySetā Message=āThe policy set definition ādiagnostics-initiativeā request is invalid. Policy set definition contains duplicate policy references. Duplicate reference Ids are ā14127430907021476224ā. Please remove any exact duplicates from the policy set definition. Violating policy definition Ids are ā/providers/Microsoft.Management/managementgroups/sandbox/providers/Microsoft.Authorization/policyDefinitions/diag-logic_apps-metrics, /providers/Microsoft.Management/managementgroups/sandbox/providers/Microsoft.Authorization/policyDefinitions/diag-virtual_network-metricsā.ā
on diagnostics_policies_initiative.tf line 34, in resource āazurerm_policy_set_definitionā ādiagsā: 34: resource āazurerm_policy_set_definitionā ādiagsā {
Steps to Reproduce
- Apply an initiative with multiple policies
- Inject an additional policy into the middle of the list OR remove an item from the list
- Plan and apply the update
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 12
- Comments: 17
Iām wondering whether setting a unique value in the optional āreference_idā will resolve the issue. I believe having that passed in alongside the definition ID may get this to work. Looking at the Security Center initiative, they have the ref ID set to a text string not numeric ID.
I havenāt had time to test that yet, but will let you know once I do.
The solution of adding āreference_idā to all the policies referenced in the initiative indeed fixed the Duplicate policy references issue for me too, thanks!
I have tried putting a unique value for
reference_idin all of mypolicy_definition_referenceblocks, however it did not appear to fix the issue.For example, if I remove one
policy_definition_referenceblock from the resource, and then do aplanorapply, it tries to re-mapreference_idās for no apparent reason:Please note how the reference_ids are being re-mapped however I have NOT changed them in my code.
I am running:
Hi @bigglesuk69 and @caldwell2000 thanks for your discussions and I just had some experiments about this.
This is truly caused by the
reference_id. When you create the set definition without assigning areference_id, Azure will automatically create one for you and send it back - therefore this attribute isComputed. But in the terraform implementation, we do not ensure this kind bind, which is saying that in a case of a reordering of thepolicy_definition_referenceblocks, terraform will treat your change as you have changed thedefinition_id, but thereference_idremains the same. In this case, Azure will return error like posted in the description complaining aboutDuplicateReferencesInPolicySet. And the reason for the reordering should be that you are using a set to iterate thepolicy_definition_reference. In a hash set, the order is deterministic but not guaranteed, every time you add or remove or change the element of it, the iteration may reorder, and therefore comes this issue.And also, to work this around, explicitly assigning
reference_idby yourself works - this manages the bind between the reference_id and the definition_id, and therefore no duplicate error will pop out.I am considering that we could change the type of
policy_definition_referencefrom List to Set (but this would be considered as a breaking change), but I am not absolutely sure, is this list ofpolicy_definition_referenceguaranteed to be distinct and orderless?Having the same issue. Is there a workaround or a fix coming soon? Using Versions: Terraform v0.12.21 provider.azurerm v2.25.0