Skip to content

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