GitHub-Centric
Infrastructure Modernisation

Replace Jenkins + SonarQube with a fully GitHub-native CI/CD platform. Production stays on AWS, dev/staging moves to Hetzner VPS. Deterministic infrastructure, promotion governance, auditability, cost discipline.

~$80+
Monthly savings
0
Stored AWS credentials
4
Promotion tiers
1
Control plane
Eliminates

Jenkins Server

No more server maintenance, plugin updates, or credential management

Eliminates

SonarQube Server

Replaced by CodeQL, PHPStan, Codecov — all free, zero infrastructure

Gains

OIDC Auth

Ephemeral AWS credentials via GitHub OIDC. No static keys anywhere

Gains

Terraform IaC

Production infrastructure as code. Auditable, reproducible, drift-free

Before vs After

Side-by-side comparison of the current and proposed infrastructure.

Current State

  • Jenkins server (~$40/mo) with manual plugin updates
  • SonarQube server (~$40/mo) for code quality
  • Single branch deploys (master only)
  • Static AWS credentials stored in Jenkins
  • SSH keys as Jenkins credentials
  • No staging or UAT environment
  • No infrastructure as code
  • Manual server configuration (snowflake)
  • Email-only deploy notifications
  • No environment approval gates
  • rsync backup after deploy (not before)
  • No secret rotation capability

Proposed State

  • GitHub Actions (free tier: 2,000 min/mo)
  • CodeQL + PHPStan + Codecov (zero cost)
  • 4-tier promotion: develop → staging → UAT → production
  • GitHub OIDC → AssumeRole (ephemeral credentials)
  • SSH key in AWS Secrets Manager (audited)
  • Staging + UAT on Hetzner CX32 (~€8/mo)
  • Terraform modules for all AWS production infra
  • Provisioning scripts + Docker Compose (reproducible)
  • GitHub environment status + future Slack integration
  • QA approval for UAT, Release Owner for production
  • Pre-deploy backup + automatic rollback on failure
  • AWS Secrets Manager with rotation support

SonarQube Replacement Matrix

SonarQube Feature GitHub Replacement Status
Code quality analysis PHPStan (level 6) + ESLint Already configured
Security scanning GitHub CodeQL (GHAS) In CI workflow
Dependency vulnerabilities Dependabot + composer audit + npm audit Active
Coverage tracking Codecov (40% threshold) In CI workflow
Quality gate (block merge) GitHub required status checks Branch protection
Dashboard / metrics GitHub Security tab + Codecov dashboard Per-PR diffs

Architecture Right-Sizing

The existing network diagram specifies a 6-VPC architecture. We recommend a single-VPC approach instead.

Existing Diagram (6 VPCs)

  • Shared VPC (public entry point)
  • Firewall VPC (AWS Network Firewall)
  • Production VPC (app + shared DB + PII DB)
  • Staging VPC (app + shared DB + PII DB)
  • Dev VPC (app + shared DB + PII DB)
  • Client VPC (per-client apps + PII DBs)
  • Transit Gateway connecting all 6 VPCs
  • ~$500+/mo in networking overhead alone
  • Requires dedicated platform team to operate

Right-Sized (1 VPC)

  • Single VPC with public + private subnets
  • Security Groups as firewall (free, built-in)
  • WAF on ALB for OWASP protection
  • Same VPC, separate security groups per env
  • PII encrypted at app layer (already implemented)
  • Tenant isolation via account_id (already implemented)
  • ~$100/mo total networking
  • Operationally simple for a small team
  • Add Client VPC later if contract requires it

Networking Cost Comparison

Component6-VPC ArchitectureRight-SizedSavings
Transit Gateway (6 attachments) ~$216/mo $0 $216/mo
AWS Network Firewall ~$300/mo $0 (Security Groups + WAF) $300/mo
VPC networking (NAT, endpoints) ~$150/mo ~$35/mo (1 NAT) $115/mo
Multiple RDS instances ~$400+/mo ~$70/mo (1 Multi-AZ) $330/mo
Networking overhead ~$1,000+/mo ~$100/mo ~$900/mo

When to add complexity back

Client VPC

When a client contract requires physical PII isolation (not just logical)

Transit Gateway

When you have multiple independent applications needing cross-VPC communication

Network Firewall

When a regulatory audit demands network-level traffic inspection beyond Security Groups

Proposed Architecture

GitHub as single control plane. All environments on AWS in one VPC. OIDC for identity.

┌─────────────────────────────────────────────────────────────────────────────┐ GITHUB (Control Plane) Repos · Actions · Environments · Branch Protection · CODEOWNERS CodeQL · Dependabot · Audit Log · Secret Scanning CI Runner (GitHub-hosted) Non-prod secrets: GitHub Secrets └──────────────┬──────────────────┼──────────────────────────────────────────────┘ OIDC (identity only) ┌──────────────▼──────────────────▼──────────────────────────────────────────────┐ AWS — Single VPC (us-west-2) ┌─ Public Subnets ──────────────────────────────────────────────────────┐ ALB (HTTPS + WAF)diagnostic.ly └───────────────────────────────────────────────────────────────────────┘ ┌─ Private Subnets ─────────────────────────────────────────────────────┐ EC2/ECS (production) EC2 (staging) EC2 (uat) SG: prod-app SG: stg-app SG: uat-app RDS Multi-AZ (prod) RDS (staging) RDS (uat) SG: prod-db SG: stg-db SG: uat-db Self-hosted runner NAT Gateway Redis (ElastiCache) └───────────────────────────────────────────────────────────────────────┘ S3 · Secrets Manager · KMS · GuardDuty · CloudWatch (365d) Prod secrets: AWS Secrets Manager (runtime via instance role) Terraform-managed · Encrypted at rest + in transit └───────────────────────────────────────────────────────────────────────────────┘

Promotion Flow

Branch
feature/*
PR + CI
Auto-deploy
develop
Staging
QA Approval
uat
UAT
Release Owner
main
Production

CI Pipeline (GitHub-hosted runner)

Lint
Pint · ESLint · tsc · PHPStan
Test
PHPUnit · Vitest
Coverage
Codecov (≥40%)
Security
CodeQL · Audits
Build
Vite + Artifact

Secrets Architecture

Identity and secrets are separate concerns. OIDC handles identity. Secrets Manager and GitHub Secrets handle configuration.

Identity

Who can access AWS

GitHub Action OIDC token AssumeRoleWithWebIdentity Temporary credentials (15 min)

No static AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY stored anywhere. Scoped to repo + branch.

Secrets

Sensitive app configuration

Production: EC2 instance role Secrets Manager .env Never visible in CI logs Non-prod: GitHub Encrypted Secrets .env No PHI, sufficient security

Secret Placement Model

Secret TypeLocationRationale
AWS deploy identity OIDC (no secret stored) Ephemeral, identity only
Production DB password AWS Secrets Manager KMS-encrypted, rotatable, CloudTrail audited
Production API keys (Stripe, SendGrid, Twilio) AWS Secrets Manager Central control, audit logging
SSH deploy key AWS Secrets Manager Retrieved via OIDC during deploy only
Staging / UAT secrets GitHub Encrypted Secrets No PHI, simpler ops, per-environment scoped
Local development .env.local Developer-only, gitignored

Cost Impact

Net reduction of ~$80+/month while gaining staging, UAT, and enterprise-grade security posture.

ItemCurrentProposedSavings
Jenkins server ~$30–50/mo $0 (GitHub Actions free tier) ~$40/mo
SonarQube server ~$30–50/mo $0 (CodeQL + Codecov free) ~$40/mo
Staging environment Not provisioned ($60–100 planned) Hetzner CX32 ~€8/mo ~$75/mo vs AWS plan
Non-prod object storage S3 ~$5/mo Hetzner Object Storage ~€5/mo ~$0
Net monthly ~$60–100+ ~$15 ~$80+/mo
~$960+
Annual savings
+2
New environments (staging + UAT)
−2
Servers to maintain (Jenkins + SonarQube)

Implementation Timeline

4-phase rollout over 10 weeks. Each phase is independently valuable.

1
Phase 1 — Week 1–2

Foundation

CI workflow (ci.yml), branch protection, Codecov, CodeQL, Dependabot. Replaces Jenkins CI stages and SonarQube analysis. Code complete

2
Phase 2 — Week 3–4

Hetzner Staging

Provision CX32, harden OS, Docker Compose stack, self-hosted runner, staging deploy workflow, .env.staging, object storage.

3
Phase 3 — Week 5–8

Production IaC

Terraform modules (VPC, RDS, ECS, ALB, IAM, monitoring). Import existing AWS resources. OIDC trust. Production deploy workflow. AWS self-hosted runner.

4
Phase 4 — Week 9–10

Cutover

Dual deploy (Jenkins + GitHub Actions) for 2 weeks. Decommission Jenkins. Remove Jenkinsfile + sonar-project.properties. Decommission SonarQube.

SOC2 Compliance Foundation

Every component is selected to satisfy SOC2 Trust Service Criteria without over-engineering.

CC6.1

Access Control

  • GitHub RBAC (Developer, QA, Release Owner)
  • AWS IAM least-privilege roles
  • OIDC (zero stored credentials)
  • Environment protection rules
  • Quarterly access review cadence
CC8.1

Change Management

  • PR → review → CI → promote → deploy
  • Required status checks block merge
  • CODEOWNERS for critical paths
  • Conventional commit enforcement
  • Full audit trail (GitHub + CloudWatch)
CC6.7

Encryption

  • TLS everywhere (ALB, DB connections)
  • RDS encrypted at rest (KMS)
  • S3 versioning + encryption
  • EBS encryption
  • Secrets Manager (KMS-backed)
CC7.2

Monitoring & Response

  • CloudWatch alarms (5xx, CPU, storage)
  • GuardDuty threat detection
  • WAF (OWASP rules + rate limiting)
  • 365-day log retention
  • Incident response runbook

Implementation Scope — 6 EPICs, 52 Issues

Full breakdown of work items tracked in GitHub Issues.

EPIC A

Governance & Branch Protection

8 issues — 2FA, RBAC roles, branch protection (main, uat, develop), environments, approval gates, signed commits

EPIC B

CI Pipeline

8 issues — Reusable CI workflow, lint, test, coverage, security scan, build artifact, required status checks

EPIC C

Hetzner Non-Prod

10 issues — VPS provisioning, OS hardening, Docker, staging/UAT stacks, self-hosted runner, anonymization pipeline

EPIC D

Production AWS / Terraform

14 issues — VPC, RDS Multi-AZ, ECS/EC2, ALB, IAM, Backup, CloudWatch, GuardDuty, WAF, S3, OIDC, runner, rollback

EPIC E

Deployment Workflows

10 issues — CI, staging, UAT, production workflows, OIDC, smoke tests, notifications, rollback, dual deploy, decommission

EPIC F

Compliance & Observability

8 issues — Change management docs, log retention, encryption, TLS, data flow, security scanning, access review, incident response

Decision Required

Approve the migration from Jenkins + SonarQube to GitHub Actions with the described architecture. Phase 1 (CI foundation) is already code-complete and ready for activation.

Risk
Low
2-week dual deploy period
Effort
10 Weeks
4 phases, each independently valuable
Impact
High
SOC2-ready, ~$960+/yr savings