# yaml-language-server: $schema=../references/diagram.schema.json
title: Web app on Azure
subtitle: Front Door sends traffic to App Service, which reaches Azure SQL and Key Vault through private endpoints
direction: down
# Filled triangles, as in Azure's reference diagrams; one port per edge.
arrowhead: filled
layout: { merge: false }

legend:
  solid: Request traffic
  dotted: Telemetry

groups:
  sub: { type: azure:subscription, label: Production subscription }
  rg: { type: azure:resource-group, label: rg-web-prod, in: sub }
  vnet: { type: azure:vnet, label: vnet-web-prod 10.20.0.0/16, in: rg }
  snet-app: { type: azure:subnet, label: snet-app-integration, in: vnet }
  snet-pe: { type: azure:subnet, label: snet-pe, in: vnet }

nodes:
  users: { icon: azure:users, label: Users }
  fd: { icon: azure:front-door, label: Azure Front Door, note: WAF policy, in: rg }
  # App Service is a PaaS service outside the VNet; only its integration interface sits in the subnet.
  app: { icon: azure:app-service, label: App Service, note: Web app, in: rg }
  vnet-int: { icon: azure:network-interfaces, label: Integration interface, note: Outbound traffic only, in: snet-app }
  pe-sql: { icon: azure:private-endpoint, label: Private endpoint, note: SQL Database, in: snet-pe }
  pe-kv: { icon: azure:private-endpoint, label: Private endpoint, note: Key Vault, in: snet-pe }
  sql: { icon: azure:sql, label: Azure SQL Database, in: rg }
  kv: { icon: azure:key-vault, label: Key Vault, note: Connection secrets, in: rg }
  # Private DNS zones make App Service resolve the private endpoints instead of the public ones.
  dns: { icon: azure:dns-zones, label: Private DNS zones, note: privatelink zones, in: rg }
  insights: { icon: azure:app-insights, label: Application Insights, note: Telemetry, in: rg }

edges:
  - users -> fd: HTTPS
  - fd -> app
  - app -> vnet-int: VNet integration
  - vnet-int -> pe-sql
  - pe-sql -> sql: Private Link
  - vnet-int -> pe-kv
  - pe-kv -> kv: Private Link
  - vnet-int -> dns: name resolution
  # Laid out Insights -> App Service (arrowhead at Insights) so it sits beside Front Door
  # instead of past the VNet.
  - { from: insights, to: app, arrow: start, line: dotted }
