Terraform-provider-azurerm: Policies always update even when no change occurs

Created on 28 Nov 2019  ·  9Comments  ·  Source: terraform-providers/terraform-provider-azurerm

Related to #2938

Terraform (and AzureRM Provider) Version

Terraform v0.12.16
+ provider.azurerm v1.34.0

Affected Resource(s)

  • azurerm_policy_definition

Terraform Configuration Files

resource "azurerm_policy_definition" "policy" {
  name         = "accTestPolicy"
  policy_type  = "Custom"
  mode         = "Indexed"
  display_name = "Acceptance test policy definition"

  metadata = <<METADATA
    {
    "category": "General"
    }
  METADATA

  policy_rule = <<POLICY_RULE
    {
    "if": {
      "not": {
        "field": "location",
        "in": "[parameters('allowedLocations')]"
      }
    },
    "then": {
      "effect": "audit"
    }
  }
POLICY_RULE

  parameters = <<PARAMETERS
    {
    "allowedLocations": {
      "type": "Array",
      "metadata": {
        "description": "The list of allowed locations for resources.",
        "displayName": "Allowed locations",
        "strongType": "location"
      }
    }
  }
PARAMETERS
}

Expected Behavior

Terraform should report no updates in policies that haven't changed during terraform apply and terraform plan

Actual Behavior

Terraform always update on refresh, policies that haven't changed.
What Terraform is updating though, are fields in Metadata that are not present in the configuration file, but are present in Azure, so it tries to clear them.

              - createdBy = "4-1c33-4966-89ae-23423423423" -> null
              - createdOn = "2019-11-28T10:04:28.3320952Z" -> null
              - updatedBy = "324234-1c33-4234-89ae-234" -> null
              - updatedOn = "2019-11-28T10:47:41.4931002Z" -> null
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
  ~ update in-place

Terraform will perform the following actions:

  # azurerm_policy_definition.policy will be updated in-place
  ~ resource "azurerm_policy_definition" "policy" {
        display_name = "Acceptance test policy definition"
        id           = "/subscriptions/43423423423423-43432423/providers/Microsoft.Authorization/policyDefinitions/accTestPolicy"
      ~ metadata     = jsonencode(
          ~ {
                category  = "General"
              - createdBy = "4-1c33-4966-89ae-23423423423" -> null
              - createdOn = "2019-11-28T10:04:28.3320952Z" -> null
              - updatedBy = "324234-1c33-4234-89ae-234" -> null
              - updatedOn = "2019-11-28T10:47:41.4931002Z" -> null
            }
        )
        mode         = "Indexed"
        name         = "accTestPolicy"
        parameters   = jsonencode(
            {
                allowedLocations = {
                    metadata = {
                        description = "The list of allowed locations for resources."
                        displayName = "Allowed locations"
                        strongType  = "location"
                    }
                    type     = "Array"
                }
            }
        )
        policy_rule  = jsonencode(
            {
                if   = {
                    not = {
                        field = "location"
                        in    = "[parameters('allowedLocations')]"
                    }
                }
                then = {
                    effect = "audit"
                }
            }
        )
        policy_type  = "Custom"
    }

Steps to Reproduce

  1. terraform apply
  2. terraform plan

Important Factoids

This policy has been created within the same configuration file, using the same state file.

  • #0000
bug servicpolicy

Most helpful comment

I had the same issue and work around is adding below section in the policy definition. Hope it works for you.

==========

lifecycle {
ignore_changes = [
metadata
]
}

All 9 comments

I had the same issue and work around is adding below section in the policy definition. Hope it works for you.

==========

lifecycle {
ignore_changes = [
metadata
]
}

While the proposed work around solves this issue, it has one con in that other changes to metadata will be ignored as well. Would be better if you could specify specific attributes to ignore on metadata

lifecycle { ignore_changes = [ metadata["updatedOn"] ] }

However this is not currently supported.

Error: Invalid index

on modules/allowed-locations/main.tf line 15, in resource "azurerm_policy_definition" "allowed-locations":
15: metadata["updatedOn"]

This value does not have any indices.

According to the documentation on lifecycle management this should be supported.

https://www.terraform.io/docs/configuration/resources.html#lifecycle-lifecycle-customizations

I have confirmed that this issue still exists in provider.azurerm = 2.4.0

I think I have a fix for this. I'll create a PR and mention this issue in it.

The pull request only address the issue in azurerm_policy_set_definition resources . Can you make the change for azurerm_policy_definition resources as well ?

I don't know why I thought it only affected policy initiatives. I need to create a test for the PR anyway, so yes, I'll modify azurerm_policy_definition too.

My first ever code change, so this is a definite learning experience!

This has been released in version 2.9.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.9.0"
}
# ... other configuration ...

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

Was this page helpful?
0 / 5 - 0 ratings