terraform-aws-eks icon indicating copy to clipboard operation
terraform-aws-eks copied to clipboard

Module argument cluster_encryption_config does not handle a null value

Open sstamatiadis-dlt opened this issue 1 year ago β€’ 0 comments

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)

  • [x] βœ‹ 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

sstamatiadis-dlt avatar May 15 '24 14:05 sstamatiadis-dlt