Zum Inhalt

Application Gateway (workload hinzufügen oder ändern)

Standardänderungen: workload zum Application Gateway hinzufügen und Änderungen an der workload-Konfiguration im Application Gateway.

Auswirkung: Das Hub Application Gateway erhält neue oder geänderte Backend-Pools, HTTP-Einstellungen, Listener, Routing-Regeln, Probes, Redirects oder Zertifikate, sodass ein workload hinter der Web Application Firewall (WAF) im Internet veröffentlicht wird. Nur der connectivity layer ändert sich. Das Gateway wird in place aktualisiert.

Die Runbooks für Reviewer und Operatoren zu dieser Änderung sind Application-Gateway-Änderung, Application-Gateway-Deployment und, für WAF-Policy-Dateien, WAF-Policy-Review.

Anfragefelder

Anfragefeld Wo es in der Gateway-JSON hingehört Hinweise
Workload Name Namen von Pool, Setting, Listener, Rule, Probe z. B. app1-pool, app1-https-settings, app1-https-listener, app1-rule
Begründung pull request
Umgebung Plattformumgebung und Region-Ordner
Backend Address (IP/FQDN) backend_address_pools.<pool>.ip_addresses / .fqdns Nur IPv4 (Konfigurationstest). Das Backend muss vom App-Gateway-Subnetz aus erreichbar sein.
Listener URL http_listeners.<listener>.host_name (oder host_names) z. B. app1.example.com. Lege den öffentlichen DNS-Eintrag selbst an, es sei denn, du nutzt die öffentliche DNS-Zone der Plattform.
Listener Port (HTTPS/HTTP) frontend_ports.<port> + http_listeners.<listener>.protocol / .frontend_port_name
SSL Certificate ssl_certificates.<cert>.key_vault_secret_id + http_listeners.<listener>.ssl_certificate_name Für HTTPS-Listener erforderlich (Konfigurationstest).
Redirect (ja/nein) redirect_configurations.<redirect> + request_routing_rules.<rule>.redirect_configuration_name z. B. HTTP → HTTPS
Health Probe (custom oder standard) standard: backend_http_settings.<s>.probe_name = null. Custom: probes.<probe> + probe_name
Fehlerseiten-URLs (502, 403), optional http_listeners.<listener>.custom_error_configurations Seiten, die das Gateway bei einem Bad Gateway oder einer Forbidden-Antwort anzeigt. Die Struktur steht im Gateway-Schema.
Kommentare

Bevor du anfängst

  • Das Gateway muss für die Region in <env-folder>/<region>/connectivity.auto.tfvars aktiviert sein:
use_web_application_firewall_policy_module              = true
web_application_firewall_policy_json_file_relative_path = "<region>/web_application_firewall_policies/"
web_application_firewall_policy_json_file_pattern       = "/**/web_application_firewall_policy_*.json"
use_new_application_firewall_policy_naming              = true

use_application_gateway_module              = true
application_gateway_json_file_relative_path = "<region>/application_gateways/"
application_gateway_json_file_pattern       = "/**/application_gateway_*.json"
use_new_application_gateway_naming          = true

use_application_gateway_module ist der einzige Schalter, der das Gateway aktiviert. create_application_gateway wird zwar übergeben, aber das Template überschreibt es mit true (infra/templates/application_gateway/main.tf). Siehe Plattform-Features, um das Gateway erstmalig zu aktivieren. - Zertifikate. Die Plattform erstellt einen Key Vault für das Gateway: kv<company>agw<env_short><region>001. Die user-assigned identity des Gateways uai-<company>-agw-<env>-<region>-001 erhält darauf Key Vault Secrets User. 1. Importiere die PFX als Zertifikat in diesen Key Vault. 2. Verwende dessen Secret-URI (https://<kv>.vault.azure.net/secrets/<name> oder …/<name>/<version>) als key_vault_secret_id.

Lass den Anfragenden die PFX in den Key Vault importieren. Die PFX enthält den privaten Schlüssel und oft ein Passwort, und so muss keines von beiden an das Plattform-Team geschickt werden. Importiere sie als Zertifikat (nicht als Secret), im PFX-Format, bevor du die Änderung deployst. Siehe Microsofts Tutorial Import a certificate in Azure Key Vault. Wenn die PFX ein Passwort hat, speichere das Passwort als Secret im selben Key Vault und trage dessen URI in certificate_password_secret_id ein. Verwende null, wenn es kein Passwort gibt.

Der Key Vault verweigert öffentlichen Zugriff, außer für erlaubte Subnetze. Importiere aus einem erlaubten Netzwerk oder füge deine IP vorübergehend hinzu. Um ein bereits verwendetes Zertifikat zu erneuern, folge Ein Zertifikat ersetzen.

Ersteinrichtung

Nur wenn die Plattform noch kein Gateway hat:

  1. Schalte die Module in <region>/connectivity.auto.tfvars für beide Umgebungen ein.
  2. Erstelle die Ordner application_gateways/ und web_application_firewall_policies/ im Region-Ordner.
  3. Erstelle application_gateway_hub.json und web_application_firewall_policy_hub.json mit genau diesen Namen, weil die Konfigurationstests nur application_gateway_hub.json prüfen.
  4. Deploye zuerst ein minimales Gateway: eine Frontend-IP und einen Port, einen Dummy-Backend-Pool, einen Dummy-HTTP-Listener, eine Routing-Regel, die SKU und die WAF-Konfiguration. Alle Top-Level-Keys müssen vorhanden sein (null, wenn ungenutzt, {} für ssl_certificates). Ersetze die Dummy-Werte nach dem ersten Deployment.
  5. Schreibe firewall_policy_id mit applicationGatewayWebApplicationFirewallPolicies, beginnend mit einem kleinen a (siehe den Upgrade-Leitfaden v4.12.x).
  6. Fülle die WAF-Policy-Datei. policy_settings wird nur angewendet, wenn die Policy erstellt wird.
  7. Führe hub aus und prüfe, dass nur connectivity das neue Gateway und die neue Policy zeigt.

Wie die JSON aufgebaut ist

Eine JSON-Datei beschreibt ein ganzes Gateway: application_gateway_<name>.json im Ordner application_gateways/ der Region. Um einen workload hinzuzufügen, ergänzt du Einträge in den Maps der bestehenden Datei. Jeder Map-Key ist der Azure-Name dieser Teilressource.

Konfigurationstests prüfen nur eine Datei mit exakt dem Namen application_gateway_hub.json (src/Xebia.Mcp/Tests/Config/XebiaAppGateway.Mcp.Config.Tests.ps1). Verwende diesen Namen für das Hub-Gateway, damit deine Änderungen vor dem Deployment validiert werden.

Alle Top-Level-Keys müssen vorhanden sein, dürfen aber null sein, außer ssl_certificates: Verwende {}, wenn es keine gibt. Das Modul liest jeden Key direkt (infra/modules/application_gateway/main.tf).

workload hinzufügen

Füge diese Einträge hinzu (Beispiel: HTTPS für app1.example.com → 10.20.4.10:443, mit HTTP→HTTPS-Redirect und einer custom Probe):

"frontend_ports": {
  "port-443": { "port": 443 },
  "port-80":  { "port": 80 }
},
"backend_address_pools": {
  "app1-pool": { "fqdns": [], "ip_addresses": ["10.20.4.10"] }
},
"probes": {
  "app1-probe": {
    "host": "app1.example.com",
    "interval": 30,
    "minimum_servers": 0,
    "path": "/health",
    "pick_host_name_from_backend_http_settings": false,
    "port": 443,
    "protocol": "Https",
    "timeout": 30,
    "unhealthy_threshold": 3,
    "matches": null
  }
},
"backend_http_settings": {
  "app1-https-settings": {
    "affinity_cookie_name": null,
    "authentication_certificates": null,
    "connection_drainings": null,
    "cookie_based_affinity": "Disabled",
    "host_name": "app1.example.com",
    "path": null,
    "pick_host_name_from_backend_address": false,
    "port": 443,
    "probe_name": "app1-probe",
    "protocol": "Https",
    "request_timeout": 30,
    "trusted_root_certificate_names": null
  }
},
"ssl_certificates": {
  "app1-cert": {
    "key_vault_secret_id": "https://kv<company>agw<envshort><region>001.vault.azure.net/secrets/app1-example-com",
    "certificate_password_secret_id": null
  }
},
"http_listeners": {
  "app1-https-listener": {
    "custom_error_configurations": null,
    "firewall_policy_id": null,
    "frontend_ip_configuration_name": "appGatewayFrontendIP",
    "frontend_port_name": "port-443",
    "host_name": "app1.example.com",
    "host_names": null,
    "protocol": "Https",
    "require_sni": true,
    "ssl_certificate_name": "app1-cert",
    "ssl_profile_name": null
  },
  "app1-http-listener": {
    "custom_error_configurations": null,
    "firewall_policy_id": null,
    "frontend_ip_configuration_name": "appGatewayFrontendIP",
    "frontend_port_name": "port-80",
    "host_name": "app1.example.com",
    "host_names": null,
    "protocol": "Http",
    "require_sni": null,
    "ssl_certificate_name": null,
    "ssl_profile_name": null
  }
},
"redirect_configurations": {
  "app1-http-to-https": {
    "include_path": true,
    "include_query_string": true,
    "redirect_type": "Permanent",
    "target_listener_name": "app1-https-listener",
    "target_url": null
  }
},
"request_routing_rules": {
  "app1-rule": {
    "backend_address_pool_name": "app1-pool",
    "backend_http_settings_name": "app1-https-settings",
    "http_listener_name": "app1-https-listener",
    "priority": 110,
    "redirect_configuration_name": null,
    "rewrite_rule_set_name": null,
    "rule_type": "Basic",
    "url_path_map_name": null
  },
  "app1-redirect-rule": {
    "backend_address_pool_name": null,
    "backend_http_settings_name": null,
    "http_listener_name": "app1-http-listener",
    "priority": 111,
    "redirect_configuration_name": "app1-http-to-https",
    "rewrite_rule_set_name": null,
    "rule_type": "Basic",
    "url_path_map_name": null
  }
}

Führe diese Einträge mit den vorhandenen Maps zusammen; ersetze sie nicht. Wenn die Frontend-Ports bereits existieren, verwende deren Namen weiter.

Achte darauf, dass protocol eines Listeners und sein frontend_port_name zusammenpassen: Ein Https-Listener verwendet den HTTPS-Port (im Beispiel 443), ein Http-Listener den HTTP-Port (80). Eine custom Probe braucht protocol, host, path, interval, timeout und unhealthy_threshold. Statt eines festen host_name kann eine HTTP-Einstellung den Host-Namen aus der Backend-Adresse übernehmen: Setze pick_host_name_from_backend_address auf true und host_name auf null.

Regeln, die die Konfigurationstests prüfen:

  • priority der Routing-Regel muss zwischen 1 und 20000 liegen und eindeutig sein;
  • jeder Listener darf nur von einer Routing-Regel verwendet werden;
  • jede Referenz (Pool, Setting, Listener, Port, Zertifikat) muss auf einen vorhandenen Key zeigen;
  • HTTPS-Listener müssen ssl_certificate_name haben;
  • Backend-IPs müssen gültige IPv4-Adressen sein.

Standard- vs. custom Health Probe. Mit probe_name: null verwendet das Gateway die Azure-Standard-Probe für dieses HTTP- Setting. Um eine custom Probe zu verwenden, definiere sie unter probes und referenziere sie in probe_name.

WAF-Policy für den workload

  • Gateway-weite WAF: application_gateway.firewall_policy_id (vollständige Ressourcen-ID der WAF-Policy).
  • WAF pro Listener: Setze http_listeners.<listener>.firewall_policy_id auf die Ressourcen-ID einer anderen WAF-Policy.
  • WAF pro Pfad: url_path_maps.<map>.path_rules.<rule>.firewall_policy_id.

WAF-Policies sind separate Dateien: <region>/web_application_firewall_policies/web_application_firewall_policy_<name>.json. Sie werden in der resource group rg-<company>-agw-<env>-<region>-001 erstellt, es sei denn, overwrite_rg_name_application_gateway ist gesetzt. Bilde die firewall_policy_id aus diesem resource group-Namen und dem name der Policy.

policy_settings wird nur angewendet, wenn eine WAF-Policy erstellt wird. infra/modules/web_application_firewall_policy/main.tf enthält lifecycle { ignore_changes = [policy_settings] }, weil Azure Policy diese Einstellungen laufend ändert. Spätere Änderungen an mode (Detection/Prevention), Body-Größenlimits und ähnlichen Einstellungen werden nicht deployt. Ändere sie im Portal und dokumentiere die Änderung, oder erstelle eine neue Policy. Custom Rules und Managed-Rule-Overrides werden aktualisiert.

WAF-False-Positives und Ausschlüsse

Eine WAF im Prevention-Modus blockiert Anfragen, die zu ihren Managed Rules passen. Manchmal wird eine legitime Anfrage blockiert, zum Beispiel eine Anfrage mit vielen Sonderzeichen in einem Argument. Behandle das als Ausnahme:

  1. Das workload-Team gibt dem Plattform-Team die blockierte Anfrage (URI, Name des Arguments oder Headers, die Regel-ID aus dem WAF-Log) und erklärt, warum es ein False Positive ist.
  2. Security genehmigt die Ausnahme.
  3. Das Plattform-Team fügt in der WAF-Policy-Datei einen eng gefassten Ausschluss hinzu (zum Beispiel für ein Argument und die Regeln, die darauf anschlagen) oder deaktiviert eine Regel, deren Deaktivierung Microsoft bei False Positives empfiehlt. Halte die Begründung und die Beispielanfrage im Änderungsdatensatz fest.

Bevorzuge einen Ausschluss für das eine Argument gegenüber dem Deaktivieren einer Regel. Führe eine Liste der Ausschlüsse und deaktivierten Regeln mit ihrer Begründung, damit du sie später prüfen kannst. Das Gateway-Modul der Shared Services unterstützt außerdem Ausnahmen, die auf eine Client-IP-Adresse, einen Request-Header oder eine URI passen, mit festen Limits und Validierung zur plan-Zeit: siehe WAF-Ausnahmen. Ob das hub-Modul sie unterstützt, ist nicht dokumentiert. Die genauen Keys stehen im WAF-Policy-Schema. Custom Rules und Managed-Rule-Overrides werden von hub aktualisiert, beachte aber den Hinweis zu policy_settings oben.

Einstellungen, die du für die WAF festlegen solltest

Eine Plattform verwendete: Gateway-SKU WAF v2 mit Autoscaling zwischen 2 und 5 Instanzen, HTTP/2 an, eine TLS-Policy mit mindestens TLS 1.2, WAF-Modus Prevention, das OWASP-3.2-Regelwerk, Request-Body-Inspektion an und Log Scrubbing an. Deine Plattform kann abweichen. Schreibe die Werte auf, die du wählst.

Netzwerkpfad zum Backend

Das Backend muss Traffic aus dem App-Gateway-Subnetz akzeptieren (AppGwSubnet im Hub-Virtual-Network). Wenn dieser Traffic die Hub-firewall durchquert, füge eine Firewallregel vom App-Gateway-Subnetz zum Backend hinzu (Firewallregeln). Prüfe auch die NSG des spokes.

Bestehenden workload ändern

Bearbeite die Einträge des workloads direkt: Backend-Adresse, Hostname, Zertifikat, Probe oder Redirect. Wenn du einen Map-Key umbenennst, wird die Teilressource umbenannt. Aktualisiere alle Referenzen darauf in derselben Änderung.

Variante: Gateway aus dem Shared-Services-Code

Der Shared-Services-Code (Shared Services: was deployt wird und wie) enthält eine zweite Implementierung des Application Gateway, das Addon appgw. Anhand der Tabelle siehst du, welche Implementierung deine Plattform betreibt. Die Abschnitte oben beschreiben das hub-Modul.

Thema Hub-Modul (diese Seite) Shared-Services-Addon appgw
Layer und Ort layer connectivity, AppGwSubnet im hub virtual network Eigenes Deployment in einem spoke, AppGwSubnet im spoke virtual network
Konfiguration application_gateway_hub.json und web_application_firewall_policy_*.json im Regionsordner der Plattformkonfiguration JSON-Dateien in gateway-definitions/ und waf-definitions/ des Addons, mit einer Variablendatei
Ressourcennamen rg-<company>-agw-<env>-<region>-001, kv<company>agw<env_short><region>001 rg-agw-<environment>-<location_short>-001, agw-<environment>-<location_short>-001, kv-agw-<environment>-<location_short>-<random>
Zertifikatsspeicher Key Vault, das die Plattform erstellt, Key Vault Secrets User für die Gateway-Identity Key Vault mit Private Endpoint und RBAC, die Gateway-Identity erhält Key Vault Certificates Officer und Key Vault Secrets User
WAF-Policy des Gateways Gesetzt mit firewall_policy_id in der Gateway-JSON Aus der Datei web_application_firewall_policy_hub.json
policy_settings nach der Erstellung Ignoriert (nicht deployt) Deployt. Wenn du den name der Policy änderst, wird die Policy ersetzt.
WAF-Ausnahmen Nicht dokumentiert Unterstützt, mit Limits und Prüfungen (WAF-Ausnahmen)
Deployment pipeline hub, layer connectivity In den Quellen nicht Teil der Shared-Services-pipeline. Frag nach, wie deine Plattform es deployt.

Für das Shared-Services-Addon verwenden die workload-Einträge (Pools, Settings, Listener, Rules, Probes, Zertifikate) dieselben Sub-Ressourcen-Namen und Felder wie unter Einen workload hinzufügen. Prüfe das Wrapper-Objekt der Datei gegen den Code (die Shared-Services-Dateien haben ein Objekt application_gateway auf oberster Ebene). Das Zertifikat muss im Key Vault dieses Gateways liegen, und das Backend muss vom Gateway-Subnet im spoke erreichbar sein.

Deployen

  1. Validiere lokal (pwsh ./dev/dev.ps1 -Action Test mit MCP_CONFIG, das auf deine mcp.json zeigt, siehe Tests lokal ausführen) und öffne einen pull request.
  2. Führe hub aus. Nur der connectivity layer sollte ~ update in-place von azurerm_application_gateway.this[...] zeigen, plus eventuelle WAF-Policy-Änderungen.
  3. Apply. Updates des Application Gateway können mehrere Minuten dauern.

Logs

Das Gateway und die WAF können ihre Logs über Diagnoseeinstellungen an einen Log-Analytics-workspace senden. Je nach diesen Einstellungen liegen die Einträge in der Tabelle AzureDiagnostics oder in ressourcenspezifischen Tabellen. Gib den Personen, die veröffentlichte Apps analysieren, Lesezugriff auf die Logs der Gateway-Ressource und nicht auf den gesamten workspace.

Prüfen

  • Azure portal → Application Gateway → Backend health: Der neue Pool ist Healthy.
  • curl -v https://app1.example.com/ aus dem Internet liefert die Antwort des Backends. Prüfe, ob das Zertifikat passt.
  • Wenn ein Redirect konfiguriert ist, liefert curl -I http://app1.example.com/ 301 mit Location: https://….

Rollback

Mache den pull request rückgängig und führe hub aus.

Häufige Probleme

Symptom Ursache
Backend health Unhealthy NSG oder firewall blockiert das Gateway; Probe-Pfad/-Host ist falsch; oder dem Backend-Zertifikat wird nicht vertraut (trusted_root_certificate_names).
Apply schlägt beim Lesen des Zertifikats fehl Die Secret-URI ist falsch, der Identity fehlt Key Vault Secrets User, oder Key-Vault-Netzwerkregeln blockieren den Zugriff.
Plan-Fehler bei ssl_certificates ssl_certificates ist null. Verwende {}.
Änderung des WAF-Modus nicht angewendet policy_settings wird nach der Erstellung ignoriert (siehe oben).
Plan zeigt überhaupt kein Gateway use_application_gateway_module = false für diese Region.