terraform-aws-eks
repository·master·Indexed 26 days ago
https://github.com/terraform-aws-modules/terraform-aws-eksA comprehensive Terraform module for provisioning and managing Amazon EKS (Elastic Kubernetes Service) infrastructure, including control planes, compute resources, and networking. It includes specialized modules for EKS managed node groups, user data rendering for various AMI types (AL2, AL2023, Bottlerocket), and EKS capabilities such as ACK, ArgoCD, and KRO.
What's inside terraform-aws-eks
- This Terraform module automates the creation and management of Amazon EKS (Kubernetes) resources on AWS. It provides a high-level abstraction for deploying EKS clusters, managing compute resources (such as managed node groups or Fargate profiles), and configuring network connectivity.
Migrate EKS Managed Node Groups from v18.x to v19.x
masterIn
v19.x, the default security group created by EKS managed node groups has been removed. To upgrade while still usingv18.xof the module:- Identify Usage: If you are using the default security group, create a new security group with the same rules and add its ID to
vpc_security_group_ids. - Disable Default SG: Set
create_security_group = falsein your node group definition oreks_managed_node_group_defaults. - Apply Changes: Apply the configuration. EKS managed node groups use a rolling update strategy (influenced by
update_config) to replace instances with new versions of the launch template that do not include the old security group.
Once the managed node group has cycled and the security group is no longer in use, you can upgrade the module version to
v19.x.- Identify Usage: If you are using the default security group, create a new security group with the same rules and add its ID to
Configure EKS Hybrid Nodes
masterEKS Hybrid Nodes allow running nodes on infrastructure outside of AWS (e.g., on-premises).
To set this up:
- Use the
eks_hybrid_node_rolemodule to create the necessary IAM role. - In the
eksmodule, defineaccess_entrieswithtype = "HYBRID_LINUX"using the hybrid node role ARN. - Configure
remote_network_configwithremote_node_networksandremote_pod_networks(the latter is required if running webhooks on Hybrid nodes). - Configure
security_group_additional_rulesto allow traffic from the remote network CIDRs.
locals { remote_network_cidr = "172.16.0.0/16" remote_node_cidr = cidrsubnet(local.remote_network_cidr, 2, 0) remote_pod_cidr = cidrsubnet(local.remote_network_cidr, 2, 1) } module "eks_hybrid_node_role" { source = "terraform-aws-modules/eks/aws//modules/hybrid-node-role" version = "~> 21.0" } module "eks" { source = "terraform-aws-modules/eks/aws" version = "~> 21.0" name = "example" kubernetes_version = "1.33" create_node_security_group = false security_group_additional_rules = { hybrid-all = { cidr_blocks = [local.remote_network_cidr] description = "Allow all traffic from remote node/pod network" from_port = 0 to_port = 0 protocol = "all" type = "ingress" } } compute_config = { enabled = true node_pools = ["system"] } access_entries = { hybrid-node-role = { principal_arn = module.eks_hybrid_node_role.arn type = "HYBRID_LINUX" } } vpc_id = "vpc-1234556abcdef" subnet_ids = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"] remote_network_config = { remote_node_networks = { cidrs = [local.remote_node_cidr] } remote_pod_networks = { cidrs = [local.remote_pod_cidr] } } }- Use the
Upgrade aws-auth ConfigMap to use Terraform Kubernetes Provider
masterStarting with v8.0.0, the
aws-authconfigmap in thekube-systemnamespace is managed via the Terraform Kubernetes provider instead ofkubectlvia null resources.To upgrade:
- Add the
kubernetesprovider to your Terraform configuration where you call the module. - Import the existing configmap into your Terraform state using the following command:
terraform import module.cluster1.kubernetes_config_map.aws_auth[0] kube-system/aws-authAlternatively, you can delete the
aws-authconfigmap before runningterraform apply, but you must perform the apply using the same user/role that created the cluster.- Add the
Migrate Self-Managed Node Groups from v18.x to v19.x
masterIn
v19.x, the default security group created by self-managed node groups has been removed. To upgrade without disruption, follow these steps while still usingv18.xof the module:- Identify Usage: If you are using the default security group, create a new security group with the same rules and add its ID to
vpc_security_group_ids. - Disable Default SG: Set
create_security_group = falsein your node group definition orself_managed_node_group_defaults. - Trigger Instance Refresh: Because changes to launch templates do not automatically cycle existing instances, you must add an
instance_refreshblock to force nodes to re-deploy. This ensures new instances launch without the old security group and old ones are terminated. - Safe Eviction: It is recommended to use
aws-node-termination-handlerto ensure pods are safely evicted during the refresh.
Once the node group has cycled and the security group is no longer attached to any instances, you can proceed to upgrade the module version to
v19.x.self_managed_node_group_defaults = { create_security_group = false instance_refresh = { strategy = "Rolling" preferences = { min_healthy_percentage = 66 } } }- Identify Usage: If you are using the default security group, create a new security group with the same rules and add its ID to
Requirements for EKS Hybrid Node Role Module
masterThe following versions are required to use this module:
- Terraform: >= 1.5.7
- AWS Provider: >= 6.52
Deploy a Self Managed Node Group
masterUse the
self-managed-node-groupmodule to create an Auto Scaling Group (ASG) for EKS, including the necessary IAM role, security group, and launch template.Important: If you are using this module outside of the main EKS module context, you MUST provide
vpc_security_group_idscontaining the cluster's security groups. Failure to do so will result in empty security groups on the nodes, preventing them from joining the cluster.module "self_managed_node_group" { source = "terraform-aws-modules/eks/aws//modules/self-managed-node-group" name = "separate-self-mng" cluster_name = "my-cluster" kubernetes_version = "1.31" cluster_endpoint = "https://012345678903AB2BAE5D1E0BFE0E2B50.gr7.us-east-1.eks.amazonaws.com" cluster_auth_base64 = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKbXFqQ1VqNGdGR2w3ZW5PeWthWnZ2RjROOTVOUEZCM2o0cGhVZUsrWGFtN2ZSQnZya0d6OGxKZmZEZWF2b2plTwpQK2xOZFlqdHZncmxCUEpYdHZIZmFzTzYxVzdIZmdWQ2EvamdRM2w3RmkvL1dpQmxFOG9oWUZkdWpjc0s1SXM2CnNkbk5KTTNYUWN2TysrSitkV09NT2ZlNzlsSWdncmdQLzgvRU9CYkw3eUY1aU1hS3lsb1RHL1V3TlhPUWt3ZUcKblBNcjdiUmdkQ1NCZTlXYXowOGdGRmlxV2FOditsTDhsODBTdFZLcWVNVlUxbjQyejVwOVpQRTd4T2l6L0xTNQpYV2lXWkVkT3pMN0xBWGVCS2gzdkhnczFxMkI2d1BKZnZnS1NzWllQRGFpZTloT1NNOUJkNFNPY3JrZTRYSVBOCkVvcXVhMlYrUDRlTWJEQzhMUkVWRDdCdVZDdWdMTldWOTBoL3VJUy9WU2VOcEdUOGVScE5DakszSjc2aFlsWm8KWjNGRG5QWUY0MWpWTHhiOXF0U1ROdEp6amYwWXBEYnFWci9xZzNmQWlxbVorMzd3YWM1eHlqMDZ4cmlaRUgzZgpUM002d2lCUEVHYVlGeWN5TmNYTk5aYW9DWDJVL0N1d2JsUHAKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==" subnet_ids = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"] // The following variables are necessary if you decide to use the module outside of the parent EKS module context. // Without it, the security groups of the nodes are empty and thus won't join the cluster. vpc_security_group_ids = [ module.eks.cluster_primary_security_group_id, module.eks.cluster_security_group_id, ] min_size = 1 max_size = 10 desired_size = 1 launch_template_name = "separate-self-mng" instance_type = "m5.large" tags = { Environment = "dev" Terraform = "true" } }Upgrade from v17.x to v18.x: Variable Renames
masterWhen upgrading from version 17.x to 18.x, several core variables have been renamed. Ensure your Terraform configuration is updated to use the new keys to avoid breaking changes.
Root Module Renames:
create_eks$\rightarrow$createsubnets$\rightarrow$subnet_idscluster_create_security_group$\rightarrow$create_cluster_security_groupcluster_log_retention_in_days$\rightarrow$cloudwatch_log_group_retention_in_dayscluster_log_kms_key_id$\rightarrow$cloudwatch_log_group_kms_key_idmanage_cluster_iam_resources$\rightarrow$create_iam_rolecluster_iam_role_name$\rightarrow$iam_role_namepermissions_boundary$\rightarrow$iam_role_permissions_boundaryiam_path$\rightarrow$iam_role_pathpre_userdata$\rightarrow$pre_bootstrap_user_dataadditional_userdata$\rightarrow$post_bootstrap_user_dataworker_groups$\rightarrow$self_managed_node_groupsworkers_group_defaults$\rightarrow$self_managed_node_group_defaultsnode_groups$\rightarrow$eks_managed_node_groupsnode_groups_defaults$\rightarrow$eks_managed_node_group_defaults
EKS Managed Node Group Sub-module Renames:
create_eks$\rightarrow$createworker_additional_security_group_ids$\rightarrow$vpc_security_group_ids
Fargate Profile Sub-module Renames:
fargate_pod_execution_role_name$\rightarrow$namecreate_fargate_pod_execution_role$\rightarrow$create_iam_rolesubnets$\rightarrow$subnet_idsiam_path$\rightarrow$iam_role_pathpermissions_boundary$\rightarrow$iam_role_permissions_boundary
Bootstrap Custom AMIs in EKS Managed Node Groups
masterWhen providing a custom
ami_id, the AWS EKS Managed Node Group service will not automatically inject the necessary bootstrap script. To resolve this, setenable_bootstrap_user_data = true. This allows the module to append the default bootstrap template to your user data. You can also usecloudinit_pre_nodeadmandcloudinit_post_nodeadmto inject additional configuration or scripts.eks_managed_node_groups = { custom_ami = { ami_id = "ami-0caf35bc73450c396" ami_type = "AL2023_x86_64_STANDARD" # Adds the bootstrap script back in using the module's template enable_bootstrap_user_data = true cloudinit_pre_nodeadm = [{ content = <<-EOT --- apiVersion: node.eks.aws/v1alpha1 kind: NodeConfig spec: kubelet: config: shutdownGracePeriod: 30s EOT content_type = "application/node.eks.aws" }] cloudinit_post_nodeadm = [{ content = <<-EOT echo "All done" EOT content_type = "text/x-shellscript; charset="us-ascii"" }] } }Migrate from EKS module v17.x to v18.x
masterWhen upgrading from version 17.x to 18.x, several configuration keys and structures have changed. Ensure you update your module calls to reflect the new naming conventions for networking, managed node groups, and self-managed node groups.
Key Changes:
Networking
- Rename
subnetstosubnet_ids.
EKS Managed Node Groups
- Rename
node_groups_defaultstoeks_managed_node_group_defaults. - Rename
node_groupstoeks_managed_node_groups. - Inside node group definitions:
- Rename
min_capacitytomin_size. - Rename
max_capacitytomax_size. - Rename
desired_capacitytodesired_size. - Rename
k8s_labelstolabels. - Rename
additional_tagstotags.
- Rename
Self-Managed Node Groups (formerly Worker Groups)
- The
worker_groups_launch_templatestructure has been replaced byself_managed_node_groups. - Use
self_managed_node_group_defaultsto set common settings likevpc_security_group_ids(replacesworker_additional_security_group_ids). - Inside
self_managed_node_groupsdefinitions:- Use
min_size,max_size, anddesired_size(replacesasg_max_size,asg_desired_capacity, etc.). - Use
bootstrap_extra_argsinstead ofkubelet_extra_args. - Use
instance_type(singular) instead ofinstance_types(plural) if defining a single type. - For mixed instance policies, use the
use_mixed_instances_policyandmixed_instances_policyblocks.
- Use
module "cluster_after" { source = "terraform-aws-modules/eks/aws" version = "~> 18.0" cluster_name = local.name cluster_version = local.cluster_version cluster_endpoint_private_access = true cluster_endpoint_public_access = true vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets eks_managed_node_group_defaults = { ami_type = "AL2_x86_64" disk_size = 50 } eks_managed_node_groups = { node_group = { min_size = 1 max_size = 10 desired_size = 1 instance_types = ["t3.large"] capacity_type = "SPOT" update_config = { max_unavailable_percentage = 50 } labels = { Environment = "test" } taints = [ { key = "dedicated" value = "gpuGroup" effect = "NO_SCHEDULE" } ] tags = { ExtraTag = "example" } } } self_managed_node_group_defaults = { vpc_security_group_ids = [aws_security_group.additional.id] } self_managed_node_groups = { worker_group = { name = "worker-group" min_size = 1 max_size = 5 desired_size = 2 instance_type = "m4.large" bootstrap_extra_args = "--kubelet-extra-args '--node-labels=node.kubernetes.io/lifecycle=spot'" } } fargate_profiles = { default = { name = "default" selectors = [{ namespace = "default" }] } } tags = { Environment = "test" } }- Rename
Use the aws-auth sub-module in v21.x
masterThe
aws-authsub-module has been removed inv21.x. If you require its functionality, you must either:- Pin your module source to a
v20.xversion (e.g.,~> v20.0). - Migrate to the new EKS access entry mechanism.
- Pin your module source to a
Requirements for EKS Managed Node Group Module
masterEnsure your environment meets the following version requirements before using the module:
- Terraform:
>= 1.5.7 - AWS Provider:
>= 6.52
- Terraform: