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.