Skip to content

Commit 0efddb2

Browse files
authored
Merge branch 'release/4' into es/ref-data-code-gen
2 parents 2ec21b3 + 36c6777 commit 0efddb2

32 files changed

Lines changed: 2198 additions & 1645 deletions

azure/AGENTS.md

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
11
---
2-
description: "Operational guidance for AI agents deploying Contoso sample services to Azure via azd/Bicep or Terraform"
2+
description: "Operational guidance for AI agents deploying Contoso sample services to Azure via azd/Bicep"
33
scope: "azure/"
4-
tags: ["azure", "deployment", "iac", "bicep", "terraform"]
4+
tags: ["azure", "deployment", "iac", "bicep"]
55
---
66

77
# AGENTS.md — Azure Deployment
88

9-
Operational guide for AI agents working in the `azure/` folder of this repository. This deploys the Contoso sample services (under `samples/src/`) to Azure using either **Azure Developer CLI (azd) + Bicep** or **Terraform**.
9+
Operational guide for AI agents working in the `azure/` folder of this repository. This deploys the Contoso sample services (under `samples/src/`) to Azure using **Azure Developer CLI (azd) + Bicep**.
1010

1111
## Scope
1212

1313
This file applies to anything under `azure/`. For application code, see the relevant `samples/` projects. Companion human-facing docs:
1414

1515
- [README.md](README.md) — azd + Bicep workflow.
16-
- [terraform/README.md](terraform/README.md) — Terraform workflow.
1716

1817
## Folder layout
1918

2019
- [azure.yaml](azure.yaml) — azd project manifest. Declares the 6 services and the pre/post hooks.
2120
- [infra/](infra/) — Bicep templates (primary IaC for `azd`).
2221
- [infra/main.bicep](infra/main.bicep) — Entry template.
23-
- [infra/modules/](infra/modules/) — Per-resource modules (`app-service-plan`, `app-services`, `aspire-dashboard`, `database`, `service-bus`, `redis`, `key-vault`, `application-insights`).
22+
- [infra/modules/](infra/modules/) — Per-resource modules (`app-service-plan`, `app-services`, `aspire-dashboard`, `database`, `postgres-database`, `service-bus`, `redis`, `key-vault`, `application-insights`).
2423
- [infra/scripts/](infra/scripts/) — Hook scripts (`use-dev-params.*`, `store-secrets.*`).
2524
- `main.{dev,test,prod}.bicepparam` — Environment parameter files.
26-
- [terraform/](terraform/) — Terraform implementation that mirrors the Bicep deployment (parity must be maintained when changing one or the other).
2725
- [scripts/](scripts/) — Higher-level deployment helper scripts (DB migrations, SQL firewall, packaging).
2826

2927
## What gets deployed
3028

31-
Both Bicep and Terraform provision the same resource set:
29+
The Bicep deployment provisions the following resource set:
3230

3331
- Linux App Service Plan.
3432
- 7 Web Apps: `aspire-dashboard`, `products-api`, `shopping-api`, `products-outbox-relay`, `shopping-outbox-relay`, `products-subscribe`, `shopping-subscribe`.
35-
- Azure SQL Server + Database (with firewall rules).
33+
- Azure SQL Server + Database (Shopping and Orders domains, with firewall rules).
34+
- Azure Database for PostgreSQL Flexible Server + Database (Products domain).
3635
- Azure Service Bus (Standard) — namespace + topic + subscriptions.
3736
- Azure Managed Redis.
3837
- Application Insights.
@@ -41,16 +40,15 @@ Both Bicep and Terraform provision the same resource set:
4140
## Conventions
4241

4342
- Comments end with a period/fullstop (repo-wide rule from [.github/copilot-instructions.md](../.github/copilot-instructions.md)).
44-
- Keep Bicep and Terraform in sync. Any new resource, parameter, or wiring change in `infra/` must have an equivalent change in `terraform/` (and vice versa). Cross-reference by env: `main.dev.bicepparam``dev.tfvars`, etc.
45-
- Resource naming, SKUs, and per-environment values are driven by the parameter/tfvars files — do not hardcode environment-specific values in templates.
43+
- Resource naming, SKUs, and per-environment values are driven by the parameter files — do not hardcode environment-specific values in templates.
4644
- Key Vault name is generated uniquely per deployment in [infra/main.bicep](infra/main.bicep). Do not assume a fixed name.
4745
- Multi-targeted .NET projects must be published with a single TFM. The TFM is sourced from `AZD_DOTNET_TARGET_FRAMEWORK` (preferred) or `DOTNET_TARGET_FRAMEWORK` and mapped to App Service Linux `DOTNETCORE|<version>` by the preprovision hook.
4846

4947
## azd hooks (defined in [azure.yaml](azure.yaml))
5048

5149
- `preprovision``infra/scripts/use-dev-params.{sh,ps1}` — selects the dev parameter file, injects `AZURE_LOCATION` and `AZURE_SQL_ADMIN_PASSWORD` into `main.parameters.json`, maps the .NET TFM to the App Service runtime.
52-
- `predeploy``scripts/run-products-db-migrations.{sh,ps1}` — runs DB migrations against the provisioned SQL DB before app code deploys.
53-
- `postprovision``infra/scripts/store-secrets.{sh,ps1}` — grants the provisioning user `Key Vault Administrator` and stores `sql-admin-password`, `sql-connection-string`, `service-bus-connection-string` in Key Vault.
50+
- `predeploy``scripts/run-products-db-migrations.{sh,ps1}` — runs domain-specific DB migrations before app code deploys: Shopping/Orders on SQL; Products on PostgreSQL. Products uses `Migrate` + `Schema` + `ResetAndData` sequence.
51+
- `postprovision``infra/scripts/store-secrets.{sh,ps1}` — grants the provisioning user `Key Vault Administrator` and stores `sql-admin-password`, `sql-connection-string`, `postgres-admin-password`, `postgres-connection-string`, `service-bus-connection-string` in Key Vault.
5452

5553
When editing hook scripts, keep the bash and PowerShell variants behaviorally identical.
5654

@@ -61,9 +59,10 @@ Set in the azd environment (`azd env set <KEY> <VALUE>`):
6159
- `AZURE_SUBSCRIPTION_ID` — target subscription.
6260
- `AZURE_LOCATION` — e.g. `eastus2`.
6361
- `AZURE_SQL_ADMIN_PASSWORD` — strong password; consumed by hooks, never committed.
62+
- `AZURE_POSTGRES_ADMIN_PASSWORD` — optional; if omitted, hooks default to `AZURE_SQL_ADMIN_PASSWORD`.
6463
- `AZD_DOTNET_TARGET_FRAMEWORK` — one of `net8.0`, `net9.0`, `net10.0`.
6564

66-
Load into the current shell before running ad-hoc `az` / `terraform` commands:
65+
Load into the current shell before running ad-hoc `az` commands:
6766

6867
```bash
6968
set -a && eval "$(azd env get-values)" && set +a
@@ -82,39 +81,62 @@ azd deploy --all --no-prompt # code-only redeploy.
8281
azd down --force --purge --no-prompt # tear down.
8382
```
8483

85-
### Terraform
84+
## Helper scripts
8685

87-
```bash
88-
cd azure/terraform
89-
./apply.sh dev plan
90-
./apply.sh dev apply
91-
```
86+
The `azure/scripts/` folder includes two helper scripts that should be preferred over manual command chains when validating a deployment.
87+
88+
### get-aspire-dashboard-login
89+
90+
- Files: `scripts/get-aspire-dashboard-login.sh`, `scripts/get-aspire-dashboard-login.ps1`.
91+
- Purpose: prints the Aspire Dashboard URL and a ready-to-open login URL when a dashboard token can be found.
92+
- Required argument: `--resource-group` / `-ResourceGroup`.
93+
- Optional arguments: dashboard app name and token timeout.
94+
- Discovery behavior: auto-detects the dashboard app when not explicitly provided.
95+
- Token retrieval order:
96+
1. SCM/Kudu command API query of runtime `container.log` (last 60 minutes).
97+
2. SCM/Kudu log archive scan.
98+
3. Live `az webapp log tail` fallback with timeout.
99+
- Output always includes dashboard app name and dashboard URL; login URL is printed only when token extraction succeeds.
100+
101+
### setup-e2e-runner
102+
103+
- Files: `scripts/setup-e2e-runner.sh`, `scripts/setup-e2e-runner.ps1`.
104+
- Purpose: wires `samples/tests/Contoso.E2E.Runner/appsettings.json` to deployed Azure endpoints and connection strings.
105+
- Required argument: `--resource-group` / `-ResourceGroup`.
106+
- Optional arguments: appsettings path, key vault name, Products app name, Shopping app name, skip-validation, insecure validation mode.
107+
- Discovery behavior: auto-detects Products and Shopping app names plus Key Vault when omitted.
108+
- Secret retrieval: reads `postgres-connection-string` and `sql-connection-string` from Key Vault.
109+
- Validation behavior (unless skipped):
110+
- `GET /api/products` for Products.
111+
- `POST /api/customers/test/baskets` for Shopping.
112+
- health and swagger endpoints for both services.
113+
- Update behavior: creates `appsettings.json.bak` before writing updated `E2E.Products` and `E2E.Shopping` values.
92114

93-
`apply.sh` loads `azd env` values, resolves the runner public IP for SQL firewall, and maps `AZD_DOTNET_TARGET_FRAMEWORK` to `app_service_linux_fx_version`.
115+
When editing either helper script, keep the bash and PowerShell variants behaviorally identical.
94116

95117
## Validating changes
96118

97119
Before declaring an infra change complete:
98120

99121
1. **Bicep**: `azd provision --preview --no-prompt` from `azure/`, or run `az deployment group what-if` against `infra/main.bicep` with `infra/main.parameters.json` after the preprovision hook has populated it.
100-
2. **Terraform**: `./apply.sh <env> plan` and confirm no unintended destroy/replace operations.
101-
3. **Parity**: diff the resource set between Bicep `what-if` and Terraform `plan` when changing either side.
102-
4. **Hooks**: if you touched `infra/scripts/` or `scripts/`, run the bash and PowerShell variants (or read them carefully) to confirm parity.
122+
2. **Hooks**: if you touched `infra/scripts/` or `scripts/`, run the bash and PowerShell variants (or read them carefully) to confirm parity.
103123

104-
Do not run `azd up`, `azd down`, `terraform apply`, or `terraform destroy` without explicit user approval — these touch live Azure resources.
124+
Do not run `azd up` or `azd down` without explicit user approval — these touch live Azure resources.
105125

106126
## Secrets and safety
107127

108-
- Never commit `AZURE_SQL_ADMIN_PASSWORD`, generated parameter files containing secrets, `terraform.tfstate*`, or any Key Vault content.
128+
- Never commit `AZURE_SQL_ADMIN_PASSWORD`, generated parameter files containing secrets, or any Key Vault content.
109129
- The post-provision hook is the canonical source for runtime secrets in Key Vault. Do not duplicate secret-storage logic elsewhere.
110-
- Treat `terraform.tfstate` as sensitive; do not print or echo it.
111-
- Avoid destructive Azure operations (`az group delete`, `azd down`, `terraform destroy`, dropping SQL DBs) unless the user has confirmed in this turn.
130+
- Avoid destructive Azure operations (`az group delete`, `azd down`, dropping SQL DBs) unless the user has confirmed in this turn.
112131

113132
## Troubleshooting cheatsheet
114133

115134
- **Multi-target publish error (NETSDK1129)** — set `AZD_DOTNET_TARGET_FRAMEWORK` and reload env.
116-
- **SQL password missing** — set `AZURE_SQL_ADMIN_PASSWORD` before `azd provision` / `terraform apply`.
135+
- **SQL password missing** — set `AZURE_SQL_ADMIN_PASSWORD` before `azd provision`.
136+
- **PostgreSQL password missing** — set `AZURE_POSTGRES_ADMIN_PASSWORD` when different from SQL admin password.
137+
- **Predeploy missing output keys** — run `azd provision --no-prompt` before `azd deploy --all --no-prompt` to refresh `sql*` and `postgres*` output values in azd env.
117138
- **API returns 404 at `/`** — expected; probe `/api/...`, `/health/ready/detailed`, or `/swagger`.
139+
- **Startup fails with invalid Service Bus/connection string right after deploy** — run `./scripts/refresh-keyvault-appsettings.sh --resource-group <rg>` (or the PowerShell variant) to refresh Key Vault references and restart apps.
118140
- **Aspire Dashboard requires token** — fetch from `az webapp log tail` (see [README.md](README.md#accessing-the-aspire-dashboard)).
119141
- **`azd init` says no project** — run from `azure/`, not the repo root.
120142

0 commit comments

Comments
 (0)