NHC Architecture Decisions — DA-15 Brief · 2026-03-31¶
DA-15 — Architecture Update · Phase 3 Complete
Internal brief · 31 March 2026
| AWS Account | 794248400165 (NHC prod) |
| Region | us-east-2 (Ohio) |
| Critical gaps | 0 — ENC-003 closed |
| Compliance | 55% — 11/20 controls |
🔄 What Changed — Phase 3 Complete¶
✅ HTTPS Enforcement Live — Last Critical Gap Closed
ALB + WAF deployed and verified. Both ALBs serve HTTPS only (HTTP redirects to 443). AWS WAF v2 attached to Django ALB with managed rule sets and rate limiting at 2,000 req/5min. CloudWatch log group captures WAF events (90-day retention). ENC-003 closed.
✅ DNS Verified
All three staging domains resolve correctly via dig. Cloudflare CNAMEs point to ALB endpoints. Django API uses grey cloud (DNS-only — PHI must not traverse Cloudflare). WP CMS uses orange cloud (proxied — Cloudflare WAF + CDN).
ℹ️ Staging Domains Active
staging-django-api.novavirtual.site·staging-portals.novavirtual.site·staging-wp-cms.novavirtual.site
ACM certs issued and attached. Django cert is a SAN cert covering both the API and Portals subdomains.
📊 Compliance Status Post Phase 3¶
| Metric | Value | Notes |
|---|---|---|
| Critical Gaps | 0 ✅ | Was 1 (ENC-003). Now closed. |
| High Gaps Remaining | 4 ⚠️ | Access controls + screenshot PHI |
| Controls Done | 11 / 20 | 55% — up from 45% at Phase 2 |
| Phases Complete | 3 / 6 ✅ | 1 Encryption · 2 App infra · 3 HTTPS+WAF |
🏗️ Settled Hosting Architecture¶
Django API + Portals — HIPAA path (AWS only)¶
User → Cloudflare DNS only (grey cloud) → ACM + ALB (HTTPS, TLS 1.2–1.3) → AWS WAF v2 → EC2 Django (private subnet)
PHI never leaves AWS network. Cloudflare is DNS-only — no traffic interception.
WP CMS — non-HIPAA¶
User → Cloudflare (proxied — WAF + CDN) → ALB (HTTPS) → EC2 App (private subnet)
Gatsby + Astro (3 sites) — static, non-HIPAA¶
User → Cloudflare Pages (CDN + WAF)
GitLab Runner (ec2-app) → wrangler pages deploy → Cloudflare Pages project
No S3, no CloudFront, no ACM certs needed. Cloudflare handles HTTPS + CDN + WAF. Phase 4 = GitLab CI config only.
Hosting Summary Table¶
| App | PHI / HIPAA? | Hosting | WAF | Status |
|---|---|---|---|---|
Django API staging-django-api.novavirtual.site |
❗ Yes — full HIPAA | EC2 private + ALB (AWS only, no CF proxy) | AWS WAF v2 | ✅ Live — Phase 3 |
Portals staging-portals.novavirtual.site |
⚠️ Auth sessions — in scope | Shared EC2 Django + ALB (must stay AWS) | AWS WAF v2 (inherited) | ✅ Live — Phase 3 |
WP CMS staging-wp-cms.novavirtual.site |
✅ No PHI | EC2 private + ALB + Cloudflare proxy | Cloudflare | ✅ Live — Phase 3 |
Gatsby staging-gatsby.novavirtual.site |
✅ No PHI | Cloudflare Pages (built on ec2-app) | Cloudflare | 🟡 Phase 4 — CI config only |
Astro (×3 sites) staging-essential · staging-caringforyou · staging-vital |
✅ No PHI | Cloudflare Pages (built on ec2-app) | Cloudflare | 🟡 Phase 4 — CI config only |
Note: Astro monorepo has 4 sites but one org stopped operations — 3 active staging domains.
✅ Deployed Infrastructure — Full Inventory¶
| Resource | ID / Endpoint | Notes |
|---|---|---|
| ec2-app | i-0880310086620ce5e · 10.1.10.241 |
WP CMS + Gatsby/Astro builds, GitLab Runner, 4GB swap |
| ec2-django | i-0341906c41c45d520 · 10.1.11.178 |
Django API + Portals, GitLab Runner, 4GB swap |
| rds-django | prod-nhc-django (MySQL 8.0) | Private subnet, KMS encrypted, PHI-tagged, 7-day backups |
| ALB — Django | prod-nhc-django-alb-1713854905.us-east-2.elb.amazonaws.com |
HTTPS only, WAF attached, health check /health/ |
| ALB — WP CMS | prod-nhc-wordpress-alb-1502175647.us-east-2.elb.amazonaws.com |
HTTPS only, Cloudflare proxied in front |
| WAF — Django | prod-nhc-django-waf | Managed rules + rate limit 2,000/5min, logs → CloudWatch 90d |
| ACM cert — Django | ad4f0d27-051e-4dc6-811a-c71c83944383 |
SAN: staging-django-api + staging-portals.novavirtual.site |
| ACM cert — WP CMS | be7a98d6-28c3-476d-8e8a-a1212d24dbf7 |
staging-wp-cms.novavirtual.site |
All EC2s: Debian 13, Docker CE + Compose, GitLab Runner, deploy user. Access via SSM Session Manager only — no SSH port open anywhere.
🗺️ Roadmap — What's Next¶
✅ Phase 1 — Security Baseline (Complete)¶
- KMS CMKs (EBS, S3, RDS, CloudTrail, Backup)
- VPC — private subnets, NAT GW, VPC endpoints, flow logs
- CloudTrail, GuardDuty, Config (HIPAA pack), Security Hub (NIST 800-53)
- AWS Backup vault — 30-day retention
- IAM baseline — SSM instance profile, Access Analyzer, password policy
✅ Phase 2 — App Infrastructure (Complete)¶
- EC2 × 2 (ec2-app + ec2-django) — Debian 13, encrypted EBS, SSM-only
- RDS MySQL 8.0 — KMS encrypted, private subnet, PHI-tagged
- Ansible bootstrap — Docker CE, GitLab Runner, deploy user, swap
✅ Phase 3 — HTTPS + WAF (Complete — ENC-003 closed)¶
- ALB module — HTTPS-only, HTTP→HTTPS redirect, TLS 1.2+1.3
- AWS WAF v2 — managed rules + rate limiting on Django ALB
- ACM certs issued and attached (both ALBs)
- DNS verified — all 3 staging domains resolving
🟡 Phase 4 — Static Site CI/CD (Next — No AWS infra needed)¶
- Register GitLab Runner on ec2-app (needs registration token)
- Create Cloudflare Pages projects (Gatsby × 1, Astro × 3)
- Write
.gitlab-ci.yml: build →wrangler pages deploy - Store
CLOUDFLARE_API_TOKENin GitLab CI/CD variables
⏳ Phase 5 — Hardening & State (Pending)¶
- S3 + DynamoDB remote state backend
- TerraformDeployRole via IaC — restore assume_role in provider
- Cross-region backup DR vault (us-west-2)
- VPC Flow Logs + SSM Parameter Store IAM policy on instance profiles
- Import Ansible SSM bucket into tofu state
⏳ Go-Live — Production Promotion (After MWE data handover)¶
- Paolo updates
stage = "prod"interraform.tfvars, runstofu applyto retag - MWE prod database + S3 migrated in — real PHI now in scope
- True staging account created from scratch post go-live
🚧 Current Blockers — Phase 4¶
| Blocker | Needed For | Owner |
|---|---|---|
| GitLab Runner registration token | Phase 4 — register runner on ec2-app | GitLab admin / Paolo |
| Cloudflare Pages projects created (4 sites) | Phase 4 — deploy targets for wrangler | Paolo |
| Cloudflare API token (Pages deploy scope) | Phase 4 — GitLab CI variable for wrangler | Paolo |
| MWE prod data handover date | Go-live — stage promotion + PHI migration | MWE / Stakeholder |
DA-15 — NHC HIPAA-Compliant Infrastructure · Phase 3 Complete · 2026-03-31 · DevOps