You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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**.
10
10
11
11
## Scope
12
12
13
13
This file applies to anything under `azure/`. For application code, see the relevant `samples/` projects. Companion human-facing docs:
- 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).
36
35
- Azure Service Bus (Standard) — namespace + topic + subscriptions.
37
36
- Azure Managed Redis.
38
37
- Application Insights.
@@ -41,16 +40,15 @@ Both Bicep and Terraform provision the same resource set:
41
40
## Conventions
42
41
43
42
- 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.
46
44
- Key Vault name is generated uniquely per deployment in [infra/main.bicep](infra/main.bicep). Do not assume a fixed name.
47
45
- 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.
48
46
49
47
## azd hooks (defined in [azure.yaml](azure.yaml))
50
48
51
49
-`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.
54
52
55
53
When editing hook scripts, keep the bash and PowerShell variants behaviorally identical.
56
54
@@ -61,9 +59,10 @@ Set in the azd environment (`azd env set <KEY> <VALUE>`):
61
59
-`AZURE_SUBSCRIPTION_ID` — target subscription.
62
60
-`AZURE_LOCATION` — e.g. `eastus2`.
63
61
-`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`.
64
63
-`AZD_DOTNET_TARGET_FRAMEWORK` — one of `net8.0`, `net9.0`, `net10.0`.
65
64
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:
- 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.
92
114
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.
94
116
95
117
## Validating changes
96
118
97
119
Before declaring an infra change complete:
98
120
99
121
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.
103
123
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.
105
125
106
126
## Secrets and safety
107
127
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.
109
129
- 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.
112
131
113
132
## Troubleshooting cheatsheet
114
133
115
134
-**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.
117
138
-**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.
118
140
-**Aspire Dashboard requires token** — fetch from `az webapp log tail` (see [README.md](README.md#accessing-the-aspire-dashboard)).
119
141
-**`azd init` says no project** — run from `azure/`, not the repo root.
0 commit comments