27.7 EKS Blueprints: Opinionated Terraform and CDK Modules for EKS
Right, so you’ve decided you want an EKS cluster. Good for you. You’ve also decided you don’t want to spend the next three weeks hand-crafting Terraform or CloudFormation for the VPC, IAM roles, node groups, add-ons, and all the other fiddly bits that AWS requires. You’re smarter than that. This is where EKS Blueprints comes in—it’s a collection of opinionated, pre-packaged modules for Terraform and CDK that aims to get you from zero to a fully-functional, production-ready cluster in a shockingly small amount of code. It’s like a brilliant but stubborn architect who says, “Trust me, I’ve already made all the hard decisions for you.”
Now, the word “opinionated” is doing a lot of work here. The Blueprints team has made specific choices about security, networking, and add-on integration. You might not agree with all of them (and I’ll call out the weird ones), but they are almost always sane, well-considered defaults that beat the pants off whatever you’d frantically scribble down at 2 AM. The beauty is that while it gives you a solid foundation, it’s still wildly customizable. It’s a framework, not a prison.
The Core Concept: Composing Your Cluster
Think of EKS Blueprints not as a single monolithic module, but as a composer. You provide it a list of “add-ons” (like Karpenter, the AWS Load Balancer Controller, or Prometheus) and “teams” (how you map IAM users/roles to Kubernetes permissions), and it wires everything together with the correct IAM permissions and Helm charts. It handles the mind-numbing cross-stack references for you.
Here’s the Terraform main.tf that will get you a basic, usable cluster. This is the “hello world” that would take 20 files to do by hand.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "my-eks-vpc"
cidr = "10.0.0.0/16"
azs = ["us-west-2a", "us-west-2b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
single_nat_gateway = true # cheaper, but a SPOF. Fine for dev.
enable_dns_hostnames = true
}
module "eks_blueprints" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints?ref=v4.32.0"
cluster_name = "my-app-cluster"
cluster_version = "1.28"
vpc_id = module.vpc.vpc_id
private_subnet_ids = module.vpc.private_subnets
# This manages the control plane itself
managed_node_groups = {
mg_5 = {
node_group_name = "managed-ondemand"
instance_types = ["m5.large"]
min_size = 2
max_size = 5
desired_size = 2
subnet_ids = module.vpc.private_subnets
}
}
}
# This is the magic: adding essential components
module "kubernetes_addons" {
source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/kubernetes-addons?ref=v4.32.0"
eks_cluster_id = module.eks_blueprints.eks_cluster_id
# Let's be honest, you need these.
enable_aws_load_balancer_controller = true
enable_metrics_server = true
enable_cluster_autoscaler = true # Or use Karpenter instead (you should)
}
output "configure_kubectl" {
description = "Command to update your kubeconfig"
value = module.eks_blueprints.configure_kubectl
}
Run terraform apply, go get a coffee, and come back to a functioning cluster. It’s borderline witchcraft.
Why Karpenter is a Blueprint Best Friend
If you’re using the cluster_autoscaler in the example above, I’m judging you a little. It’s fine, but it’s the old guard. Karpenter is the new hotness, and Blueprints integrates it seamlessly. Karpenter doesn’t just scale node groups; it provisions the right nodes for pending pods on the fly. It’s faster, cheaper, and smarter. Using it via Blueprints means all the IAM permissions and Helm values are pre-configured.
# Inside your kubernetes-addons module block:
enable_karpenter = true
karpenter = {
# This is the cool part: Blueprints creates the IAM role for you
# and injects the cluster endpoint and name automatically.
# You just define the node class.
node_iam_role_additional_policies = {
AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
}
The best practice here is to let Blueprints handle the Karpenter infrastructure (the Provisioner/NodePool CRDs) and then use GitOps (like ArgoCD, which Blueprints also supports) to manage the actual workload-specific configurations. This separation of concerns is clean and maintainable.
The Rough Edges and Pitfalls
It’s not all rainbows and unicorns. The Blueprints framework is powerful, which means it’s complex.
- State Management is a Bear: This is Terraform 101, but it’s worth screaming about. You are now managing critical cluster infrastructure with Terraform. Your state file is literally the key to your kingdom. You must use remote state (S3 backend with DynamoDB locking) with strict access controls. Losing this state file means entering a world of pain.
- Version Upgrades Require Planning: Upgrading the Blueprints module version or your Kubernetes version is not something you do on a live cluster on a Friday afternoon. The Blueprints team does a good job with backwards compatibility, but always check the release notes. Test in a staging environment first. The upgrade path often involves a careful sequence of
terraform applysteps. - Debugging Can Be Opaque: When something fails—say, the CoreDNS add-on doesn’t deploy correctly—you’re debugging through layers of abstraction. You need to be comfortable reading the underlying Blueprints code to understand what Helm values it’s generating or what IAM policy it’s attaching. The error messages don’t always bubble up nicely.
- The “AWS Way” or the Highway: The designers’ choices are generally good, but they are very AWS-centric. For example, its integration with AWS Secrets and Configuration Provider (ASCP) is first-class. If you’re married to a different secrets management tool, you’ll be fighting the framework more than using it.
Despite these pitfalls, the alternative—managing all this by hand—is infinitely worse. EKS Blueprints embodies the DevOps principle of “automate the boring stuff.” It encodes best practices so you don’t have to rediscover them the hard way. Just treat it with the respect a powerful tool deserves: read the code, plan your changes, and for the love of all that is holy, back up your state.