ALB Patterns¶
CWIQ.IO uses internet-facing Application Load Balancers for services that require public HTTPS access. Currently deployed for GitLab (shared-services) and Authentik (NLB). Most other services are accessible only via Tailscale.
GitLab ALB (shared-gitlab-alb)¶
The GitLab ALB is the primary example of the CWIQ.IO ALB pattern.
Architecture¶
Internet
│
▼
AWS ALB (internet-facing, public subnets 10.0.1.x, 10.0.2.x)
│ HTTPS:443 — SSL terminated at ALB (ACM certificate)
│ HTTP:80 — redirected to HTTPS (HTTP 301)
▼
GitLab EC2 (private subnet 10.0.10.64/26)
Port 80 (HTTP — ALB handles TLS)
├── monitoring_whitelist: 10.0.0.0/8 (required for ALB health checks)
└── Puma boot time: ~70 seconds (ALB returns 503 during startup)
ALB Configuration¶
| Attribute | Value |
|---|---|
| Name | shared-gitlab-alb |
| Scheme | internet-facing (public) |
| Subnets | 10.0.1.0/24 (us-west-2a), 10.0.2.0/24 (us-west-2b) — public subnets |
| SSL Policy | ELBSecurityPolicy-TLS13-1-2-2021-06 |
| Certificate | Imported from Let's Encrypt via cert-server → ACM |
| Session Stickiness | lb_cookie, 24 hours (required for Authentik SSO OAuth flows) |
Target Group¶
| Attribute | Value |
|---|---|
| Target Port | 80 (HTTP — ALB does SSL termination) |
| Health Check Path | /-/health |
| Health Check Protocol | HTTP |
| Healthy Threshold | 2 |
| Unhealthy Threshold | 3 |
| Interval | 30 seconds |
| Deregistration Delay | 30 seconds |
Listeners¶
| Listener | Port | Action |
|---|---|---|
| HTTPS | 443 | Forward to shared-gitlab-tg |
| HTTP | 80 | Redirect to HTTPS (301) |
GitLab Pages Routing (wiki.shared.cwiq.io)¶
GitLab Pages are served at wiki.shared.cwiq.io using hostname-based routing on the same ALB:
| Attribute | Value |
|---|---|
| Certificate | Separate ACM cert for wiki.shared.cwiq.io (attached via SNI) |
| Listener Rule | Host header = wiki.shared.cwiq.io → forward to pages target group |
| Pages Target Port | 8090 (GitLab Pages daemon) |
| Rule Priority | 10 (evaluated before default rule) |
This allows a single ALB to serve both gitlab.shared.cwiq.io (main app, port 80) and wiki.shared.cwiq.io (Pages, port 8090) with separate SSL certificates via SNI.
SSL Certificate Management for ALBs¶
ALB certificates must be in ACM (AWS Certificate Manager). CWIQ.IO uses Let's Encrypt certificates managed by the cert-server playbook:
- cert-server renews Let's Encrypt cert for the domain
cert-server/acm-import.ymlimports the cert to ACM in us-west-2- Terraform references the ACM certificate ARN or uses a data source lookup by domain
# Import cert to ACM (run from ansible server)
ansible-playbook acm-import.yml -e "cert_domain=gitlab.shared.cwiq.io"
Health Check Considerations¶
GitLab monitoring_whitelist
GitLab's monitoring_whitelist must include 10.0.0.0/8 to allow ALB health checks from the ALB's private IPs. Without this, the ALB target shows unhealthy even when GitLab is running.
GitLab Puma boot time
GitLab Puma takes ~67-70 seconds to boot. The ALB health check will return 503 during this window. If 503 persists beyond 2 minutes after container start, check target health:
When to Use an ALB vs Tailscale-Only Access¶
| Service Type | Access Pattern | Why |
|---|---|---|
| GitLab | Public ALB | External developers, CI integrations, webhooks from GitHub/etc. |
| Authentik | Internal NLB | Apps redirect to SSO; accessed via Tailscale subnet router (SNAT) |
| Nexus | Tailscale-only | Internal artifact registry; CI runners reach via VPC peering |
| Grafana | Tailscale-only | Operations team only, no public exposure needed |
| Vault | Tailscale-only | Secrets must not be internet-accessible |
| SonarQube | Tailscale + VPC peering | CI runners (EKS pods) use VPC private IP; humans use Tailscale |
Terraform Source¶
terraform-plan/organization/environments/shared-services/ec2-instances/gitlab/
├── alb.tf ← ALB, target groups, listeners, Pages routing, SNI certs
├── route53.tf ← Alias records pointing to ALB DNS name
└── variables.tf ← alb_cert_arn, alb_cert_domain, gitlab_pages_enabled, etc.
Related Pages¶
- Security Groups — ALB SG and app SG configuration
- Route53 DNS — Alias records for ALB
- SSL Architecture — cert-server and ACM import workflow