Skip to content

[eks-managed-node-group]: for_each statement fails due to values not known before applyΒ #3593

@grrtrr

Description

@grrtrr

Description

Getting the following error with create_iam_role = false:

β”‚ Error: Invalid for_each argument
β”‚ 
β”‚   on .terraform/modules/karpenter_node_group.node_group/modules/eks-managed-node-group/main.tf line 538, in resource "aws_iam_role_policy_attachment" "this":
β”‚  538:   for_each = { for k, v in merge(
β”‚  539:     {
β”‚  540:       AmazonEKSWorkerNodePolicy          = "${local.iam_role_policy_prefix}/AmazonEKSWorkerNodePolicy"
β”‚  541:       AmazonEC2ContainerRegistryReadOnly = "${local.iam_role_policy_prefix}/AmazonEC2ContainerRegistryReadOnly"
β”‚  542:     },
β”‚  543:     local.ipv4_cni_policy,
β”‚  544:     local.ipv6_cni_policy
β”‚  545:   ) : k => v if local.create_iam_role }
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ local.create_iam_role is false
β”‚     β”‚ local.iam_role_policy_prefix is "arn:aws:iam::aws:policy"
β”‚     β”‚ local.ipv4_cni_policy will be known only after apply
β”‚     β”‚ local.ipv6_cni_policy will be known only after apply
  • βœ‹ I have searched the open/closed issues and my issue is not listed.

Versions

Reproduction Code [Required]

It's in a spacelift test, next section should clarify.

Steps to reproduce the behavior:

  • Set create_iam_role = false.
  • Provide iam_role_arn.

Root cause

The for_each statement should under no circumstances fail.
The problem is that the merge statement is evaluated before the if condition.

Suggested fix

Pulling the if condition outside of the merge statement avoids the problem:

resource "aws_iam_role_policy_attachment" "this" {
  for_each = local.create_iam_role ? { for k, v in merge(
    {
      AmazonEKSWorkerNodePolicy          = "${local.iam_role_policy_prefix}/AmazonEKSWorkerNodePolicy"
      AmazonEC2ContainerRegistryReadOnly = "${local.iam_role_policy_prefix}/AmazonEC2ContainerRegistryReadOnly"
    },
    local.ipv4_cni_policy,
    local.ipv6_cni_policy
  ) : k => v } : {}  # <== CHANGED

  policy_arn = each.value
  role       = aws_iam_role.this[0].name
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions