Skip to content

Incorrect EKS Addon timeouts coalescingย #3479

@Moglum

Description

@Moglum

Description

EKS Addon timeouts can be specified "globally" for all addons via addons_timeouts and for each addon specifically via addons.someAddon.timeouts, which, if specified, should override the global settings.

This stopped working with 21.0.5.

Unless at least an empty timeouts = {} is specified for a given addon, the global default addons_timeouts are ignored.

Versions

  • Module version [Required]:
    terraform-aws-eks 21.0.9

  • Terraform version:

Terraform v1.12.2
on linux_amd64
  • Provider version(s):
+ provider registry.terraform.io/hashicorp/aws v6.8.0
+ provider registry.terraform.io/hashicorp/time v0.12.1
+ provider registry.terraform.io/hashicorp/tls v4.0.6

Reproduction Code [Required]

Steps to reproduce the behavior:

  # module.eks_al2023.aws_eks_addon.this["coredns"] will be created
  + resource "aws_eks_addon" "this" {
      + addon_name                  = "coredns"
      + addon_version               = (known after apply)
      + arn                         = (known after apply)
      + cluster_name                = (known after apply)
      + configuration_values        = (known after apply)
      + created_at                  = (known after apply)
      + id                          = (known after apply)
      + modified_at                 = (known after apply)
      + preserve                    = true
      + region                      = "eu-west-1"
      + resolve_conflicts_on_create = "NONE"
      + resolve_conflicts_on_update = "OVERWRITE"
      + tags                        = {
          + "Example"    = "ex-eks-mng"
          + "GithubOrg"  = "terraform-aws-modules"
          + "GithubRepo" = "terraform-aws-eks"
        }
      + tags_all                    = {
          + "Example"    = "ex-eks-mng"
          + "GithubOrg"  = "terraform-aws-modules"
          + "GithubRepo" = "terraform-aws-eks"
        }

      + timeouts {}
    }
  • add global timeouts to EKS module
  addons_timeouts = {
    create = "55m"
  }
  • run plan again
  • same result as above, but this time incorrectly ignored global create timeout
  • modify addons config
  addons = {
    coredns = { timeouts = {} }
    ...
  }
  • run plan again
  • now the global default is used for coredns, but not for any other addon
  # module.eks_al2023.aws_eks_addon.this["coredns"] will be created
  + resource "aws_eks_addon" "this" {
      + addon_name                  = "coredns"
      + addon_version               = (known after apply)
      + arn                         = (known after apply)
      + cluster_name                = (known after apply)
      + configuration_values        = (known after apply)
      + created_at                  = (known after apply)
      + id                          = (known after apply)
      + modified_at                 = (known after apply)
      + preserve                    = true
      + region                      = "eu-west-1"
      + resolve_conflicts_on_create = "NONE"
      + resolve_conflicts_on_update = "OVERWRITE"
      + tags                        = {
          + "Example"    = "ex-eks-mng"
          + "GithubOrg"  = "terraform-aws-modules"
          + "GithubRepo" = "terraform-aws-eks"
        }
      + tags_all                    = {
          + "Example"    = "ex-eks-mng"
          + "GithubOrg"  = "terraform-aws-modules"
          + "GithubRepo" = "terraform-aws-eks"
        }

      + timeouts {
          + create = "55m"
        }
    }

  # module.eks_al2023.aws_eks_addon.this["kube-proxy"] will be created
  + resource "aws_eks_addon" "this" {
      + addon_name                  = "kube-proxy"
      + addon_version               = (known after apply)
      + arn                         = (known after apply)
      + cluster_name                = (known after apply)
      + configuration_values        = (known after apply)
      + created_at                  = (known after apply)
      + id                          = (known after apply)
      + modified_at                 = (known after apply)
      + preserve                    = true
      + region                      = "eu-west-1"
      + resolve_conflicts_on_create = "NONE"
      + resolve_conflicts_on_update = "OVERWRITE"
      + tags                        = {
          + "Example"    = "ex-eks-mng"
          + "GithubOrg"  = "terraform-aws-modules"
          + "GithubRepo" = "terraform-aws-eks"
        }
      + tags_all                    = {
          + "Example"    = "ex-eks-mng"
          + "GithubOrg"  = "terraform-aws-modules"
          + "GithubRepo" = "terraform-aws-eks"
        }

      + timeouts {}
    }

Expected behavior

This

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "21.0.9"
  ...
  addons          = { cert-manager = {} }
  addons_timeouts = { update = "60m" }
}

should result in the addon being created with an update timeout of 60m

resource "aws_eks_addon" "cert-manager" {
  addon_name   = "cert-manager"
  ...
  timeouts {
    update = "60m"
  }
}

Actual behavior

But the actual result from version 21.0.5 is that no timeouts will be specified, so that the default will be used. Older versions work as expected.

For 21.0.5 and newer, only when at least an empty timeouts block is specified on the addon level

  addons          = { cert-manager = { timeouts = {} } }
  addons_timeouts = { update = "60m" }

will the coalescing logic actually kick in.

Terminal Output Screenshot(s)

Additional context

This PR changed the logic #3449, and the expected behavior above is no longer working.

The addition of coalesce() broke it

create = try(coalesce(each.value.timeouts.create, var.addons_timeouts.create), null)

When each.value.timeouts isn't specified, the expression each.value.timeouts.create returns an error, which in turn causes the whole coalesce(..) to return an error and try will skip it to returning null instead of var.addons_timeouts.create.

The previous logic worked as expected, discarding the first error expression and using the global default, if specified. Only defaulting to null if neither is specified.

create = try(each.value.timeouts.create, var.addons_timeouts.create, null)

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