|
1 | 1 | # Architecture |
2 | 2 |
|
3 | | -## Scope and ownership |
4 | | - |
5 | | -`infra/main.bicep` is a subscription-scope orchestrator. It creates one resource |
6 | | -group for a selected environment and delegates coherent concerns to |
7 | | -resource-group-scoped modules. |
8 | | - |
9 | | -```text |
10 | | -Subscription deployment |
11 | | - -> environment resource group |
12 | | - -> observability module |
13 | | - -> Log Analytics workspace |
14 | | - -> workspace-based Application Insights |
15 | | - -> compute module |
16 | | - -> Container Apps managed environment |
17 | | - -> Container App with system-assigned identity |
18 | | - -> Azure Monitor diagnostic settings |
19 | | - -> budget module (optional) |
20 | | - -> resource-group budget and notifications |
| 3 | +The CAS Platform infrastructure relies on a modular, subscription-scoped orchestration model built with Azure Bicep. It emphasizes environment isolation, strict identity boundaries, and comprehensive observability. |
| 4 | + |
| 5 | +## System Architecture Diagram |
| 6 | + |
| 7 | +```mermaid |
| 8 | +flowchart TD |
| 9 | + subgraph Subscription ["Azure Subscription"] |
| 10 | + direction TB |
| 11 | + Main[infra/main.bicep Orchestrator] |
| 12 | + |
| 13 | + subgraph RG ["Environment Resource Group (rg-cas-{env})"] |
| 14 | + direction TB |
| 15 | + |
| 16 | + subgraph Observability ["Observability Module"] |
| 17 | + LAW[Log Analytics Workspace] |
| 18 | + AppInsights[Application Insights] |
| 19 | + LAW --- AppInsights |
| 20 | + end |
| 21 | + |
| 22 | + subgraph Compute ["Compute Module"] |
| 23 | + CAE[Container Apps Environment] |
| 24 | + CA[Container App Workload] |
| 25 | + CAE --- CA |
| 26 | + end |
| 27 | + |
| 28 | + subgraph Cost ["Cost Management Module (Optional)"] |
| 29 | + Budget[Resource Group Budget] |
| 30 | + end |
| 31 | + |
| 32 | + CA -->|Sends Telemetry| AppInsights |
| 33 | + CA -->|Diagnostics Logs| LAW |
| 34 | + end |
| 35 | + |
| 36 | + subgraph ExternalAuth ["External Authorization (Optional)"] |
| 37 | + FoundryRBAC[Foundry RBAC Module] |
| 38 | + FoundryProject[Foundry Project Resource] |
| 39 | + end |
| 40 | + end |
| 41 | +
|
| 42 | + Main -->|Deploys| RG |
| 43 | + Main -->|Configures| Observability |
| 44 | + Main -->|Configures| Compute |
| 45 | + Main -->|Configures| Cost |
| 46 | + Main -.->|Assigns Role| FoundryRBAC |
| 47 | + |
| 48 | + CA -->|System-Assigned Managed Identity| FoundryRBAC |
| 49 | + FoundryRBAC -->|Grants Scoped Access| FoundryProject |
21 | 50 | ``` |
22 | 51 |
|
23 | | -## Environment model |
| 52 | +## Scope and Ownership |
24 | 53 |
|
25 | | -Dev, test, and production use the same module graph. Parameter files vary only |
26 | | -approved values such as retention, workload sizing, ingress, and budget. Each |
27 | | -environment receives a separate resource group, telemetry workspace, compute |
28 | | -environment, identity boundary, and budget. |
| 54 | +`infra/main.bicep` acts as the subscription-scope orchestrator. It ensures the creation of a dedicated resource group for a specified environment (e.g., `dev`, `test`, `prod`) and delegates specific capabilities to resource-group-scoped modules. |
29 | 55 |
|
30 | | -## Identity and networking |
| 56 | +## Environment Model |
31 | 57 |
|
32 | | -The Container App receives a system-assigned managed identity. Foundry access |
33 | | -is optional and creates no role assignment by default. When both an explicit |
34 | | -Foundry project resource ID and an approved role definition resource ID are |
35 | | -provided, the platform assigns that role only at the project resource scope. |
36 | | -Subscription-wide workload roles are not supported. |
| 58 | +Dev, test, and production environments utilize the exact same module graph. Variations are handled purely through parameter files (e.g., log retention duration, workload sizing, ingress configuration, and budget limits). Each environment receives its own isolated: |
| 59 | +- Resource group |
| 60 | +- Telemetry workspace (Log Analytics & Application Insights) |
| 61 | +- Compute environment (Container Apps) |
| 62 | +- Identity boundary |
| 63 | +- Budget |
37 | 64 |
|
38 | | -External ingress defaults to disabled. Enabling it is an explicit parameter |
39 | | -decision and requires a threat-model review. The v0.1 baseline does not claim |
40 | | -private networking. That topology remains deferred until a target landing-zone |
41 | | -contract identifies required subnets, DNS, firewall, and egress ownership. |
| 65 | +## Identity and Networking |
42 | 66 |
|
43 | | -## Reference product contract |
| 67 | +The core workload (Container App) relies exclusively on a **system-assigned managed identity**. |
44 | 68 |
|
45 | | -The workload module follows the public `cas-reference-product` deployment |
46 | | -interface: Linux container image, port 8080, internal ingress by default, |
47 | | -system-assigned identity, `/health/live` and `/health/ready` probes, and |
48 | | -non-secret workload configuration. Application Insights configuration is |
49 | | -injected directly from the observability module. |
| 69 | +* **Foundry Access:** This access is completely optional and disabled by default. If an explicit Foundry project resource ID and role definition are provided, the platform assigns that specific role *only* at the project scope. There are no subscription-wide assignments. |
| 70 | +* **Networking:** External ingress is disabled by default. Enabling it requires an explicit parameter override and threat-model review. Private networking is currently deferred until a target landing-zone contract is established. |
| 71 | + |
| 72 | +## Reference Product Contract |
| 73 | + |
| 74 | +The workload module is designed to implement the public `cas-reference-product` deployment interface: |
| 75 | +* Deploys a Linux container image on port `8080`. |
| 76 | +* Ingress is internal by default. |
| 77 | +* Expects `/health/live` and `/health/ready` probe endpoints. |
| 78 | +* Workload configuration is non-secret and injected at runtime. |
| 79 | +* Application Insights connection strings are injected securely directly from the observability module outputs. |
50 | 80 |
|
51 | 81 | ## Observability |
52 | 82 |
|
53 | | -Platform and application diagnostic settings send all supported logs and |
54 | | -metrics to the environment Log Analytics workspace. Application Insights is |
55 | | -workspace-based. No workspace shared keys or instrumentation connection strings |
56 | | -are output. |
| 83 | +Diagnostic settings for both platform components and the application workload are configured to forward all supported logs and metrics into the environment's Log Analytics workspace. Application Insights is strictly workspace-based, meaning no legacy shared keys are utilized. |
| 84 | + |
| 85 | +## Change Safety |
57 | 86 |
|
58 | | -## Change safety |
| 87 | +Infrastructure updates are managed via a strict pipeline: |
| 88 | +1. Linting and contract tests. |
| 89 | +2. Subscription-level `what-if` validation. |
| 90 | +3. Explicit deployment authorization. |
59 | 91 |
|
60 | | -Normal changes flow through build, lint, contract tests, and subscription |
61 | | -`what-if`. Resource naming is deterministic. Renaming workload, environment, or |
62 | | -location can replace resource boundaries and must be treated as a migration. |
| 92 | +**Note on Naming:** Resource naming is deterministic based on subscription, workload name, environment, and region. Changing any of these core parameters will result in the replacement of resource boundaries and must be executed as a carefully planned migration. |
0 commit comments