Use lifecycle.ignore_changes on dynamic block

Hi everyone!
Last time when I had quite specific problem this community really help me, therefore I have some challenge for you!

I had created initiative on Azure, but I need to put inside “definition_references” empty dictionary in “parameter_values”. I can’t type “null”, because inside “azurerm_policy_set_definition” I have to use dynamic block for provide more then one “definition_references” inside. Forcing “null” variable there respond an error when I have defined parameter somewhere else in “definition_references”.
To clarify when I have parmeter defined in first field of “definition_references”, and I do not have parameter in the second one, I have error. When in every field of “definition_references.parameter_values” I type “null” deploy is completed.
I hope it’s understandable why I need provide ‘{}’ there

What the problem is?
When I type empty dictionary, on the plan action every time I had change on this initiative, why? Because on the provider level parameter is convert using jsonencode()

      ~ policy_definition_reference {
          + parameter_values     = jsonencode({})
            # (3 unchanged attributes hidden)

So I need to find some way to skip this change, I try to add exception inside lifecycle, but I can’t itter inside because I have to meet dynamic block requirements

  lifecycle {
    ignore_changes = [
      policy_definition_reference[0].parameter_values,
    ]
  }

I have to change this “0” to “*” but terraform do not allow it…
Terraform code:

resource "azurerm_policy_set_definition" "initiative" {
  for_each            = local.initiative
  name                = each.value["name"]
  policy_type         = each.value["type"]
  display_name        = each.value["dname"]
  management_group_id = each.value["mg"]
  parameters          = jsonencode(each.value["parameters"])
  description         = each.value["description"]
  metadata            = each.value["metadata"]

  dynamic "policy_definition_reference" {
    for_each = toset(each.value["definition_references"])

    content {
      policy_definition_id = policy_definition_reference.key.policyDefinitionId
      parameter_values     = policy_definition_reference.key.parameters
      reference_id         = policy_definition_reference.key.policyDefinitionReferenceId
      policy_group_names   = policy_definition_reference.key.groupNames
    }
  }

  lifecycle {
    ignore_changes = [
      policy_definition_reference[0].parameter_values,
    ]
  }
}

I hope you could give me some useful hint :wink:
Best regards!

Hi @rebel123,

ignore_changes only takes static references, so there is no way to specifically ignore an unspecified number of object attributes.

However if your configuration is not changing, then ignore_changes is not the correct tool, because there should be no local changes to ignore. The problem here is a bug in the provider, but there are usually a couple ways to work around it.

  • The initial plan may not be normalized correctly by the provider, and applying the proposed minor changes will allow it to converge on a stable configuration value.
  • If the provider continues to toggle the given values, insert the empty value that the provider expects in your configuration.