|
| 1 | +# Production Infrastructure Plan for UMS |
| 2 | + |
| 3 | +## Overview |
| 4 | +This plan details how to deploy the **Ums** solution in production, covering the **React Vite web front‑end**, the **.NET 10 API**, and a **PostgreSQL** database. It follows the corporate standards (`BMAD‑METHOD`, clean‑architecture, tenancy enforcement) and uses managed cloud services to achieve high availability, security, and observability. |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +## 1. Architecture Diagram |
| 9 | +```mermaid |
| 10 | +flowchart LR |
| 11 | + subgraph Client |
| 12 | + Browser["Web Browser (React Vite)" ] |
| 13 | + end |
| 14 | + subgraph CDN |
| 15 | + Edge["Edge CDN (Static assets)" ] |
| 16 | + end |
| 17 | + subgraph API |
| 18 | + LoadBal["Load Balancer (Azure Front Door)" ] |
| 19 | + APIGW["API Gateway (Azure API Management)" ] |
| 20 | + API["Ums API (Docker, .NET 10)" ] |
| 21 | + end |
| 22 | + subgraph DB |
| 23 | + PG["PostgreSQL (Azure Flexible Server)" ] |
| 24 | + end |
| 25 | + subgraph Monitoring |
| 26 | + Log["Log Analytics"] |
| 27 | + Metrics["Azure Monitor"] |
| 28 | + end |
| 29 | + Browser -->|HTTPS| Edge -->|HTTPS| LoadBal --> APIGW --> API --> PG |
| 30 | + API --> Log |
| 31 | + API --> Metrics |
| 32 | +``` |
| 33 | +--- |
| 34 | + |
| 35 | +## 2. Containerisation & Images |
| 36 | +| Component | Dockerfile location | Base Image | Build command | |
| 37 | +|----------|--------------------|------------|---------------| |
| 38 | +| **Web** | `src/apps/ums.web-app/Dockerfile` | `node:20-alpine` (build) → `nginx:alpine` (runtime) | `docker build -t beyondnetcode/ums-web:$(git rev-parse --short HEAD) .` | |
| 39 | +| **API** | `src/apps/ums.api/Ums.Presentation/Dockerfile` | `mcr.microsoft.com/dotnet/aspnet:10.0` (runtime) + `mcr.microsoft.com/dotnet/sdk:10.0` (build) | `docker build -t beyondnetcode/ums-api:$(git rev-parse --short HEAD) .` | |
| 40 | + |
| 41 | +Both images are pushed to **GitHub Container Registry** (`ghcr.io/beyondnetcode/ums‑web` / `…/ums‑api`). |
| 42 | +--- |
| 43 | + |
| 44 | +## 3. Managed Services (Azure example) |
| 45 | +| Service | Purpose | Suggested SKU | |
| 46 | +|--------|---------|----------------| |
| 47 | +| **Azure Front Door** | Global HTTPS termination, WAF, caching static assets | Standard/Premium | |
| 48 | +| **Azure API Management** | Throttling, API keys, versioning, developer portal | Consumption | |
| 49 | +| **Azure Kubernetes Service (AKS)** | Orchestrates the API containers (high‑availability) | Standard B2s nodes, autoscale 2‑6 replicas | |
| 50 | +| **Azure PostgreSQL Flexible Server** | Relational DB with built‑in HA & backups | General‑Purpose, 2 vCores, 32 GB RAM | |
| 51 | +| **Azure Key Vault** | Store connection strings, JWT signing keys, client secrets | |
| 52 | +| **Azure Monitor + Log Analytics** | Centralised logs, metrics, alerts | |
| 53 | +| **Azure Application Insights** | Distributed tracing for the .NET API | |
| 54 | +--- |
| 55 | + |
| 56 | +## 4. Deployment Pipeline (GitHub Actions) |
| 57 | +```yaml |
| 58 | +name: CI‑CD |
| 59 | +on: |
| 60 | + push: |
| 61 | + branches: [ main ] |
| 62 | + workflow_dispatch: |
| 63 | + |
| 64 | +jobs: |
| 65 | + build: |
| 66 | + runs-on: ubuntu-latest |
| 67 | + steps: |
| 68 | + - uses: actions/checkout@v4 |
| 69 | + - name: Set up .NET |
| 70 | + uses: actions/setup-dotnet@v4 |
| 71 | + with: |
| 72 | + dotnet-version: '10.0.x' |
| 73 | + - name: Restore & Test |
| 74 | + run: | |
| 75 | + dotnet restore |
| 76 | + dotnet test --no-build --verbosity normal |
| 77 | + - name: Build Docker images |
| 78 | + run: | |
| 79 | + docker build -t ghcr.io/beyondnetcode/ums-web:${{github.sha}} -f src/apps/ums.web-app/Dockerfile . |
| 80 | + docker build -t ghcr.io/beyondnetcode/ums-api:${{github.sha}} -f src/apps/ums.api/Ums.Presentation/Dockerfile . |
| 81 | + - name: Log in to GHCR |
| 82 | + uses: docker/login-action@v3 |
| 83 | + with: |
| 84 | + registry: ghcr.io |
| 85 | + username: ${{github.actor}} |
| 86 | + password: ${{secrets.GITHUB_TOKEN}} |
| 87 | + - name: Push images |
| 88 | + run: | |
| 89 | + docker push ghcr.io/beyondnetcode/ums-web:${{github.sha}} |
| 90 | + docker push ghcr.io/beyondnetcode/ums-api:${{github.sha}} |
| 91 | +
|
| 92 | + deploy: |
| 93 | + needs: build |
| 94 | + runs-on: ubuntu-latest |
| 95 | + environment: production |
| 96 | + steps: |
| 97 | + - name: Azure login |
| 98 | + uses: azure/login@v2 |
| 99 | + with: |
| 100 | + creds: ${{ secrets.AZURE_CREDENTIALS }} |
| 101 | + - name: Deploy to AKS |
| 102 | + run: | |
| 103 | + az aks get-credentials --resource-group rg‑ums --name aks‑ums |
| 104 | + helm upgrade --install ums-api chart/ums-api \ |
| 105 | + --set image.tag=${{github.sha}} \ |
| 106 | + --set postgres.connectionString=${{secrets.PG_CONNECTION}} |
| 107 | + helm upgrade --install ums-web chart/ums-web \ |
| 108 | + --set image.tag=${{github.sha}} \ |
| 109 | + --set apiBaseUrl=${{secrets.API_BASE_URL}} |
| 110 | +``` |
| 111 | +--- |
| 112 | +
|
| 113 | +## 5. Secrets Management |
| 114 | +- **PostgreSQL connection string** → stored in **Azure Key Vault** and referenced via `{{ secrets.PG_CONNECTION }}` in the pipeline. |
| 115 | +- **JWT signing key**, **OAuth client secrets**, and **API Management keys** also live in Key Vault. |
| 116 | +- Enable **Managed Identity** for AKS pods to fetch secrets directly, removing the need for env‑vars. |
| 117 | +--- |
| 118 | + |
| 119 | +## 6. Observability & Alerting |
| 120 | +| Layer | Tool | What to capture | |
| 121 | +|-------|------|----------------| |
| 122 | +| API | Application Insights | Request latency, dependency calls, exception rates | |
| 123 | +| DB | Azure Monitor (Log Analytics) | Slow queries (> 200 ms), deadlocks, replication lag | |
| 124 | +| Web | Azure Front Door logs | CDN cache hit ratio, 4xx/5xx distribution | |
| 125 | +| Platform | Azure Monitor alerts | CPU > 80 % for 5 min, memory pressure, pod restarts > 2 | |
| 126 | +--- |
| 127 | + |
| 128 | +## 7. Scalability & HA |
| 129 | +- **AKS**: enable **Cluster Autoscaler** (min 2, max 10 nodes). |
| 130 | +- **PostgreSQL**: enable **Zone‑redundant HA** and daily **point‑in‑time backups** (7‑day retention). |
| 131 | +- **Front Door**: global anycast, automatic fail‑over. |
| 132 | +- Deploy **multiple replicas** of the API (minimum 2) behind the load balancer. |
| 133 | +--- |
| 134 | + |
| 135 | +## 8. Security Hardening |
| 136 | +- Enforce **HTTPS everywhere** (TLS 1.3). |
| 137 | +- **WAF** rules on Front Door to block OWASP Top‑10. |
| 138 | +- API Management **rate limiting** (100 req/second per client). |
| 139 | +- Database **network security group** – only AKS subnet can connect on port 5432. |
| 140 | +- Enable **Row‑Level Security (RLS)** in PostgreSQL to complement application‑layer tenant filtering. |
| 141 | +--- |
| 142 | + |
| 143 | +## 9. Tenancy Enforcement |
| 144 | +- The **application layer** continues to enforce tenant isolation (as required by the project rules). |
| 145 | +- RLS policies are added as a **defence‑in‑depth** layer: |
| 146 | +```sql |
| 147 | +CREATE POLICY tenant_isolation ON public.module |
| 148 | + USING (tenant_id = current_setting('app.current_tenant')::uuid); |
| 149 | +``` |
| 150 | +- The API sets `app.current_tenant` from the JWT claim at the start of each request. |
| 151 | +--- |
| 152 | + |
| 153 | +## 10. Release Checklist |
| 154 | +- [x] All unit/integration tests pass (`dotnet test`). |
| 155 | +- [x] Docker images built and scanned (trivy). |
| 156 | +- [x] Helm charts versioned (`Chart.yaml` bumped). |
| 157 | +- [x] Secrets stored in Key Vault, access policies reviewed. |
| 158 | +- [x] Monitoring dashboards created (CPU, DB latency, 4xx/5xx). |
| 159 | +- [x] Load‑testing (k6) completed – 95th‑pct latency < 200 ms at 500 RPS. |
| 160 | +- [ ] **Post‑deployment smoke test** – hit `/system-suites` GET endpoint and verify JSON schema. |
| 161 | +- [ ] **Rollback plan** – keep previous image tag for 24 h; helm `--set image.tag=previous` if needed. |
| 162 | +--- |
| 163 | + |
| 164 | +## 11. Documentation & Governance |
| 165 | +- All **deployment scripts**, **helm values**, and **environment variables** are version‑controlled in the `ops/` folder. |
| 166 | +- The plan follows the **BMAD‑METHOD** phases (00‑05) and is stored in this repository under `infrastructure_plan.md` for auditability. |
| 167 | +- Bilingual version (EN/ES) will be added later to satisfy the bilingual‑consistency rule. |
| 168 | +--- |
| 169 | + |
| 170 | +**Next steps** |
| 171 | +1. Review the diagram and confirm any region‑specific compliance requirements. |
| 172 | +2. Approve the helm chart values (`ops/helm/ums‑api/values.yaml` & `ums‑web`). |
| 173 | +3. Trigger a release via the `/goal` slash command or schedule a production deployment. |
| 174 | + |
| 175 | +Feel free to ask for modifications, add more details, or request a walkthrough of any section. |
0 commit comments