Terraform AWS EKS Modules with GitHub Actions for Production Kubernetes

Deploying Amazon Elastic Kubernetes Service with Terraform and automating the pipeline through GitHub Actions combines declarative infrastructure with continuous delivery. The terraform-aws-eks module is a comprehensive Terraform module for provisioning and managing Amazon Elastic Kubernetes Service (EKS) clusters and their associated infrastructure. The module abstracts the complexity of EKS cluster creation by managing the EKS control plane, compute resources (node groups), IAM roles, security groups, network configuration, encryption, and cluster add-ons through a single, declarative configuration.

AWS Elastic Kubernetes Service (EKS) is a managed service that lets you deploy, manage, and scale containerized applications on Kubernetes. In this tutorial context, you will deploy an EKS cluster using Terraform. Then, you will configure kubectl using Terraform output and verify that your cluster is ready to use. While you could use the built-in AWS provisioning processes (UI, CLI, CloudFormation) for EKS clusters, Terraform provides you with several benefits:

Unified Workflow - If you already use Terraform to deploy AWS infrastructure, you can use the same workflow to deploy both EKS clusters and applications into those clusters.
Full Lifecycle Management - Terraform creates, updates, and deletes tracked resources without requiring you to inspect an API to identify those resources.
Graph of Relationships - Terraform determines and observes dependencies between resources. For example, if an AWS Kubernetes cluster needs a specific VPC and subnet configurations, Terraform will not attempt to create the cluster if it fails to provision the VPC and subnet first.

The tutorial assumes some basic familiarity with Kubernetes and kubectl but does not assume any pre-existing deployment. You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects.

Module Architecture and Core Files

This page covers the module's architecture, component relationships, and high-level configuration patterns. For specific topics, see the dedicated documentation.

The module is organized into a root module and several specialized sub-modules that handle specific aspects of EKS infrastructure:

Key Files:

main.tf
Creates awsekscluster resource, IAM roles, security groups, OIDC provider, and add-ons

variables.tf
Defines all module input variables including cluster configuration, node group definitions, and IAM settings

outputs.tf
Exposes cluster attributes, endpoints, security group IDs, and IAM role ARNs

node_groups.tf
Orchestrates the creation of compute resources by invoking sub-modules

The root module provisions the following primary resources:

Resource Type Terraform Resource Purpose
EKS Cluster awsekscluster.this Kubernetes control plane
CloudWatch Log Group awscloudwatchlog_group.this Control plane logs
IAM Role (Cluster) awsiamrole.this Control plane permissions
IAM Role (Auto Mode) awsiamrole.eks_auto EKS Auto Mode node permissions
OIDC Provider awsiamopenidconnectprovider.oidc_provider IRSA (IAM Roles for Service Accounts)
Security Groups awssecuritygroup.cluster

This structure makes the module suitable for both greenfield deployments and incremental adoption in existing accounts.

State Management and Remote Backend

Production Terraform workflows require remote state with locking and encryption. Store Terraform state in S3 with DynamoDB locking.

hcl terraform { backend "s3" { bucket = "terraform-state-bucket" key = "eks/terraform.tfstate" region = "us-west-2" dynamodb_table = "terraform-state-lock" encrypt = true use_lockfile = true } }

The backend configuration uses bucket terraform-state-bucket, key eks/terraform.tfstate, region us-west-2, dynamodbtable terraform-state-lock, encrypt true, uselockfile true. The dynamodb_table ensures concurrent runs cannot corrupt state and encryption protects secrets stored in state.

Modular Organization for Maintainability

Breaking the configuration into modules improves maintainability and enables reuse across environments.

```hcl
module "vpc" {
source = "./modules/vpc"
# VPC configuration parameters
}

module "eks" {
source = "./modules/eks"
# EKS configuration parameters
vpcid = module.vpc.vpcid
subnetids = module.vpc.privatesubnet_ids
}
```

The VPC module outputs network identifiers that feed directly into the EKS module inputs. This explicit dependency graph prevents the cluster creation from attempting to start before the network exists.

EKS Blueprints Add-Ons and ArgoCD Deployment

The terraform-aws-eks module manages core control plane resources. For add-ons, the AWS EKS Blueprints framework provides composable modules.

Deploy ArgoCD using the EKS Blueprints framework:

hcl module "kubernetes_addons" { source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/kubernetes-addons" eks_cluster_id = module.eks_blueprints.eks_cluster_id enable_argocd = true enable_metrics_server = true enable_cluster_autoscaler = true enable_aws_load_balancer_controller = true argocd_helm_config = { values = [templatefile("${path.module}/values.yaml", {})] } }

The configuration enables ArgoCD, metrics server, cluster autoscaler, and AWS Load Balancer Controller as Helm-managed add-ons. The eks_cluster_id ties the add-on lifecycle to the cluster.

Automatic Scaling Based on Resource Utilization

Node groups can be scaled automatically using Target Tracking policies.

hcl resource "aws_autoscaling_policy" "cluster_autoscaling" { name = "eks-cluster-autoscaling" policy_type = "TargetTrackingScaling" target_tracking_configuration { target_value = 75.0 predefined_metric_specification { predefined_metric_type = "ASGAverageCPUUtilization" } } autoscaling_group_name = aws_eks_node_group.main.resources[0].autoscaling_groups[0].name }

The policy targets 75.0 percent average CPU utilization across the Auto Scaling group backing the node group. The module exposes the autoscaling group name through computed references.

GitHub Actions CI/CD for Terraform EKS

Automating EKS with GitHub Actions is a reliable way to manage your new cluster. The workflow separates plan on pull requests from apply on main.

Create a workflow file in .github/workflows to define the deployment process:

yaml name: Terraform AWS Workflow on: pull_request: branches: [ main ] push: branches: [ main ] jobs: terraform: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - uses: actions/checkout@v3 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: arn:aws:iam::123456789012:role/github-actions aws-region: us-west-2 - name: Setup Terraform uses: hashicorp/setup-terraform@v3 - name: Terraform Init run: terraform init - name: Terraform Plan if: github.event_name == 'pull_request' run: terraform plan -no-color - name: Terraform Apply if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: terraform apply -auto-approve

The workflow runs on ubuntu-latest with id-token write and contents read permissions. AWS credentials are assumed via role-to-assume arn:aws:iam::123456789012:role/github-actions in aws-region us-west-2. Terraform is set up with hashicorp/setup-terraform@v3. Init always runs. Plan runs only on pullrequest. Apply runs only when github.ref == 'refs/heads/main' && github.eventname == 'push'.

This pattern provides peer review via plan output and automated promotion to production.

Integration Patterns and Workflow Considerations

When using the terraform-aws-eks module with GitHub Actions, several operational patterns emerge.

State isolation per environment is achieved by using distinct backend key paths, e.g., eks/dev/terraform.tfstate and eks/prod/terraform.tfstate while sharing the same bucket and lock table.

Variable management can be handled via GitHub Actions secrets for AWS credentials and Terraform Cloud variables for module inputs. The module's variables.tf defines all module input variables including cluster configuration, node group definitions, and IAM settings, making it straightforward to map secrets to inputs.

Add-on upgrades are decoupled from control plane changes. The kubernetes_addons module allows independent enable/disable flags for ArgoCD, metrics server, cluster autoscaler, and AWS load balancer controller without touching node group definitions.

Scaling policies reference computed autoscaling group names from awseksnodegroup.main.resources[0].autoscalinggroups[0].name, which requires a dependency on the node group creation. Terraform's graph of relationships ensures correct ordering.

Operational Best Practices

The module abstracts complexity but does not replace architectural decisions. Network configuration should place the control plane in private subnets with public endpoint access disabled for hardening. Encryption settings should be enforced for secrets and logs. IAM roles should follow least privilege and be versioned alongside code.

For CI/CD, the workflow shown uses actions/checkout@v3 and aws-actions/configure-aws-credentials@v2. Using OpenID Connect for role assumption avoids long-lived credentials. Terraform init with -backend-config can be used to avoid hardcoding backend details in code.

The combination of Terraform AWS EKS modules and GitHub Actions provides a repeatable, auditable path from pull request to production Kubernetes cluster.

Conclusion

The terraform-aws-eks module delivers a complete, declarative model for EKS clusters including control plane, IAM, security groups, OIDC provider, and CloudWatch logging. Pairing it with modular VPC definitions, S3/DynamoDB state, EKS Blueprints add-ons for ArgoCD and autoscaling, and a GitHub Actions workflow that plans on pull_request and applies on push to main creates a production-grade delivery pipeline for Kubernetes on AWS. The architecture supports full lifecycle management, dependency graph enforcement, and unified workflow for infrastructure and platform teams. This approach scales from single cluster experiments to multi-account, multi-environment platforms while maintaining auditability and repeatability.

Sources

  1. DeepWiki Terraform AWS EKS
  2. Dev.to Terrateam Deploying AWS EKS
  3. Terrateam Blog Deploying AWS EKS Cluster
  4. HashiCorp Terraform EKS Tutorial
  5. Terraform AWS Modules GitHub

Related Posts