GitLab on EKS
A self-managed GitLab deployment on Kind-backed EKS using the upstream Helm chart with external stateful dependencies. GitLab connects to RDS PostgreSQL, ElastiCache Redis, five S3 buckets (LFS, artifacts, uploads, packages, backups), and SES for email. Kubernetes-native controllers (AWS Load Balancer Controller, ExternalDNS, External Secrets Operator) manage AWS resources from Ingress and ExternalSecret manifests.
Services
| Service | Role |
|---|---|
| EKS | Kind-backed cluster hosting GitLab components via Helm chart |
| EC2 | VPC networking, security groups |
| ELBv2 | ALB created by AWS Load Balancer Controller from Ingress resources |
| RDS | PostgreSQL 15 for GitLab application data, KMS encrypted |
| ElastiCache | Redis 7.0 for caching and Sidekiq queues |
| S3 | Five buckets: LFS objects, CI artifacts, uploads, packages, backups - all SSE-KMS |
| SESv2 | Email delivery for GitLab notifications |
| Route53 | Hosted zone with records managed by ExternalDNS |
| ACM | TLS certificate for HTTPS |
| KMS | Three keys: RDS, S3, EKS secrets encryption |
| IAM/STS | Six roles: cluster, node, pod, LB controller, ExternalDNS, CI/CD |
| Secrets Manager | Database credentials, admin credentials, Rails secret key |
| ECR | Container image repository |
| CodeCommit | Helm values and deployment overrides |
| CodeBuild | Helm template rendering and kubectl apply |
| CodePipeline | Deployment orchestration |
Architecture
Client --> Route53 --> ALB (HTTPS, ACM)
|
v
EKS Kind Cluster
┌──────────────────────────────────┐
│ GitLab components (Helm chart): │
│ webservice (Puma + Workhorse) │
│ sidekiq, gitaly, gitlab-shell │
│ migrations, toolbox │
└──────────────────────────────────┘
| | | | |
v v v v v
RDS Redis S3(5) SES Secrets
(PG15) (7.0) (buckets) (email) Manager
Controllers (IRSA):
AWS LB Controller --> creates ALB from Ingress
ExternalDNS --> creates Route53 records from Ingress
External Secrets --> syncs Secrets Manager --> K8s Secrets
The deployment follows the cloud-native pattern: no manual ALB or DNS creation. The AWS Load Balancer Controller watches Ingress resources and provisions the ALB automatically. ExternalDNS watches the same Ingress and creates Route53 ALIAS records. External Secrets Operator synchronizes Secrets Manager entries into Kubernetes Secrets that GitLab pods consume. All three controllers authenticate to AWS via IRSA.
What This Validates
- Large upstream Helm chart deployment (GitLab) on Kind-backed EKS
- Helm-based deployment driven by CI/CD (CodeBuild runs helm template + kubectl apply)
- AWS Load Balancer Controller creating ALB from Kubernetes Ingress annotations
- ExternalDNS creating Route53 records from Kubernetes Ingress annotations
- External Secrets Operator syncing Secrets Manager to Kubernetes Secrets
- IRSA with OIDC for three Kubernetes controllers (LB, DNS, Secrets)
- Five S3 buckets for GitLab object storage (LFS, artifacts, uploads, packages, backups)
- RDS PostgreSQL 15 and ElastiCache Redis 7.0 as external dependencies
- SES email delivery integration from a Kubernetes application
- Database migrations running as Kubernetes init containers
Test Coverage
Tests cover CI/CD pipeline execution, smoke checks for the web UI, version endpoint, and all backing services. Integration tests validate admin sign-in, project creation, repository operations, merge requests, file uploads to S3 object storage, and outbound email via SES. Security tests verify KMS encryption on RDS, S3, and EKS secrets, IAM role scoping, and Secrets Manager synchronization. Performance tests cover concurrent API operations.