Skip to content
EgyKode
06 · KubernetesLab 36 / 59
Guided labterraform

Amazon EKS Cluster & Managed Node Group Provisioning

Provision the cluster everything else runs on, with worker nodes in private subnets and no public endpoint.

Time
31 min
Level
Intermediate
Objectives
4 objectives
Cost
Billable

Where this fits in the platform

Before you start

CostBillable

An EKS control plane is $0.10/hour (~$73/month) from the moment it exists, with no free tier — plus the node group's EC2 instances and any NAT Gateway. Budget a few dollars for an afternoon, and destroy the cluster the same day.

How to clean up

The scenario#

You have a network, roles and a registry. Nothing is running on any of it.

This is the cluster — and the two permission systems that catch everybody the first time, because they look like one.

Hands-on environment

Run it on AWS

This lab builds real cloud infrastructure, so it needs your own AWS account. Follow the cost and cleanup notes above — the resources are yours, and so is the bill.

Anything you tick here is your own record. EgyKode cannot see inside that terminal, so the success criteria stay self-assessed even when the environment checks your work for you.

The cluster

Step 1 of 5

What you are building#

text
   AWS manages this                     You manage this
  +-------------------------+          +--------------------------+
  |  EKS control plane      |          |  managed node group      |
  |  apiserver, etcd,       | <------> |  2 x t3.medium, private  |
  |  scheduler, controllers |          |  subnets, autoscaling    |
  |  across 3 AZs           |          |  to 6                    |
  +-------------------------+          +--------------------------+
        $0.10/hour                          EC2 pricing

EKS runs the control plane you built by hand in the kubeadm lab: the API server, etcd and the controllers, replicated across availability zones and patched by AWS. You do not get a node to log into, and you do not get to break etcd.

A managed node group is still EC2. AWS handles the launch template, the draining on upgrade and the replacement of an unhealthy instance, but the nodes are yours, they sit in your subnets, and they bill at normal EC2 rates.


Build it#

Two permission systems, not one#

This is the part worth slowing down for, because the error message is unhelpful.

text
IAM          ->  may you call the EKS API? (DescribeCluster, ListClusters)
EKS access   ->  may you call the KUBERNETES API? (get pods, create deploy)

update-kubeconfig only needs the first. It writes a file. Getting a kubeconfig therefore tells you nothing about whether kubectl will work, and the failure appears one command later as:

text
error: You must be logged in to the server (Unauthorized)

Grant the second explicitly:

Terminal
aws eks create-access-entry --cluster-name platform \
  --principal-arn arn:aws:iam::111122223333:role/deployer \
  --type STANDARD
 
aws eks associate-access-policy --cluster-name platform \
  --principal-arn arn:aws:iam::111122223333:role/deployer \
  --access-scope type=namespace,namespaces=production \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy

On clusters older than 1.23 this is the aws-auth ConfigMap instead — the same idea with a much worse failure mode, since a malformed edit locks everyone out including you.


Verify it worked#

DestructiveThis removes real resources. Check which environment you are in first.

Terminal
# Nodes are Ready, and in private subnets
kubectl get nodes -o wide
aws ec2 describe-instances --filters "Name=tag:eks:cluster-name,Values=platform" \
  --query 'Reservations[].Instances[].[InstanceId,PrivateIpAddress,PublicIpAddress]' --output table
# the PublicIpAddress column must be empty
 
# The OIDC provider exists and matches the cluster issuer
aws eks describe-cluster --name platform --query 'cluster.identity.oidc.issuer'
aws iam list-open-id-connect-providers
 
# Secrets are encrypted with your key
aws eks describe-cluster --name platform --query 'cluster.encryptionConfig'
 
# Something actually schedules
kubectl run smoke --image=nginx:alpine --restart=Never
kubectl wait --for=condition=Ready pod/smoke --timeout=90s && kubectl delete pod smoke

That last one is the real test. Nodes reporting Ready and a Pod actually running are different claims — a broken CNI gives you the first without the second.


Clean up#

DestructiveThis removes real resources. Check which environment you are in first.

Terminal
kubectl delete svc --all-namespaces --field-selector spec.type=LoadBalancer
kubectl delete ingress --all -A
terraform destroy -auto-approve
aws eks list-clusters

Cost of this lab: Billable. The EKS control plane is $0.10/hour (~$73/month) whether or not anything runs on it, plus two t3.medium nodes at about $0.08/hour together. Destroy it the moment you finish.

Success criteria

0 of 4

The concept behind it

Ready to try it without help?Do the challenge

Next up

Lab 36 of 59 on the project path

Application Routing with K8s Ingress & AWS Load Balancer ControllerLet a Kubernetes manifest provision a real AWS load balancer, and make the application reachable from the internet.Why next: An EKS cluster with workers in private subnets23 minIntermediateBillable — destroy resources when you finish

Previous: Core Kubernetes Workloads, ConfigMaps & Secrets