Skip to content

azurerm_container_app_job: inconsistent final plan for Key Vault secret set due to null/empty value normalization #32923

Description

@arnaujc91

Is there an existing issue for this?

  • I have searched the existing issues

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 comments along the lines of "+1", "me too" or "any updates", 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 and review the contribution guide to help.

Terraform Version

1.14.0

AzureRM Provider Version

4.60.0

Affected Resource(s)/Data Source(s)

azurerm_container_app_job

Affected Location(s)

West Europe

Terraform Configuration Files

resource "azurerm_container_app_job" "crawler" {
  # Existing job; required top-level and template attributes omitted for brevity.

  # This Key Vault reference is known during the initial plan. Omitting `value`
  # is valid according to the resource schema and documentation.
  secret {
    name                = azurerm_key_vault_secret.application_insights.name
    identity            = azurerm_user_assigned_identity.crawler.id
    key_vault_secret_id = azurerm_key_vault_secret.application_insights.versionless_id
  }

  # Our real configuration also contains Key Vault secret elements whose IDs
  # are unknown in the initial plan and become known during apply.
  dynamic "secret" {
    for_each = local.credentials

    content {
      name                = secret.key
      identity            = azurerm_user_assigned_identity.crawler.id
      key_vault_secret_id = "${trimsuffix(data.azurerm_key_vault.secrets.vault_uri, "/")}/secrets/${secret.value.key_vault_secret_name}"
    }
  }
}

data "azurerm_key_vault" "secrets" {
  name                = var.key_vault_name
  resource_group_name = var.key_vault_resource_group_name

  # Representative of the apply-time dependency in the reproducing setup.
  # When the dependency changes, vault_uri is deferred until apply.
  depends_on = [module.key_vault]
}

Debug Output/Panic Output

Error: Provider produced inconsistent final plan

When expanding the plan for azurerm_container_app_job.crawler[0] to include
new values learned so far during apply, provider
"registry.terraform.io/hashicorp/azurerm" produced an invalid new value for
.secret: planned set element
cty.ObjectVal(map[string]cty.Value{
  "identity":cty.StringVal("/subscriptions/***/resourceGroups/example/providers/Microsoft.ManagedIdentity/userAssignedIdentities/crawler"),
  "key_vault_secret_id":cty.StringVal("https://example.vault.azure.net/secrets/application-insights-conn-string"),
  "name":cty.StringVal("application-insights-conn-string"),
  "value":cty.NullVal(cty.String)
}) does not correlate with any element in actual.

This is a bug in the provider, which should be reported in the provider's
own issue tracker.

The saved plan/state representation of the same Key Vault reference contains
value = "", while the apply-time expanded element shown above contains
value = null.

Expected Behaviour

The apply-time plan expansion should correlate the existing Key Vault-backed
secret element successfully. Omitting value should work when
key_vault_secret_id is set, including when other elements of the secret set
contain values that are resolved during apply.

Actual Behaviour

The provider fails during apply-time plan expansion because a planned secret
set element containing value = null does not correlate with the existing
element represented with value = "".

This appears to be null/empty-string normalization affecting the hash or
correlation of the secret TypeSet. The Azure resource itself remains valid
and healthy.

Explicitly setting the otherwise irrelevant value field works around the
failure:

secret {
  name                = azurerm_key_vault_secret.application_insights.name
  identity            = azurerm_user_assigned_identity.crawler.id
  key_vault_secret_id = azurerm_key_vault_secret.application_insights.versionless_id
  value               = ""
}

With that change, the plan and apply succeed without changing the resulting
Azure Key Vault secret reference.

Steps to Reproduce

  1. Create an azurerm_container_app_job containing multiple Key Vault-backed
    secret blocks, leaving value omitted as documented.
  2. Ensure at least one key_vault_secret_id is unknown in the initial plan and
    becomes known during apply (for example, through an apply-time data-source
    dependency).
  3. Run terraform plan -out=tfplan.
  4. Run terraform apply tfplan.
  5. Observe the inconsistent-final-plan error while AzureRM re-expands the
    secret set.
  6. Set value = "" explicitly on the otherwise-known secret element and repeat;
    the apply succeeds.

Important Factoids

Public Azure, West Europe. The Container App Job uses a user-assigned managed
identity and versionless Key Vault secret IDs. The failure has reproduced in
multiple CI apply attempts.

References

This resembles the set-element correlation class reported for another AzureRM
resource in #18263, but affects the secret set of
azurerm_container_app_job and specifically exposes null versus "" for
value.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions