⚠️ Note: This module has been revamped and currently supports EC2 managed node groups only. Fargate and AutoMode support are not available in this version.
A Terraform module for creating and managing Amazon EKS (Elastic Kubernetes Service) clusters with EC2 managed node groups.
- EC2 Managed Node Groups: Full support with customizable launch templates and auto-scaling
- Dual-Stack Support: IPv4 and IPv6 cluster support (IPv6 service CIDR auto-assigned by AWS)
- Modern EKS Access Entries: Native EKS authentication via access entries (no aws-auth ConfigMap)
- IRSA Support: OIDC provider setup for IAM Roles for Service Accounts
- EKS Addons: Flexible addon configuration (CoreDNS, VPC CNI, Kube-proxy, Pod Identity Agent, EBS CSI Driver)
- EKS Capabilities: Support for ACK, KRO, and ArgoCD capabilities
- AWS Load Balancer Controller: Optional IAM role creation for AWS Load Balancer Controller (IRSA)
- Security: KMS encryption, IMDSv2 enforcement, security groups
- CloudWatch Log Group: Optional log group for EKS control plane logs; set
cloudwatch_log_group_force_destroy = trueto allow the log group to be deleted onterraform destroy(default is to protect it).
| Name | Version |
|---|---|
| terraform | >= 1.6.0 |
| aws | >= 6.0 |
| kubernetes | ~> 2.30 |
| helm | ~> 2.13 |
| tls | ~> 4.0 |
module "eks" {
source = "tfstack/eks-basic/aws"
name = "my-eks-cluster"
kubernetes_version = "1.35"
vpc_id = "vpc-12345678"
subnet_ids = ["subnet-12345678", "subnet-87654321"]
endpoint_public_access = true
# Configure access entries for cluster access
access_entries = {
admin = {
principal_arn = "arn:aws:iam::123456789012:role/admin-role"
type = "STANDARD"
policy_associations = {
admin = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope = {
type = "cluster"
}
}
}
}
}
# Configure EKS addons
addons = {
coredns = {
addon_version = "v1.13.2-eksbuild.1"
}
kube-proxy = {
addon_version = "v1.35.0-eksbuild.2"
}
vpc-cni = {
before_compute = true
addon_version = "v1.21.1-eksbuild.3"
}
eks-pod-identity-agent = {
before_compute = true
addon_version = "v1.3.10-eksbuild.2"
}
}
# Configure managed node groups
eks_managed_node_groups = {
default = {
name = "node-group-1"
ami_type = "AL2023_x86_64_STANDARD"
instance_types = ["t3.medium"]
min_size = 1
max_size = 3
desired_size = 2
disk_size = 20
}
}
tags = {
Environment = "production"
ManagedBy = "terraform"
}
}- examples/basic - Basic EKS cluster with EC2 node groups
- examples/ebs-web-app - EKS cluster with node groups and VPC setup
- examples/eks-capabilities - Platform engineering example with EKS capabilities
| Name | Version |
|---|---|
| terraform | >= 1.6.0 |
| aws | >= 6.0 |
| helm | >= 2.13 |
| kubernetes | >= 2.30 |
| tls | >= 4.0 |
| Name | Version |
|---|---|
| aws | 6.28.0 |
| time | 0.13.1 |
| tls | 4.1.0 |
No modules.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| access_entries | Map of access entries to add to the cluster | map(object({ |
{} |
no |
| addons | Map of EKS addons to enable | map(object({ |
{} |
no |
| capabilities | Map of EKS capabilities to enable. Valid keys: ack, kro, argocd | map(object({ |
{} |
no |
| cloudwatch_log_group_class | Specifies the log class of the log group. Valid values are: STANDARD or INFREQUENT_ACCESS | string |
null |
no |
| cloudwatch_log_group_force_destroy | When true, allow the CloudWatch log group to be deleted on terraform destroy. When false, protect it with lifecycle { prevent_destroy = true }. | bool |
false |
no |
| cloudwatch_log_group_kms_key_id | The ARN of the KMS Key to use when encrypting log data | string |
null |
no |
| cloudwatch_log_group_retention_in_days | Number of days to retain log events in the CloudWatch log group | number |
14 |
no |
| cloudwatch_log_group_tags | Additional tags to apply to the CloudWatch log group | map(string) |
{} |
no |
| cluster_authentication_mode | Authentication mode for the EKS cluster. Valid values: CONFIG_MAP, API, API_AND_CONFIG_MAP. Defaults to API_AND_CONFIG_MAP when capabilities are enabled, otherwise CONFIG_MAP. | string |
"API_AND_CONFIG_MAP" |
no |
| cluster_encryption_config_key_arn | ARN of the KMS key to use for encrypting Kubernetes secrets | string |
null |
no |
| cluster_encryption_config_resources | List of strings with resources to be encrypted. Valid values: secrets | list(string) |
[ |
no |
| cluster_ip_family | IP family for the EKS cluster. Valid values: ipv4, ipv6 | string |
"ipv4" |
no |
| create_cloudwatch_log_group | Whether to create a CloudWatch log group for EKS cluster logs | bool |
true |
no |
| create_kms_key | Controls if a KMS key for cluster encryption should be created | bool |
true |
no |
| eks_managed_node_groups | Map of EKS managed node group configurations | map(object({ |
{} |
no |
| enable_aws_load_balancer_controller | Whether to create IAM role for AWS Load Balancer Controller (IRSA) | bool |
false |
no |
| enable_cluster_creator_admin_permissions | Indicates whether or not to add the cluster creator (the identity used by Terraform) as an administrator via access entry | bool |
false |
no |
| enabled_cluster_log_types | List of control plane logging types to enable | list(string) |
[ |
no |
| endpoint_public_access | Whether the Amazon EKS public API server endpoint is enabled | bool |
true |
no |
| kubernetes_version | Kubernetes version to use for the EKS cluster | string |
n/a | yes |
| name | Name of the EKS cluster | string |
n/a | yes |
| public_access_cidrs | List of CIDR blocks that can access the Amazon EKS public API server endpoint | list(string) |
[ |
no |
| region | AWS region for CloudWatch log group | string |
"ap-southeast-2" |
no |
| service_ipv4_cidr | IPv4 CIDR block for Kubernetes services. Required for all clusters. Must not overlap with VPC CIDR. If not provided, EKS will auto-assign. | string |
null |
no |
| subnet_ids | Subnet IDs for EKS cluster control plane (should include both public and private) | list(string) |
n/a | yes |
| tags | Map of tags to apply to all resources | map(string) |
{} |
no |
| vpc_id | VPC ID where the cluster is deployed | string |
n/a | yes |
| Name | Description |
|---|---|
| access_entries | Map of access entries created and their attributes |
| access_policy_associations | Map of eks cluster access policy associations created and their attributes |
| aws_load_balancer_controller_role_arn | IAM role ARN for AWS Load Balancer Controller (when enabled) |
| cloudwatch_log_group_arn | Arn of cloudwatch log group created |
| cloudwatch_log_group_name | Name of cloudwatch log group created |
| cluster_addons | Map of attribute maps for all EKS cluster addons enabled |
| cluster_arn | The Amazon Resource Name (ARN) of the cluster |
| cluster_auth_token | Token to authenticate with the EKS cluster |
| cluster_ca_certificate | Decoded certificate data required to communicate with the cluster |
| cluster_certificate_authority_data | Base64 encoded certificate data required to communicate with the cluster |
| cluster_endpoint | Endpoint for your Kubernetes API server |
| cluster_iam_role_arn | Cluster IAM role ARN |
| cluster_iam_role_name | Cluster IAM role name |
| cluster_ip_family | The IP family used by the cluster (e.g. ipv4 or ipv6) |
| cluster_name | The name of the EKS cluster |
| cluster_oidc_issuer_url | The URL on the EKS cluster for the OpenID Connect identity provider |
| cluster_platform_version | Platform version for the cluster |
| cluster_primary_security_group_id | Cluster security group that was created by Amazon EKS for the cluster |
| cluster_security_group_id | ID of the cluster security group |
| cluster_service_cidr | The IPv4 CIDR block where Kubernetes pod and service IP addresses are assigned from |
| cluster_service_ipv6_cidr | The IPv6 CIDR block where Kubernetes pod and service IP addresses are assigned from (when ip_family is ipv6) |
| cluster_version | The Kubernetes version for the cluster |
| eks_managed_node_groups | Map of attribute maps for all EKS managed node groups created |
| kms_key_arn | The Amazon Resource Name (ARN) of the key |
| kms_key_id | The globally unique identifier for the key |
| launch_templates | Map of launch templates created for node groups |
| node_iam_role_arn | Node IAM role ARN |
| node_iam_role_name | Node IAM role name |
| node_security_group_id | ID of the node shared security group |
| oidc_provider | The OpenID Connect identity provider (issuer URL without leading https://) |
| oidc_provider_arn | The ARN of the OIDC Provider |
After the cluster is created, configure kubectl:
aws eks update-kubeconfig --name <cluster_name> --region <aws_region>Verify connection:
kubectl get nodesThe module includes comprehensive tests using Terraform's test framework. Run tests with:
terraform testterraform-aws-eks-basic/
├── main.tf # Core EKS cluster, node groups, addons, OIDC provider
├── access-entries.tf # EKS access entries for authentication
├── capabilities.tf # EKS Capabilities (ACK, KRO, ArgoCD)
├── capabilities-iam.tf # IAM roles for EKS Capabilities
├── addons-iam.tf # IAM roles for addons (EBS CSI, etc)
├── locals.tf # Local values and computed configurations
├── cluster-auth.tf # Cluster authentication data source
├── variables.tf # Input variables
├── outputs.tf # Output values
├── versions.tf # Provider version constraints
├── README.md # This file
└── examples/
├── basic/ # Basic usage example
├── ebs-web-app/ # Example with VPC and node groups
└── eks-capabilities/ # Platform engineering with capabilities
MIT License - see LICENSE file for details.