Chapter 01 · Overview

Azure Topology

The bird's-eye view. Every Azure service the harness needs, organized by resource group, with the data flows that connect them.

Four resource groups

The recommended deployment organizes Azure resources into four resource groups, each scoped to a single concern. This keeps IAM policies tight, cost tracking clear, and blast radius contained when you need to tear down and recreate a layer.

rg-harness-core

Compute. The Container Apps Environment and the three Container Apps that make up the runtime: the Harness API (ASP.NET Core backend), AgentHub (SignalR real-time gateway), and the MCP Server (HTTP + JWT tool exposure). This is where your code runs.

rg-harness-ai

AI services. Azure OpenAI (a chat completion model for reasoning, an embedding model for vector embeddings) and Azure AI Search (hybrid vector + BM25 retrieval). These are the most expensive resources and the most common scaling bottleneck.

rg-harness-data

Data. Knowledge graph backend (Neo4j on AKS — the choice in the validated staging/prod payloads — or any managed PostgreSQL; both implement IKnowledgeGraphStore, while the embedded Kuzu backend used for local dev implements IGraphDatabaseBackend), Azure SQL (plan state persistence via EF Core), and Blob Storage (document ingestion, FAISS index snapshots, JSONL audit logs).

rg-harness-platform

Platform. Key Vault (secrets and certificates), Application Insights + Log Analytics (telemetry, traces, metrics), Front Door (global ingress, WAF, TLS termination), and Entra ID (authentication, managed identity).

Full topology

The diagram below shows every Azure service and the connections between them. Each box is color-coded by category: blue for compute, purple for AI, green for data, teal for networking, orange for security, yellow for monitoring, and gray for storage.

Azure Resource Topology
Front Door / App Gateway
Global ingress, WAF, TLS termination Standard_AzureFrontDoor
Harness API
Container App · ASP.NET Core Consumption / Dedicated
AgentHub
Container App · SignalR Consumption / Dedicated
MCP Server
Container App · HTTP + JWT Consumption / Dedicated
↓   ↓   ↓
Azure OpenAI
Chat completion + embedding models Standard S0
🔍
Azure AI Search
Hybrid vector + BM25 retrieval Basic / Standard S1
↓   ↓
🗂
Neo4j on AKS
Knowledge graph backend Single / HA cluster
🗃
Azure SQL
Plan state · EF Core Serverless / S1
📁
Blob Storage
Documents, FAISS, audit logs Standard LRS
🔒
Key Vault
Secrets, certificates, keys Standard
📈
Application Insights
Traces, metrics, logs Workspace-based
👤
Entra ID
Auth, managed identity, RBAC P1 / P2

Data flow: a user message

To make the topology concrete, here's what happens when a user sends a message through the harness. Every hop crosses a service boundary shown in the diagram above.

  1. User → Front Door → Harness API Container App. The user's message arrives via HTTPS. Front Door handles TLS termination, WAF inspection, and routes to the nearest Container App revision.
  2. API → Azure OpenAI (LLM call). The harness builds the prompt (system instructions + conversation history + skill context + retrieved documents) and sends it to the chat completion deployment. The model returns a response, possibly including tool-use requests.
  3. API → AI Search (RAG retrieval) → Azure OpenAI (embeddings). If RAG is triggered, the query is embedded via the embedding deployment, then sent to AI Search for hybrid vector + BM25 retrieval. Results are reranked and assembled into the context window.
  4. API → Knowledge graph backend (graph query). For graph-backed memory queries — entity lookup, community detection, cross-session recall — the API hits the configured graph backend (Neo4j on AKS in the validated payloads, or a managed PostgreSQL store).
  5. API → Application Insights (telemetry). Every step emits OpenTelemetry spans: the LLM call duration, token counts, retrieval latency, tool execution time, and governance decisions. All flow to Application Insights via the OTLP exporter.
Dev shortcut

For local development, everything runs on localhost with SQLite (plan state), in-memory FAISS (vector search), and the InMemoryGraphStore (knowledge graph). You don't need any Azure resources to develop locally — only an Azure OpenAI endpoint for LLM calls.

Environment variations

Not every environment needs every service. The table below shows the recommended configuration at each tier, from zero-cost local development to a full production deployment.

Development
  • AgentHub on Container Apps (single replica, scale-to-zero)
  • Dashboard on Static Web App
  • Azure OpenAI S0 (chat + embedding)
  • Blob Storage (artifacts, eval datasets)
  • Key Vault for secrets
  • Application Insights
  • SQLite (plan state) and FAISS (vectors) stay in-process — no Azure data resources
~$183/mo (API-validated, eastus)
Staging
  • AgentHub + MCP Server on Container Apps (VNet ingress)
  • Front Door + APIM in front
  • Azure OpenAI S1, AI Search Basic
  • Neo4j single-node on AKS (KG)
  • Azure SQL (plan state), Blob Storage, Key Vault — all private endpoint
  • Entra ID, Log Analytics + App Insights
~$1,573/mo (API-validated, eastus)
Production
  • Staging shape, plus DDoS Protection Standard
  • Front Door Premium with private-link origins
  • Azure OpenAI PTU + S1 burst, AI Search S2 (HA)
  • Neo4j Enterprise causal cluster on AKS (zone-redundant)
  • Azure SQL Business Critical, Redis Cache, geo-redundant Storage
  • Key Vault Premium (HSM), CMK on data services
~$4,597/mo (API-validated, eastus)

Generated topology diagrams

The three tiers above were modeled deterministically with the AzureCraft Architecture Generator and validated against the Azure Well-Architected Framework pillars (security, reliability, performance, operational excellence, cost). The generator places services into the right resource group, VNet, and subnet automatically; the cost figures above are pulled directly from its pricing model for the East US region.

The payload files below are the source of truth for the topology — edit them and re-POST to the generator's /api/generate endpoint (port floats per restart; see the "How to regenerate" callout below this table for the current invocation) to refresh. The full DiagramState JSON (nodes, edges, layout, validationResults, costSummary) is saved by the generator under its own generated/ directory; reference the file IDs from the table below.

Tier Services Connections Monthly cost Findings Payload
Development 6 5 $183.44 6 (all expected for a public, minimal dev tier — no DDoS / Entra / Log Analytics by design) dev.json
Staging 14 20 $1,573.07 3 (no DDoS plan, no Redis, storage lifecycle — saved for the prod tier) staging.json
Production 16 22 $4,597.37 0 — clean against all WAF pillars prod.json
i
How to regenerate

With the AzureCraft generator running locally (npm run dev in its apps/web folder — the port floats; 3002 as of 2026-06-03), POST any payload above to /api/generate:

Invoke-RestMethod -Uri 'http://localhost:3002/api/generate' `
  -Method Post -ContentType 'application/json' `
  -InFile 'documentation/architecture/assets/diagrams/payloads/prod.json'

The response includes a report summary, the full diagram state, and a file path under the generator's own generated/ output. A committed copy of the production diagram lives at assets/diagrams/generated/prod.json so reviewers can inspect node placement, edge routing, and per-service costs without running the generator. Re-run after any topology change to refresh both the table above and the committed diagram.

Why dev shows 6 findings and prod shows 0

Dev intentionally omits DDoS Protection, Front Door, Entra ID, and Log Analytics to stay cheap — the generator correctly flags these as gaps against the WAF security and reliability pillars. They reappear in staging and prod where the cost is justified. Prod hits zero findings after wiring the Neo4j AKS workload to both Key Vault and App Insights (a real omission the generator caught and we fixed before committing).

!
Region matters

Azure OpenAI model availability varies by region. Not every region has every model. Check the model availability table before choosing your deployment region. AI Search and Azure OpenAI should be co-located in the same region to minimize embedding and retrieval latency.