Chapter 14 of 24

EC2 Data Plane

Make workload placement visible through managed node groups, labels, taints, capacity types, and bounded updates.

01Learning objectives

02Four groups across three private-subnet AZs

This is the production intent, not an AWS guarantee of one node per AZ. Capacity, Kubernetes topology spread, and disruption policy complete the design.

03Placement matrix

GroupCapacityLabels and taintsWhy
systemOn-Demandworkload=system
dedicated=system:NO_SCHEDULE
Envoy, Argo CD, and platform agents need stable EC2 features.
application_on_demandOn-Demandworkload=application
lifecycle=on-demand
Baseline capacity for fault-intolerant services.
application_spotSpot, three instance typeslifecycle=spot:NO_SCHEDULEInterruptible workers opt in with a toleration.
CassandraOn-Demandworkload=cassandra
dedicated=cassandra:NO_SCHEDULE
StatefulSets and EBS-backed data avoid Spot interruption.

04Lab: compare learning and production

# Provider-mocked tests create no AWS resources.
terraform -chdir=learn-terraform/capstone/infra/modules/eks test
tofu -chdir=learn-terraform/capstone/infra/modules/eks test

# Inspect both profiles before any plan.
terraform fmt -check learn-terraform/capstone/infra/environments/learning/eks.tfvars
terraform fmt -check learn-terraform/capstone/infra/environments/production/eks.tfvars
tofu fmt -check learn-terraform/capstone/infra/environments/learning/eks.tfvars
tofu fmt -check learn-terraform/capstone/infra/environments/production/eks.tfvars

Learning keeps paid capacity small and Cassandra at zero desired nodes. Production makes a three-node floor visible for every group; applying it is outside this chapter.

05Read update behavior

  1. version = var.kubernetes_version makes every managed group follow the reviewed control-plane minor version instead of relying on the provider default.
  2. ami_type = AL2023_x86_64_STANDARD makes the OS family reviewable and enables drift detection for that choice.
  3. release_version = null lets EKS choose the latest compatible AMI only when the group is created. Terraform does not discover later recommended AMI releases while that input stays null. Set a reviewed release_version value in the selected tfvars, inspect the in-place node-group update, and roll it out during a maintenance window.
  4. Capacity type, subnet set, node role, and launch choices can replace a node group. Treat replacement as a migration.
  5. max_unavailable = 1 bounds a rolling update, but PodDisruptionBudgets still decide whether eviction succeeds.
  6. node_repair_config.enabled = true lets EKS replace unhealthy nodes; it does not repair application data.
  7. Spot uses multiple instance types to widen capacity pools. Design for interruption rather than assuming replacement arrives first.
  8. Terraform owns desired size in this phase. Chapter 16 will define autoscaler ownership without permanent plan drift.

!Failure drill

The plan changes Cassandra from On-Demand to Spot. Reject it. The replacement and interruption model do not preserve database availability or EBS attachment semantics. Restore dedicated On-Demand capacity, then review rack/AZ placement and backup readiness separately.

06Verify the contract

terraform -chdir=learn-terraform/capstone/infra/modules/eks test -filter=tests/eks.tftest.hcl
tofu -chdir=learn-terraform/capstone/infra/modules/eks test -filter=tests/eks.tftest.hcl

The assertions require four groups, private subnets, On-Demand system and Cassandra capacity, separate Spot application capacity, stable labels and taints, node repair, and bounded updates.

07Cleanup

No resources were created. Remove only temporary plans and copied working directories. After a future apply, drain workloads and remove dependent GitOps state before deleting a node group.

08Quick check

Does a label stop other pods from using the node?

No. A label attracts selected pods; a taint repels pods that lack a matching toleration.

Does three desired nodes guarantee one per AZ?

No. The group spans three subnets, but placement can be uneven. Topology spread and workload replicas complete availability.

09Recap and next

Managed groups turn resilience and cost choices into reviewable HCL: stable system capacity, two application lifecycles, and isolated Cassandra capacity.

Next: add Fargate for a narrow class of stateless worker pods while keeping system and stateful workloads on EC2.

10Source notes