Skip to content
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

Module argument cluster_encryption_config does not handle a null value #3036

Open
1 task done
sstamatiadis-dlt opened this issue May 15, 2024 · 0 comments
Open
1 task done
Labels

Comments

@sstamatiadis-dlt
Copy link

sstamatiadis-dlt commented May 15, 2024

Description

I am trying to set the cluster_encryption_config to encrypt the cluster secrets conditionally, only in case I supply the KMS key in my variable kms_key_arn. The variable is set to null by default. I am getting an error because the module does not perform a null check before applying KMS. I had the impression that setting something to null would guide terraform to "unset" and resort to the default module behavior (see Conditionally Omitted Arguments)

  • ✋ I have searched the open/closed issues and my issue is not listed.

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

  • Module version [Required]: 19.5.1

  • Terraform version: v1.5.4

  • Provider version(s): registry.terraform.io/hashicorp/aws v4.67.0

Reproduction Code [Required]

module "eks-cluster" {
  source                    = "terraform-aws-modules/eks/aws"
  version                   = "19.5.1"
  cluster_name              = var.cluster_name
  cluster_version           = var.kubernetes_version
  control_plane_subnet_ids  = module.vpc.private_subnets
  vpc_id                    = module.vpc.vpc_id
  enable_irsa               = true
  manage_aws_auth_configmap = true
  cluster_addons = {
    coredns = {
      preserve    = true
      most_recent = true
      configuration_values = jsonencode(
        {
          tolerations = [
            {
              key      = "CriticalAddonsOnly"
              operator = "Exists"
            },
            {
              key    = "node-role.kubernetes.io/master"
              effect = "NoSchedule"
            }
          ]
        }
      )
    }
  }
  create_kms_key = false
  cluster_encryption_config = (var.kms_key_arn != null ? {
    provider_key_arn = var.kms_key_arn
    resources        = ["secrets"]
  } : null)
  iam_role_path                          = var.iam_path
  cluster_enabled_log_types              = var.control_plane_logging
  cloudwatch_log_group_retention_in_days = var.control_plane_logging_retention
  cloudwatch_log_group_kms_key_id        = var.kms_key_arn
  cluster_endpoint_public_access         = true
  cluster_endpoint_public_access_cidrs   = var.whitelist_cidrs
  cluster_endpoint_private_access        = true
  aws_auth_users                         = var.cluster_api_permitted_users
  aws_auth_roles = concat([{
    rolearn  = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/EKS.${var.cluster_name}.KRPNTRNodeRole"
    username = "system:node:{{EC2PrivateDNSName}}"
    groups = [
      "system:bootstrappers",
      "system:nodes"
    ]
    }],
  var.cluster_api_permitted_roles)
  cluster_security_group_tags = {
    "karpenter.sh/discovery" = var.cluster_name
  }

  eks_managed_node_groups = {
    core = {
      subnet_ids          = data.aws_subnets.single_zone_subnets.ids
      ami_release_version = var.node_ami_version
      desired_size        = var.core_node_desired_size
      max_size            = var.core_node_max_size
      min_size            = var.core_node_min_size
      instance_types      = var.core_node_instance_types

      labels = {
        workloads = "core"
      }

      create_launch_template     = false
      use_custom_launch_template = true
      launch_template_id         = aws_launch_template.eks-template.id
      launch_template_version    = aws_launch_template.eks-template.default_version

      iam_role_additional_policies = {
        "S3FullAccessPolicy"           = var.additional_worker_policy_s3
        "AmazonSSMManagedInstanceCore" = var.additional_worker_policy_ssm
      }

      tags = {
        "k8s.io/cluster-autoscaler/${var.cluster_name}" = "owned"
        "k8s.io/cluster-autoscaler/enabled"             = "TRUE"
      }
    }
  }

  tags = merge(
    var.tags,
    {
      Name = "EKS.${var.cluster_name}.Cluster"
  })
}

Steps to reproduce the behavior:

  1. Set kms_key_arn variable to null
  2. Deploy EKS module
  3. Fail with error

Expected behavior

The encryption configuration should be conditional, accept and handle a null config the same way it does for an empty object {}. When the null value is checked by the module code, it does not do a null check see https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/main.tf#L20

ℹ️ If I try to use an empty object instead of a null value in the false statement of the ternary operator, terraform validation complains that the type is not the same because it does not contain the 2 encryption attributes. Setting them separately null does not work either, leaving no other possible work-around.

Actual behavior

Error: Invalid function argument
│ 
│   on .terraform/modules/eks-cluster/main.tf line 18, in locals:
│   18:   enable_cluster_encryption_config = length(var.cluster_encryption_config) > 0 && !local.create_outposts_local_cluster
│     ├────────────────
│     │ while calling length(value)
│     │ var.cluster_encryption_config is null
│ 
│ Invalid value for "value" parameter: argument must not be null.

if we use this solution:

  create_kms_key = false
  cluster_encryption_config = (var.kms_key_arn != null ? {
    provider_key_arn = var.kms_key_arn
    resources        = ["secrets"]
  } : {})

we get a validation error:

Error: Inconsistent conditional result types
│ 
│   on aws-eks-module.tf line 40, in module "eks-cluster":
│   40:   cluster_encryption_config = (var.kms_key_arn != null ? {
│   41:     provider_key_arn = var.kms_key_arn
│   42:     resources        = ["secrets"]
│   43:   } : {})
│     ├────────────────
│     │ var.kms_key_arn is a string
│ 
│ The true and false result expressions must have consistent types. The 'true' value includes object attribute "provider_key_arn", which is absent in the 'false' value.

Terminal Output Screenshot(s)

Additional context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants