Skip to content

ibm_iam_policy_template_version - Plan shows update instead of replace #6167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
rmahroua opened this issue Apr 17, 2025 · 0 comments
Open
Labels
service/IAM Issues related to IAM service/IAMPAP Issues related to IAM Policy Management

Comments

@rmahroua
Copy link

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 other comments that do not add relevant new information or questions, 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 CLI and Terraform IBM Provider Version

» terraform -v
Terraform v1.11.4
on darwin_amd64
+ provider registry.terraform.io/hashicorp/external v2.3.4
+ provider registry.terraform.io/hashicorp/local v2.5.2
+ provider registry.terraform.io/hashicorp/vault v4.6.0
+ provider registry.terraform.io/ibm-cloud/ibm v1.75.0

Affected Resource(s)

  • ibm_iam_policy_template_version

Terraform Configuration Files

resource "ibm_iam_policy_template_version" "policy_templates" {
  for_each = local.policy_versions

  name        = each.value.template_name
  description = each.value.description
  committed   = true
  template_id = split("/", lookup(local.policy_template_by_id, each.value.template_name, "ERROR: Template ID not found"))[0]

  policy {
    type  = var.default_policy_type
    roles = each.value.roles

    resource {
      dynamic "attributes" {
        for_each = each.value.attributes != null ? [each.value.attributes] : []

        content {
          key      = attributes.value.key
          value    = attributes.value.value
          operator = attributes.value.operator
        }
      }
    }
  }

  depends_on = [ibm_iam_policy_template.parent_policy_templates]
  lifecycle {
    ignore_changes = [
      committed
    ]
  }
}
variable "policy_templates" {
  description = "Default settings for managed access groups"
  type = list(
    object(
      {
        name        = string
        description = string
        roles       = list(string)
        attributes  = map(string)
      }
    )
  )
  default = [
    {
      "name"        = "Read-only access",
      "description" = "Provide read only access to all resources",
      "roles" = [
        "Viewer",
        "Reader"
      ],
      "attributes" = {
        "value"    = "service",
        "operator" = "stringEquals",
        "key"      = "serviceType"
      }
    }
  ]
}
locals {
  policy_templates = {
    for p in var.policy_templates : p.name => p
  }

  policy_template_by_id = {
    for name, p in ibm_iam_policy_template.parent_policy_templates : name => p.id
  }

  policy_versions = {
    for name, config in local.policy_templates :
    "${name}-${md5(jsonencode(
      {
        description = config.description
        roles       = config.roles
        attributes  = config.attributes
        type        = var.default_policy_type
      }))
      }" => {
      template_name = config.name
      description   = config.description
      roles         = config.roles
      attributes    = config.attributes
    }
  }
}

Debug Output

https://gist.github.com/rmahroua/1e2698214cae5e8b2bdd00f0be776715

Panic Output

None

Expected Behavior

When a field included in the hash calculation (e.g., description, roles, attributes) is modified in the var.policy_templates variable for an existing template (e.g., "Resources manager"):

  1. The md5 hash calculated in local.policy_versions for "Resources manager" should change.
  2. The corresponding key in the for_each map for the ibm_iam_policy_template_version.policy_templates resource should change as well.
  3. terraform plan should detect this key change and plan to destroy the resource instance associated with the old key (e.g., ...["Resources manager-<OLD_HASH>"]) and create a resource instance associated with the new key (e.g., ...["Resources manager-<NEW_HASH>"]).

The plan summary should reflect this replacement (e.g., 1 to add, 0 to change, 1 to destroy, potentially alongside other unrelated changes).

Actual Behavior

After modifying a field included in the hash calculation (e.g., description for the "Resources manager" policy template) in var.policy_templates, saving the file, and confirming via the Terraform console that the calculated hash key for "Resources manager" definition does change:

  1. Running terraform plan shows an incorrect plan.
  2. The plan summary may show unrelated add/destroy/change counts (e.g., Plan: 1 to add, 13 to change, 1 to destroy. was observed), but the specific action for the modified resource is wrong.
  3. Critically, the plan includes an in-place update (~ resource ... will be updated in-place) for the specific ibm_iam_policy_template_version instance associated with the old hash key (e.g., ...["Resources manager-<OLD_HASH>"]), only showing the changed attribute (e.g., description) within that existing resource instance:
# Snippet from plan output:
module.policy_templates[0].ibm_iam_policy_template_version.policy_templates["Resources manager-a54c0fede9c38a509451fca8aa074332"] will be updated in-place
  ~ resource "ibm_iam_policy_template_version" "policy_templates" {
      ~ description = "Provides management access to accounts, excluding IAM" -> "Provide management access to platform services"
        id          = "policyTemplate-b8d5d67c-f2b6-47f2-935a-5d8bc1f59e7e/1" # ID associated with old instance
        name        = "Resources manager"
        # ...
    }

This contradicts the expected Terraform behavior for for_each key changes, which should force replacement.
The debug log consistently shows the warning:

[WARN] Provider "registry.terraform.io/ibm-cloud/ibm" produced an invalid plan for ... [<OLD_HASH_KEY_INSTANCE>], but we are tolerating it because it is using the legacy plugin SDK. This occurs even after upgrading Terraform Core (to v1.11.4+) and the IBM provider (to v1.77.1+).

Steps to Reproduce

  1. Run terraform apply to create the initial parent template and Version 1 for the Resources manager policy template.
  2. Modify the description in the var.policy_templates default block
  3. Run terraform console and read the local.policy_versions variable. Compare the resource key from before the change to confirm that it is different.
  4. Run terraform plan

Important Factoids

  1. The "hash" workaround was added to address a potential issue in how this resource handles versions. Namely, it attempts to perform in-place upgrade for existing policy template versions that are already committed. IBM Cloud IAM API doesn't allow to make changes to committed templates.
  2. Standard IBM Cloud account. Issue persists after upgrading Terraform Core and IBM Provider to recent versions (TF >= 1.11.4, Provider >= 1.77.1).

References

@github-actions github-actions bot added service/IAM Issues related to IAM service/IAMPAP Issues related to IAM Policy Management labels Apr 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
service/IAM Issues related to IAM service/IAMPAP Issues related to IAM Policy Management
Projects
None yet
Development

No branches or pull requests

1 participant