Creating an Amazon EKS cluster with managed node groups using Terraform requires careful coordination of VPC networking, IAM roles, cluster configuration, and EC2 worker definitions. The reference implementations show two complementary patterns: a hands-on tutorial that builds a VPC with public and private subnets and places EKS nodes in private subnets, and the HashiCorp Terraform AWS EKS module that abstracts EKS managed node groups, authentication mode, and Auto Mode settings.
The architecture described in the tutorial uses a VPC with 2 public subnets and 2 private subnets in different Availability Zones. Each public subnet contains a NAT gateway that allows private subnets to access the Internet. The EKS nodes are created in the private subnets. The nodes are EC2 t3-micro instances managed by EKS.
VPC and Networking Foundation
EKS needs subnets across at least two availability zones. The tutorial builds the networking as part of the setup using a custom AWS VPC module.
The module is referenced as:
hcl
module "aws_vpc" {
source = "github.com/erozedguy/AWS-VPC-terraform-module.git"
networking = var.networking
security_groups = var.security_groups
}
The networking variable is defined as an object with the following attributes:
- cidr_block
- vpc_name
- azs
- public_subnets
- private_subnets
- nat_gateways
The default values used in the example are:
- cidr_block = "10.0.0.0/16"
- vpc_name = "terraform-vpc"
- azs = ["us-east-1a", "us-east-1b"]
- public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
- private_subnets = ["10.0.3.0/24", "10.0.4.0/24"]
- nat_gateways = true
The security_groups variable is a list of objects with name, description, and ingress. The default example defines an SSH security group:
hcl
variable "security_groups" {
type = list(object({
name = string
description = string
ingress = object({
description = string
protocol = string
from_port = number
to_port = number
cidr_blocks = list(string)
ipv6_cidr_blocks = list(string)
})
}))
default = [{
name = "ssh"
description = "Port 22"
ingress = {
description = "Allow SSH access"
protocol = "tcp"
from_port = 22
to_port = 22
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = null
}
}]
}
Kubernetes clusters managed by Amazon EKS make calls to other AWS services on your behalf to manage the resources that you use with the service.
The production guide notes that you need the AWS provider configured and a VPC with subnets ready. If you are starting from scratch, the VPC is built as part of this setup.
Terraform requirements from the guide:
hcl
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
Managed Node Groups Overview
Running Kubernetes on AWS means running EKS. If you want your worker nodes managed by AWS - patched, updated, and drained gracefully during upgrades - managed node groups are the way to go. They handle the EC2 lifecycle so you can focus on your workloads instead of babysitting instances.
The guide walks through building a production-ready EKS cluster with managed node groups in Terraform. It covers the VPC, IAM roles, the cluster itself, node groups with different instance types, and launch template customization.
The HashiCorp tutorial configures the cluster with three nodes across two node groups using the eks_managed_node_groups parameter.
hcl
eks_managed_node_groups = {
one = {
name = "node-group-1"
instance_types = ["t3.small"]
min_size = 1
max_size = 3
desired_size = 2
}
two = {
name = "node-group-2"
instance_types = ["t3.small"]
min_size = 1
max_size = 2
desired_size = 1
}
}
Node Group Configuration Patterns
The module example shows a single managed node group with explicit AMI and instance type settings.
hcl
eks_managed_node_groups = {
example = {
ami_type = "AL2023_x86_64_STANDARD"
instance_types = ["m5.xlarge"]
min_size = 2
max_size = 10
desired_size = 2
}
}
Starting on 1.30, AL2023 is the default AMI type for EKS managed node groups.
Tags are applied at the module level:
hcl
tags = {
Environment = "dev"
Terraform = "true"
}
When enabling authentication_mode = "API_AND_CONFIG_MAP", EKS will automatically create an access entry for the IAM role(s) used by managed node group(s) and Fargate profile(s).
The following table summarizes node group examples from the reference facts:
| Example | Node Group Name | Instance Types | Min Size | Max Size | Desired Size | AMI Type |
|---|---|---|---|---|---|---|
| Tutorial one | node-group-1 | t3.small | 1 | 3 | 2 | not specified |
| Tutorial two | node-group-2 | t3.small | 1 | 2 | 1 | not specified |
| Module example | example | m5.xlarge | 2 | 10 | 2 | AL2023x8664_STANDARD |
The VPC subnet example for the module shows:
| Subnet ID | Type |
|---|---|
| subnet-xyzde987 | - |
| subnet-slkjf456 | - |
| subnet-qeiru789 | - |
Terraform Module Parameters
The Terraform AWS EKS module creates Amazon EKS resources. Relevant module parameters documented in the reference include:
eks_managed_node_groups| Map of EKS managed node group definitions to create | map(object({ | null | noenable_auto_mode_custom_tags| Determines whether to enable permissions for custom tags resources created by EKS Auto Mode | bool | true | noenable_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 | noenable_irsa| Determines whether to create an OpenID Connect Provider for EKS to enable IRSA | bool | true | noenable_kms_key_rotation| Specifies whether key rotation is enabled | bool | true | noenabled_log_types| A list of the desired control plane logs to enable
Additional module notes cover Compute Resources, User Data, Network Connectivity, Upgrade Guides, and Frequently Asked Questions.
Caution regarding EKS Auto Mode:
Due to the current EKS Auto Mode API, to disable EKS Auto Mode you will have to explicitly set:
hcl
compute_config = {
enabled = false
}
If you try to disable by simply removing the compute_config block, this will fail to disable EKS Auto Mode.
HCP Terraform Integration and Workflow
The HashiCorp tutorial integrates with HCP Terraform.
Set the TFCLOUDORGANIZATION environment variable to your HCP Terraform organization name. This will configure your HCP Terraform integration.
bash
export TF_CLOUD_ORGANIZATION=
Initialize your configuration. Terraform will automatically create the learn-terraform-eks workspace in your HCP Terraform organization.
bash
terraform init
Output includes:
Initializing HCP Terraform...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Installing hashicorp/aws v5.7.0...
- Installed hashicorp/aws v5.7.0 (signed by HashiCorp)
HCP Terraform has been successfully initialized!
You may now begin working with HCP Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure.
If you ever set or change modules or Terraform Settings, run "terraform init" again to reinitialize your working directory.
Run terraform apply to create your cluster and other necessary resources.
Confirm the operation with a yes.
This process can take up to 10 minutes.
Production Considerations
The production guide emphasizes building a production-ready EKS cluster with managed node groups in Terraform. The workflow covers:
- VPC construction with at least two availability zones
- IAM roles for the cluster and node groups
- Cluster creation with authentication mode options
- Node groups with different instance types
- Launch template customization
Managed node groups handle EC2 lifecycle tasks including patching, updating, and graceful draining during upgrades. This reduces operational burden compared to self-managed node groups.
The tutorial repository for the custom VPC and EKS approach is:
GITHUB repository: https://github.com/erozedguy/Terraform-EKS-Cluster-with-Node-Group
AWS VPC module: https://github.com/erozedguy/AWS-VPC-terraform-module
The architecture places nodes in private subnets behind NAT gateways in public subnets, which provides outbound internet access for package updates while keeping worker instances isolated from direct internet ingress.
Conclusion
EKS node group configuration in Terraform centers on defining networking, IAM, and managed node group specifications that align with operational requirements. The reference implementations demonstrate a custom module approach with explicit VPC, subnet, and NAT gateway creation using a 10.0.0.0/16 CIDR with public subnets 10.0.1.0/24 and 10.0.2.0/24 and private subnets 10.0.3.0/24 and 10.0.4.0/24 across us-east-1a and us-east-1b, and a module-based approach using eks_managed_node_groups with instance types such as t3.small and m5.xlarge, sizing parameters minsize, maxsize, desiredsize, and AMI type AL2023x8664STANDARD.
Both patterns support production use. The custom VPC module gives fine-grained control over security groups and NAT configuration for t3-micro nodes in private subnets. The Terraform AWS EKS module provides standardized parameters for authenticationmode, Auto Mode computeconfig, IRSA, KMS key rotation, and tagging. HCP Terraform integration streamlines workspace creation and provider initialization with hashicorp/aws v5.7.0. Combined, these practices enable repeatable, managed EKS node groups with AWS handling node lifecycle while Terraform codifies infrastructure state.