IaC Bazaar
AWSStatic-verified

EKS Cluster with Managed Node Groups

Opinionated EKS cluster with node groups, core add-ons, Pod Identity, and KMS secret encryption.

terraformAWS#aws

Compare Managed Kubernetes across clouds →

aws-eksterraform v1.7

Verification

Static-verified

Passed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan: findings disclosed (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-06-28 · how we verify

Documentation

aws-eks

Opinionated EKS cluster with managed node groups, core add-ons, EKS Pod Identity, and KMS secret encryption. Works with Terraform and OpenTofu (>= 1.6), AWS provider >= 6.0, < 7.0.

Secure defaults:

  • KMS envelope encryption of Kubernetes secrets (dedicated rotation-enabled key created unless you bring your own)
  • Private API endpoint always enabled; public endpoint CIDR-restrictable or off
  • Control-plane logging (api, audit, authenticator) to a retention-managed CloudWatch log group
  • Modern API authentication mode (access entries) and STANDARD upgrade policy (no surprise extended-support billing)
  • No SSH/remote access to nodes; least-privilege cluster and node IAM roles
  • Default add-on set includes eks-pod-identity-agent, so Pod Identity associations work out of the box

Usage

module "eks" {
  source = "./aws-eks"

  cluster_name = "platform-prod"
  subnet_ids   = ["subnet-aaa", "subnet-bbb"] # private, 2+ AZs

  node_groups = {
    general = {
      instance_types = ["m6i.large"]
      min_size       = 2
      desired_size   = 3
      max_size       = 6
    }
    spot = {
      capacity_type  = "SPOT"
      instance_types = ["m6i.large", "m5.large"]
    }
  }

  pod_identity_associations = {
    app = {
      namespace       = "default"
      service_account = "app"
      role_arn        = "arn:aws:iam::123456789012:role/app"
    }
  }

  tags = { Environment = "prod" }
}

Inputs

NameTypeDefaultDescription
cluster_namestringCluster name; prefixes IAM roles, KMS alias, node groups (required)
subnet_idslist(string)Private subnets in 2+ AZs for control plane + nodes (required)
kubernetes_versionstringnull"1.NN" minor version; null = AWS default
endpoint_public_accessbooltruePublic API endpoint on/off (private endpoint always on)
endpoint_public_access_cidrslist(string)["0.0.0.0/0"]CIDRs allowed to the public endpoint
additional_security_group_idslist(string)[]Extra control-plane ENI security groups
authentication_modestring"API"API or API_AND_CONFIG_MAP
bootstrap_cluster_creator_admin_permissionsbooltrueAdmin access entry for the creating identity
upgrade_support_typestring"STANDARD"STANDARD or EXTENDED upgrade policy
enabled_log_typeslist(string)["api","audit","authenticator"]Control-plane log types (empty disables)
log_retention_daysnumber90CloudWatch retention for control-plane logs
kms_key_arnstringnullBYO KMS key for secrets; null = create one
kms_key_deletion_window_in_daysnumber30Deletion window for the created key
node_groupsmap(object)one default groupManaged node groups (instance_types, capacity_type, ami_type, disk_size, sizes, labels, taints, subnet_ids)
addonsmap(object)coredns, kube-proxy, vpc-cni, eks-pod-identity-agentEKS add-ons (version, configuration_values, service_account_role_arn)
pod_identity_associationsmap(object){}namespace + service_account => role_arn
tagsmap(string){}Tags applied to all resources

Outputs

cluster_name, cluster_arn, cluster_endpoint, cluster_version, cluster_certificate_authority_data, cluster_security_group_id, oidc_issuer_url, cluster_iam_role_arn, node_iam_role_arn, node_group_arns, kms_key_arn, addon_versions.

Requirements

  • Terraform or OpenTofu >= 1.6
  • AWS provider >= 6.0, < 7.0
  • An existing VPC with private subnets in at least two AZs (pair with the aws-vpc module)

Notes

  • Node group desired_size is ignored after creation so cluster-autoscaler or Karpenter can own live capacity.
  • Control plane costs $0.10/hr; expect ~15 min create and ~10 min destroy.
  • disk_size/ami_type are managed-node-group-native (no launch template). AL2023 AMIs enforce IMDSv2 by default.

Verification

Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.

License

Commercial — IaC Bazaar EULA. © IaC Bazaar. Original work (not derived from a third-party module).