AWS: EKS, RDS and platform services¶
The AWS deployment is split into four roots. Networking and the database live outside Kubernetes; the web and rest services run on EKS. The load balancer controller translates the application's Ingress into an ALB. That ALB is created indirectly by the controller, rather than declared as an aws_lb resource in the Terraform roots.
Networking and traffic¶
aws/network consumes terraform-aws-modules/vpc/aws with the ~> 5.0 constraint. It selects as many availability zones as there are private subnet entries, taking the first available zones returned by AWS.
| Setting | Versioned default | Consequence |
|---|---|---|
| Region | eu-west-1 |
All AWS roots must agree |
| Base name | gitlab-terraform-eks |
Does not automatically include ENVIRONMENT |
| VPC | 10.0.0.0/16 |
Private network for the AWS implementation |
| Private subnets | 10.0.1.0/24, 10.0.2.0/24, 10.0.3.0/24 |
EKS nodes and the RDS subnet group |
| Public subnets | 10.0.4.0/24, 10.0.5.0/24, 10.0.6.0/24 |
Public module resources and ALB subnet discovery |
| NAT | Enabled; one NAT Gateway | Shared egress for private subnets |
| DNS | Hostnames and DNS support enabled | Internal resolution and managed endpoints |
Public subnets have kubernetes.io/role/elb=1; private ones have kubernetes.io/role/internal-elb=1. These tags let the controller discover load balancer subnets. They do not themselves expose an application: the Ingress requests the external load balancer.
A single NAT reduces the number of gateways but concentrates egress and can create cross-zone traffic. It should not be described as a highly available egress strategy. The thesis explains the choice of small compute sizes for the demonstration (§7.2.7, printed page 44 / PDF 50); it does not explicitly attribute every availability tradeoff to the author.
EKS and its identities¶
aws/kubernetes consumes terraform-aws-modules/eks/aws (~> 20.0) and network outputs. It configures:
- Cluster name
gitlab-terraform-eksand Kubernetes version1.31. - Nodes in private subnets.
- Public API access enabled, with allowed CIDRs
0.0.0.0/0. - Administrative permissions for the cluster creator identity.
- One
defaultmanaged node group:t3.small, desired 1, minimum 1, maximum 3. - A 33% unavailability limit during node group updates.
- IRSA and the
aws-ebs-csi-driveradd-on.
Version 1.31 is the value in the source, not a version recommendation for a new deployment. Before rebuilding the lab, check that version's availability and support in the target region, and update the configuration through a reviewed change where necessary.
The node group's 1–3 limits do not establish automatic scaling based on load or pending pods. No Cluster Autoscaler or Karpenter is declared. AWS distinguishes capacity settings from mechanisms that adjust capacity in response to workloads; see EKS autoscaling.
EBS CSI through IRSA¶
The AmazonEKSTFEBSCSIRole-<cluster> role is created with IAM module 5.39.0, trusts the cluster's OIDC identity and restricts the subject to system:serviceaccount:kube-system:ebs-csi-controller-sa. It receives the managed AmazonEBSCSIDriverPolicy; the add-on receives that role's ARN.
The association is with the controller service account, not a blanket grant of that policy to every node role. The driver enables storage capability: the reviewed demonstration manifests declare no PVC for web or rest, since data lives in RDS.
RDS MySQL¶
The database layer consumes the VPC and subnets from network, and the node security group from kubernetes through the eks state alias.
| Setting | Source value |
|---|---|
| Engine | MySQL 8.0 |
| Instance class | db.t4g.micro |
| Storage | gp3, initially 20 GiB, maximum 100 GiB |
| Database and port | restdb, TCP 3306 |
| Initial user | restuser; required sensitive password |
| Exposure | publicly_accessible=false |
| Availability | multi_az=false |
| Backups | 1-day automated backup retention |
| Deletion protection | Disabled |
| Final snapshot | Skipped by default |
| Change application | apply_immediately=true |
The RDS security group accepts MySQL from the EKS node security group and permits general outbound traffic. This provides a network boundary between the database and clients, but does not replace SQL user authorization or pod-level network policy.
Outputs expose host, port, database, sensitive username, security IDs and JDBC URL. The password is supplied as an input and participates in state; sensitive does not remove it from IaC persistence. See protecting state and plans.
Platform preparation¶
aws/platform requires the EKS API to be reachable from the runner. The Kubernetes and Helm providers execute aws eks get-token using the job's AWS identity, cluster name and region. This bootstrap path differs from subsequent application-pipeline access through the Agent.
| Resource | Purpose |
|---|---|
app namespace |
Hosts the demonstration workloads |
rest Secret |
REST_DB_HOST, REST_DB_PORT, REST_DB_DATABASE, REST_DB_USER, REST_DB_PASSWORD |
gitlab-agent namespace |
Hosts the agent |
gitlab-agent Helm release |
Uses the supplied KAS address and agent token |
| ALB controller service account | aws-load-balancer-controller in kube-system, annotated with its IRSA role |
| ALB controller IRSA role | IAM-module policy plus additional listener-attribute permissions |
| ALB controller Helm release | Uses cluster, region, VPC and the pre-created service account |
The additional policy allows elasticloadbalancing:DescribeListenerAttributes and elasticloadbalancing:ModifyListenerAttributes on *. Its existence is verified in source; the particular incident or reason for adding it cannot be established from the file and is not invented here.
Neither Helm release pins a chart version. The VPC/EKS modules use major-version constraints; IAM is pinned to 5.39.0. No provider lockfiles are versioned in the snapshot. These differences matter when reproducing the installation months later.
HTTP and TLS ingress¶
The Ingress belongs to web-application/deployments/frontend. It requests an internet-facing ALB, IP targets, 80/443 listeners and HTTPS redirection. It routes /api/v1 to rest:8080 and / to web:8080.
The manifest contains a domain and a concrete ACM ARN from the original deployment. A replica requires a valid certificate in the target region and DNS pointing to the generated load balancer. Neither certificate nor DNS is provisioned by the inspected roots. Replacing these values is an adaptation prerequisite, not an operation performed by the documentation pipeline.
Acceptance checks¶
After creation, check each layer: coherent networking outputs; Ready nodes; available RDS reachable by the application; connected agent; available ALB controller; and a rest secret with expected keys, without printing its values. After application deployment, check the HTTPS endpoint, API routing and database connection. A successful apply_platform alone does not establish these functional outcomes.
For variables and credentials, see the reference. To retire the environment while preserving necessary data, see teardown.
Sources¶
- Networking and VPC module, network variables.
- EKS, EKS variables, EBS IRSA.
- RDS, RDS defaults, outputs.
- Platform providers, Secret, Agent, ALB controller, additional IAM policy.
- Application Ingress, commit 38ef821c.
- Thesis §7.2.7, printed pages 43–47 (PDF 49–53). The IRSA/node distinction and scaling boundaries are clarified from the source code.