Azure Architecture Diagram¶
This page documents the Azure infrastructure deployed by the infrastructure and azure-templates repositories for the Hinze Technologies project (prefix: ht, region: northeurope).
High-Level Overview¶
flowchart TB
subgraph internet["Internet"]
user["Users / Browsers"]
end
subgraph global["rg-ht-global (Global Shared Services)"]
acr["Azure Container Registry<br/><b>acrht</b><br/>Basic SKU"]
identity["User-Assigned Managed Identity<br/><b>id-ht</b>"]
law["Log Analytics Workspace<br/><b>law-ht</b>"]
appi["Application Insights<br/><b>appi-ht</b>"]
kvg["Global Key Vault<br/><b>kvg-ht</b>"]
end
subgraph envdev["rg-ht-dev (Dev Environment)"]
subgraph vnet["VNet: vnet-ht-dev (10.0.0.0/16)"]
subgraph snetappgw["snet-appgw (10.0.8.0/24)"]
appgw["Application Gateway<br/><b>agw-ht-dev</b><br/>WAF v2 + Public IP"]
end
subgraph snetca["snet-containerapps (10.0.0.0/23)"]
cae["Container Apps Environment<br/><b>cae-ht-dev</b>"]
blazor["Container App<br/><b>ca-sampleblazorweb-ht-dev</b><br/>SampleBlazor.Web"]
docs["Container App<br/><b>ca-docs-ht-dev</b><br/>Docs (MkDocs)"]
end
subgraph snetpe["snet-privateendpoints (10.0.4.0/24)"]
pekv["PE: Key Vault"]
pelaw["PE: Log Analytics"]
end
end
kvenv["Environment Key Vault<br/><b>kv-ht-dev</b>"]
waf["WAF Policy<br/><b>waf-ht-dev</b><br/>OWASP 3.2 Prevention"]
dns1["Private DNS: privatelink.vaultcore.azure.net"]
dns2["Private DNS: privatelink.ods.opinsights.azure.com"]
dns3["Private DNS: cae-ht-dev.northeurope.azurecontainerapps.io"]
end
user -->|"HTTP/HTTPS"| appgw
appgw -->|"Host-based routing<br/>*.dev.hinze-technologies.com"| blazor
appgw -->|"Host-based routing<br/>*.dev.hinze-technologies.com"| docs
blazor --> cae
docs --> cae
cae -.->|"ACR pull via Managed Identity"| acr
cae -.->|"Telemetry"| appi
appi --> law
pekv -.->|"Private Link"| kvg
pekv -.->|"Private Link"| kvenv
pelaw -.->|"Private Link"| law
Resource Naming Convention¶
All resources follow a consistent naming pattern:
| Pattern | Example | Description |
|---|---|---|
{type}-{prefix} |
acr-ht, id-ht |
Global resources |
{type}-{prefix}-{env} |
vnet-ht-dev, cae-ht-dev |
Environment resources |
ca-{appName}-{prefix}-{env} |
ca-sampleblazorweb-ht-dev |
Container apps |
kv-{prefixClean}-{env} |
kv-ht-dev |
Key Vaults (no hyphens in name) |
kvg-{prefixClean} |
kvg-ht |
Global Key Vault |
Deployment Layers¶
The infrastructure is deployed in three layers, each managed by a separate Bicep module:
Layer 1: Global Shared Services (global.bicep)¶
Deployed once to rg-ht-global via global-pipeline.yml.
| Resource | Name | Purpose |
|---|---|---|
| Azure Container Registry | acrht |
Hosts Docker images (Basic SKU) |
| Managed Identity | id-ht |
Used by Container Apps to pull images from ACR and access Key Vaults |
| Log Analytics Workspace | law-ht |
Centralized logging (30-day retention) |
| Application Insights | appi-ht |
Application performance monitoring |
| Global Key Vault | kvg-ht |
Stores outputs shared across pipelines (ACR login server, identity IDs, etc.) |
Layer 2: Environment Infrastructure (global.environment.bicep)¶
Deployed per environment (dev/tst/prd) to rg-ht-{env} via environment-pipeline.yml.
| Resource | Name | Purpose |
|---|---|---|
| Virtual Network | vnet-ht-dev |
10.0.0.0/16 address space with 3 subnets |
| NSGs | nsg-containerapps-ht-dev, etc. |
Network security rules per subnet |
| Container Apps Environment | cae-ht-dev |
Internal (VNet-integrated) hosting environment |
| Application Gateway | agw-ht-dev |
WAF v2 with public IP, host-based routing via *.dev.hinze-technologies.com |
| WAF Policy | waf-ht-dev |
OWASP 3.2 in Prevention mode |
| Environment Key Vault | kv-ht-dev |
Stores environment-specific secrets (Container Apps Environment ID, app FQDNs) |
| Private Endpoints | pe-kv-ht-dev, pe-law-ht-dev |
Private connectivity to Key Vault and Log Analytics |
| Private DNS Zones | Various | DNS resolution for private endpoints and CAE internal domain |
Layer 3: Container Applications (containers.bicep)¶
Deployed per application via container-pipeline.yml.
| Resource | Name | Purpose |
|---|---|---|
| Container App | ca-sampleblazorweb-ht-dev |
SampleBlazor.Web — Blazor WebAssembly app served via nginx |
| Container App | ca-docs-ht-dev |
Documentation site — MkDocs served via nginx |
Each container app is configured with:
- User-assigned managed identity for ACR pull
- External ingress on port 80 (routed through App Gateway)
- Auto-scaling: 1–3 replicas based on HTTP concurrency (50 requests)
- Application Insights telemetry
Network Architecture¶
Subnet Layout¶
| Subnet | CIDR | Purpose | Delegation |
|---|---|---|---|
snet-containerapps |
10.0.0.0/23 |
Container Apps Environment + apps | Microsoft.App/environments |
snet-privateendpoints |
10.0.4.0/24 |
Private Endpoints (ACR, KV, LAW) | None |
snet-appgw |
10.0.8.0/24 |
Application Gateway (WAF v2) | None |
Traffic Flow¶
sequenceDiagram
participant User as Internet User
participant AGW as App Gateway (WAF v2)
participant CA as Container App
participant ACR as Azure Container Registry
participant KV as Key Vault
participant LAW as Log Analytics
User->>AGW: HTTPS request to *.dev.hinze-technologies.com
AGW->>AGW: WAF inspection (OWASP 3.2)
AGW->>CA: Route to backend via host header
CA->>ACR: Pull image (via Managed Identity + Private Link)
CA->>KV: Read secrets (via Private Endpoint)
CA->>LAW: Send telemetry (via Private Endpoint)
CA-->>AGW: Response
AGW-->>User: Response
Security¶
- WAF v2 with OWASP 3.2 ruleset in Prevention mode protects all inbound traffic
- Private Endpoints ensure ACR, Key Vault, and Log Analytics are not exposed to the public internet
- Private DNS Zones enable name resolution for private endpoints within the VNet
- NSGs restrict traffic per subnet (only HTTPS inbound to Container Apps, Gateway Manager ports for App Gateway)
- RBAC on Key Vaults — the managed identity is granted Key Vault Secrets User role
Pipeline Architecture¶
flowchart LR
subgraph infra["infrastructure repo"]
gp["global-pipeline.yml"]
gd["global-dev.yaml"]
end
subgraph templates["azure-templates repo"]
gbt["global-pipeline.yml template"]
ept["environment-pipeline.yml template"]
cpt["container-pipeline.yml template"]
gb["global.bicep"]
ge["global.environment.bicep"]
cb["containers.bicep"]
end
subgraph apps["App repos (sampleblazor, docs)"]
ap["azure-pipelines.yml"]
end
gp -->|"extends"| gbt
gd -->|"extends"| ept
ap -->|"Build stage"| ap
ap -->|"Deploy stage extends"| cpt
gbt -->|"deploys"| gb
ept -->|"deploys"| ge
cpt -->|"deploys"| cb
| Pipeline | Trigger | What it deploys |
|---|---|---|
infrastructure/global-pipeline.yml |
Push to main | Global shared resources via global.bicep |
infrastructure/global-dev.yaml |
Push to main | Dev environment infrastructure via global.environment.bicep |
sampleblazor/azure-pipelines.yml |
Push to main | Build + push Docker image, then deploy via container-pipeline.yml |
docs/azure-pipelines.yml |
Push to main | Build + push Docker image, then deploy via container-pipeline.yml |