Port the Vacation Planner web app samples to .NET 10 - #120
Conversation
Use the Azure-scoped emulator host as the azurerm provider metadata_host in every sample's providers.tf and in the Terraform READMEs that quote it, so the documented configuration matches what the deploy scripts apply. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…mples Introduce the ASP.NET Core Razor Pages port of the Vacation Planner used by every web-app sample: one Index page with TempData flash messages, a Delete page keyed on the store id, an IActivityStore abstraction initialized at startup, a /health endpoint, and Kestrel binding to the PORT that App Service and the emulator inject. The custom-image variant serves the same info page and /api/status from a multi-stage sdk:10.0 -> aspnet:10.0 image; the managed-identity variant stores one blob per activity through DefaultAzureCredential. Deployment artifacts mirror the Python siblings: DOTNETCORE|10.0 code deployment with the project source zipped for the Oryx build, dotnet_version in Terraform, runtimeName 'dotnetcore' in Bicep, unchanged WEBSITES_PORT values and validation scripts. Register both samples in run-samples.sh, link them from the root README and normalize line endings for C# sources. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ry sample in the root README
The Vacation Planner reads its SQL connection string from the Key Vault
secret (falling back to SQL_* variables or a Microsoft Entra token), serves
HTTPS on port 8443 with the Key Vault certificate, and exposes /update/{id}
and /api/certificate like the Python sample; get-web-app-url.sh now fails
when the 8443 endpoint or its certificate cannot be retrieved instead of
comparing two empty thumbprints. InvariantGlobalization is dropped from the
template because Microsoft.Data.SqlClient cannot open connections in
invariant mode.
The root README outline gains an introduction, a longer description per
sample, the implementation language in parentheses, and separate Python and
.NET links for the web-app samples.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
MySqlConnector store with the same idempotent DDL, md5 ids, 30x2s startup retry and TLS-without-verification semantics (MYSQL_SSL) as the Python sample; artifacts switch to DOTNETCORE|10.0 with a source zip for the Oryx build, dotnet_version in Terraform and 'dotnetcore' in Bicep. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Npgsql store with the same DDL, indexes, md5 ids, 30x2s startup retry and libpq "prefer" TLS semantics as the Python sample; artifacts switch to DOTNETCORE|10.0 with a source zip for the Oryx build, dotnet_version in Terraform and 'dotnetcore' in Bicep. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
MongoDB.Driver store keeping the {_id, username, activity, timestamp}
documents, md5 ids and the three indexes of the Python sample, created once at
startup instead of on every operation; artifacts switch to DOTNETCORE|10.0
with a source zip for the Oryx build, dotnet_version in Terraform and
'dotnetcore' in Bicep. call-web-app.sh probes container port 8000, the port
this sample sets through WEBSITES_PORT, instead of 80.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Microsoft.Azure.Cosmos store in Gateway mode (the emulator exposes the account
endpoint over HTTPS only), keeping the {id, username, activity, timestamp}
items partitioned by /username, the 400 RU container created on demand and
id-keyed deletes of the Python sample; scripts-only deployment as in the
Python sibling, switched to DOTNETCORE:10.0 with a source zip.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The port kept only the startup and store-initialization logs, so nothing
appeared in the container log while adding, updating or deleting an activity —
unlike the Python samples, which log a gunicorn access line per request, the
store operation (with the affected documents) and an application-level
"Activity added/updated" line.
Add the same three layers to every .NET sample: a one-line access log
("POST / -> 302 in 45.3ms") from a small middleware, the store operation with
its documents or affected-row counts, and "Activity added/updated/deleted" from
the page handlers. Each store logs at the granularity its Python counterpart
does: full documents for Cosmos DB (MongoDB and NoSQL APIs), blob names and
sizes for Blob Storage, row counts and ids for SQL Database, retrieval counts
for the MySQL and PostgreSQL flexible servers.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The .NET sample now carries its own Visio drawing and rendered PNG instead of the copies inherited from the Python sibling. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ample in CI The .NET SQL Database sample's get-web-app-url.sh becomes call-web-app.sh, the name every other sample uses and the one its Python sibling's README already documented; the Python script is renamed with it so both run-samples.sh entries resolve. The renamed .NET copy keeps the strict certificate checks (a failed call, an empty thumbprint or a missing TLS certificate now exit 1 instead of comparing two empty strings). Also from manual validation of the samples: the Terraform deployments use the local-* resource naming of the script deployments and pass secret_name through, and the validate/README instructions show how to read the web app host name. Register samples/web-app-cosmosdb-nosql-api/dotnet in run-samples.sh; it was the only validated .NET web app missing from the matrix, which now builds 17 web-app-*/dotnet jobs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
There are Terraform type errors in newly added modules and at least one .NET sample diverges from the PR-stated “flash message parity” requirement.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR ports the “Vacation Planner” Azure Web App samples to .NET 10 (ASP.NET Core Razor Pages) and aligns deployment artifacts (scripts/Terraform/Bicep) so the samples ship in both Python and .NET with consistent emulator-friendly configuration.
Changes:
- Adds new
.NET 10sample implementations (Razor Pages) plus supporting scripts/infra for multipleweb-app-*variants. - Updates Terraform provider configuration across samples to use
metadata_host = "azure.localhost.localstack.cloud:4566". - Extends
.gitattributesto enforce LF endings for C#-related files.
File summaries
| File | Description |
|---|---|
| samples/web-app-sql-database/python/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-sql-database/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-sql-database/python/terraform/deploy.sh | Adjusts naming and passes secret_name into Terraform plan. |
| samples/web-app-sql-database/dotnet/terraform/terraform.tfvars | Adds location and dotnet_version inputs for Terraform. |
| samples/web-app-sql-database/dotnet/terraform/providers.tf | Adds Terraform provider configuration for .NET sample. |
| samples/web-app-sql-database/dotnet/terraform/outputs.tf | Exposes Terraform outputs for deployed resources. |
| samples/web-app-sql-database/dotnet/src/VacationPlanner.csproj | Introduces .NET 10 web project and package dependencies. |
| samples/web-app-sql-database/dotnet/src/Services/StoreInitializer.cs | Adds hosted startup initialization/retry helper. |
| samples/web-app-sql-database/dotnet/src/Services/IActivityStore.cs | Defines storage abstraction for activity persistence. |
| samples/web-app-sql-database/dotnet/src/Pages/Update.cshtml.cs | Implements update redirect handler. |
| samples/web-app-sql-database/dotnet/src/Pages/Update.cshtml | Adds Razor page route for update. |
| samples/web-app-sql-database/dotnet/src/Pages/Index.cshtml.cs | Implements list/add/update UI handler logic. |
| samples/web-app-sql-database/dotnet/src/Pages/Delete.cshtml.cs | Implements delete handler logic. |
| samples/web-app-sql-database/dotnet/src/Pages/Delete.cshtml | Adds Razor page route for delete. |
| samples/web-app-sql-database/dotnet/src/Pages/_ViewImports.cshtml | Adds Razor imports/tag helpers. |
| samples/web-app-sql-database/dotnet/src/Models/Activity.cs | Introduces shared activity model. |
| samples/web-app-sql-database/dotnet/src/appsettings.json | Adds ASP.NET Core logging defaults. |
| samples/web-app-sql-database/dotnet/scripts/validate.sh | Adds CLI validation script for deployed resources. |
| samples/web-app-sql-database/dotnet/bicep/main.bicepparam | Adds Bicep parameterization for .NET runtime. |
| samples/web-app-postgresql-flexible-server/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/terraform.tfvars | Adds prefix/suffix/location inputs for Terraform. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/providers.tf | Adds Terraform provider configuration for .NET sample. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/outputs.tf | Exposes Terraform outputs for deployed resources. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/web_app/outputs.tf | Outputs for web app module resources. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/web_app/main.tf | Defines Linux Web App with .NET stack and diagnostics. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/virtual_network/variables.tf | Inputs for virtual network module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/virtual_network/outputs.tf | Outputs for virtual network module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/private_endpoint/outputs.tf | Outputs for private endpoint module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/private_endpoint/main.tf | Defines Private Endpoint + DNS zone group. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/private_dns_zone/variables.tf | Inputs for private DNS zone module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/private_dns_zone/outputs.tf | Outputs for private DNS zone module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/private_dns_zone/main.tf | Creates private DNS zone and VNet links. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/postgres_flexible_server/outputs.tf | Outputs for PostgreSQL flexible server module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/postgres_flexible_server/main.tf | Defines PostgreSQL flexible server + DB + firewall + diagnostics. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/network_security_group/variables.tf | Inputs for NSG module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/network_security_group/outputs.tf | Outputs for NSG module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/nat_gateway/variables.tf | Inputs for NAT gateway module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/nat_gateway/output.tf | Outputs for NAT gateway module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/nat_gateway/main.tf | Defines NAT gateway + associations. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/log_analytics/variables.tf | Inputs for Log Analytics module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/log_analytics/output.tf | Outputs for Log Analytics module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/log_analytics/main.tf | Defines Log Analytics workspace. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/app_service_plan/variables.tf | Inputs for App Service Plan module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/app_service_plan/outputs.tf | Outputs for App Service Plan module. |
| samples/web-app-postgresql-flexible-server/dotnet/terraform/modules/app_service_plan/main.tf | Defines service plan + diagnostics. |
| samples/web-app-postgresql-flexible-server/dotnet/src/VacationPlanner.csproj | Introduces .NET 10 web project and Npgsql dependency. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Services/StoreInitializer.cs | Adds hosted startup initialization/retry helper. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Services/PostgresOptions.cs | Reads and validates env-var configuration. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Services/IActivityStore.cs | Defines activity store abstraction. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Services/ActivityId.cs | Implements shared activity ID generation. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Program.cs | Configures Razor Pages app, access logging, /health. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Pages/Index.cshtml.cs | Implements list/add/update UI handler logic. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Pages/Delete.cshtml.cs | Implements delete handler logic. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Pages/Delete.cshtml | Adds Razor page route for delete. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Pages/_ViewImports.cshtml | Adds Razor imports/tag helpers. |
| samples/web-app-postgresql-flexible-server/dotnet/src/Models/Activity.cs | Introduces shared activity model. |
| samples/web-app-postgresql-flexible-server/dotnet/src/appsettings.json | Adds ASP.NET Core logging defaults. |
| samples/web-app-postgresql-flexible-server/dotnet/bicep/modules/private-dns-zone.bicep | Adds Bicep module for private DNS zone. |
| samples/web-app-postgresql-flexible-server/dotnet/bicep/modules/log-analytics.bicep | Adds Bicep module for Log Analytics workspace. |
| samples/web-app-postgresql-flexible-server/dotnet/bicep/main.bicepparam | Adds Bicep parameterization for .NET runtime and PG settings. |
| samples/web-app-mysql-flexible-server/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/terraform.tfvars | Adds prefix/suffix/location inputs for Terraform. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/providers.tf | Adds Terraform provider configuration for .NET sample. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/outputs.tf | Exposes Terraform outputs for deployed resources. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/web_app/outputs.tf | Outputs for web app module resources. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/web_app/main.tf | Defines Linux Web App with .NET stack and diagnostics. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/virtual_network/variables.tf | Inputs for virtual network module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/virtual_network/outputs.tf | Outputs for virtual network module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/private_endpoint/outputs.tf | Outputs for private endpoint module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/private_endpoint/main.tf | Defines Private Endpoint + DNS zone group. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/private_dns_zone/variables.tf | Inputs for private DNS zone module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/private_dns_zone/outputs.tf | Outputs for private DNS zone module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/private_dns_zone/main.tf | Creates private DNS zone and VNet links. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/network_security_group/variables.tf | Inputs for NSG module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/network_security_group/outputs.tf | Outputs for NSG module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/nat_gateway/variables.tf | Inputs for NAT gateway module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/nat_gateway/output.tf | Outputs for NAT gateway module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/nat_gateway/main.tf | Defines NAT gateway + associations. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/mysql_flexible_server/outputs.tf | Outputs for MySQL flexible server module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/log_analytics/variables.tf | Inputs for Log Analytics module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/log_analytics/output.tf | Outputs for Log Analytics module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/log_analytics/main.tf | Defines Log Analytics workspace. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/app_service_plan/variables.tf | Inputs for App Service Plan module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/app_service_plan/outputs.tf | Outputs for App Service Plan module. |
| samples/web-app-mysql-flexible-server/dotnet/terraform/modules/app_service_plan/main.tf | Defines service plan + diagnostics. |
| samples/web-app-mysql-flexible-server/dotnet/src/VacationPlanner.csproj | Introduces .NET 10 web project and MySqlConnector dependency. |
| samples/web-app-mysql-flexible-server/dotnet/src/Services/StoreInitializer.cs | Adds hosted startup initialization/retry helper. |
| samples/web-app-mysql-flexible-server/dotnet/src/Services/MySqlOptions.cs | Reads and validates env-var configuration. |
| samples/web-app-mysql-flexible-server/dotnet/src/Services/IActivityStore.cs | Defines activity store abstraction. |
| samples/web-app-mysql-flexible-server/dotnet/src/Services/ActivityId.cs | Implements shared activity ID generation. |
| samples/web-app-mysql-flexible-server/dotnet/src/Program.cs | Configures Razor Pages app, access logging, /health. |
| samples/web-app-mysql-flexible-server/dotnet/src/Pages/Index.cshtml.cs | Implements list/add/update UI handler logic. |
| samples/web-app-mysql-flexible-server/dotnet/src/Pages/Delete.cshtml.cs | Implements delete handler logic. |
| samples/web-app-mysql-flexible-server/dotnet/src/Pages/Delete.cshtml | Adds Razor page route for delete. |
| samples/web-app-mysql-flexible-server/dotnet/src/Pages/_ViewImports.cshtml | Adds Razor imports/tag helpers. |
| samples/web-app-mysql-flexible-server/dotnet/src/Models/Activity.cs | Introduces shared activity model. |
| samples/web-app-mysql-flexible-server/dotnet/src/appsettings.json | Adds ASP.NET Core logging defaults. |
| samples/web-app-mysql-flexible-server/dotnet/bicep/modules/private-dns-zone.bicep | Adds Bicep module for private DNS zone. |
| samples/web-app-mysql-flexible-server/dotnet/bicep/modules/log-analytics.bicep | Adds Bicep module for Log Analytics workspace. |
| samples/web-app-mysql-flexible-server/dotnet/bicep/main.bicepparam | Adds Bicep parameterization for .NET runtime and MySQL settings. |
| samples/web-app-managed-identity/python/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-managed-identity/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-managed-identity/dotnet/terraform/terraform.tfvars | Adds location and dotnet_version inputs for Terraform. |
| samples/web-app-managed-identity/dotnet/terraform/providers.tf | Adds Terraform provider configuration for .NET sample. |
| samples/web-app-managed-identity/dotnet/terraform/outputs.tf | Exposes Terraform outputs for deployed resources. |
| samples/web-app-managed-identity/dotnet/src/VacationPlanner.csproj | Introduces .NET 10 web project and Azure SDK deps. |
| samples/web-app-managed-identity/dotnet/src/Services/StoreInitializer.cs | Adds hosted startup initialization/retry helper. |
| samples/web-app-managed-identity/dotnet/src/Services/IActivityStore.cs | Defines activity store abstraction. |
| samples/web-app-managed-identity/dotnet/src/Services/BlobStorageOptions.cs | Reads env-var configuration for blob storage. |
| samples/web-app-managed-identity/dotnet/src/Program.cs | Configures Razor Pages app, access logging, /health. |
| samples/web-app-managed-identity/dotnet/src/Pages/Index.cshtml.cs | Implements list/add/update UI handler logic. |
| samples/web-app-managed-identity/dotnet/src/Pages/Delete.cshtml.cs | Implements delete handler logic. |
| samples/web-app-managed-identity/dotnet/src/Pages/Delete.cshtml | Adds Razor page route for delete. |
| samples/web-app-managed-identity/dotnet/src/Pages/_ViewImports.cshtml | Adds Razor imports/tag helpers. |
| samples/web-app-managed-identity/dotnet/src/Models/Activity.cs | Introduces shared activity model. |
| samples/web-app-managed-identity/dotnet/src/appsettings.json | Adds ASP.NET Core logging defaults. |
| samples/web-app-managed-identity/dotnet/bicep/main.bicepparam | Adds Bicep parameterization for .NET runtime. |
| samples/web-app-custom-image/python/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-custom-image/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-custom-image/dotnet/terraform/terraform.tfvars | Adds prefix/suffix/location inputs for Terraform. |
| samples/web-app-custom-image/dotnet/terraform/push_image.sh | Adds image build/tag/push helper for ACR. |
| samples/web-app-custom-image/dotnet/terraform/providers.tf | Adds Terraform provider configuration for .NET sample. |
| samples/web-app-custom-image/dotnet/terraform/outputs.tf | Exposes Terraform outputs for deployed resources. |
| samples/web-app-custom-image/dotnet/terraform/modules/web_app/outputs.tf | Outputs for web app module resources. |
| samples/web-app-custom-image/dotnet/terraform/modules/virtual_network/variables.tf | Inputs for virtual network module. |
| samples/web-app-custom-image/dotnet/terraform/modules/virtual_network/outputs.tf | Outputs for virtual network module. |
| samples/web-app-custom-image/dotnet/terraform/modules/virtual_network/main.tf | Defines virtual network/subnets/diagnostics. |
| samples/web-app-custom-image/dotnet/terraform/modules/private_endpoint/variables.tf | Inputs for private endpoint module. |
| samples/web-app-custom-image/dotnet/terraform/modules/private_endpoint/outputs.tf | Outputs for private endpoint module. |
| samples/web-app-custom-image/dotnet/terraform/modules/private_endpoint/main.tf | Defines Private Endpoint + DNS zone group. |
| samples/web-app-custom-image/dotnet/terraform/modules/private_dns_zone/variables.tf | Inputs for private DNS zone module. |
| samples/web-app-custom-image/dotnet/terraform/modules/private_dns_zone/outputs.tf | Outputs for private DNS zone module. |
| samples/web-app-custom-image/dotnet/terraform/modules/private_dns_zone/main.tf | Creates private DNS zone and VNet links. |
| samples/web-app-custom-image/dotnet/terraform/modules/network_security_group/variables.tf | Inputs for NSG module. |
| samples/web-app-custom-image/dotnet/terraform/modules/network_security_group/outputs.tf | Outputs for NSG module. |
| samples/web-app-custom-image/dotnet/terraform/modules/nat_gateway/variables.tf | Inputs for NAT gateway module. |
| samples/web-app-custom-image/dotnet/terraform/modules/nat_gateway/output.tf | Outputs for NAT gateway module. |
| samples/web-app-custom-image/dotnet/terraform/modules/nat_gateway/main.tf | Defines NAT gateway with IP prefix + associations. |
| samples/web-app-custom-image/dotnet/terraform/modules/managed_identity/variables.tf | Inputs for managed identity module. |
| samples/web-app-custom-image/dotnet/terraform/modules/managed_identity/output.tf | Outputs for managed identity module. |
| samples/web-app-custom-image/dotnet/terraform/modules/managed_identity/main.tf | Defines user-assigned identity + AcrPull role. |
| samples/web-app-custom-image/dotnet/terraform/modules/log_analytics/variables.tf | Inputs for Log Analytics module. |
| samples/web-app-custom-image/dotnet/terraform/modules/log_analytics/output.tf | Outputs for Log Analytics module. |
| samples/web-app-custom-image/dotnet/terraform/modules/log_analytics/main.tf | Defines Log Analytics workspace. |
| samples/web-app-custom-image/dotnet/terraform/modules/container_registry/variables.tf | Inputs for ACR module. |
| samples/web-app-custom-image/dotnet/terraform/modules/container_registry/output.tf | Outputs for ACR module. |
| samples/web-app-custom-image/dotnet/terraform/modules/container_registry/main.tf | Defines ACR + identity + diagnostics. |
| samples/web-app-custom-image/dotnet/terraform/modules/app_service_plan/variables.tf | Inputs for App Service Plan module. |
| samples/web-app-custom-image/dotnet/terraform/modules/app_service_plan/outputs.tf | Outputs for App Service Plan module. |
| samples/web-app-custom-image/dotnet/terraform/modules/app_service_plan/main.tf | Defines service plan + diagnostics. |
| samples/web-app-custom-image/dotnet/terraform/deploy.sh | Adds Terraform deployment script for custom-image variant. |
| samples/web-app-custom-image/dotnet/src/VacationPlanner.csproj | Introduces .NET 10 web project for container image. |
| samples/web-app-custom-image/dotnet/src/Program.cs | Configures status endpoints and /health. |
| samples/web-app-custom-image/dotnet/src/Pages/Index.cshtml.cs | Renders deployment metadata into page. |
| samples/web-app-custom-image/dotnet/src/Pages/Index.cshtml | Adds Razor UI for custom-image sample. |
| samples/web-app-custom-image/dotnet/src/Pages/_ViewImports.cshtml | Adds Razor imports/tag helpers. |
| samples/web-app-custom-image/dotnet/src/Dockerfile | Adds multi-stage .NET 10 Docker build/publish image. |
| samples/web-app-custom-image/dotnet/src/appsettings.json | Adds ASP.NET Core logging defaults. |
| samples/web-app-custom-image/dotnet/src/AppInfo.cs | Adds helper for app/image/host metadata. |
| samples/web-app-custom-image/dotnet/src/.dockerignore | Adds Docker ignore patterns for build context. |
| samples/web-app-custom-image/dotnet/scripts/call-web-app.sh | Adds simple script to call status endpoint. |
| samples/web-app-custom-image/dotnet/bicep/modules/private-dns-zone.bicep | Adds Bicep module for private DNS zone. |
| samples/web-app-custom-image/dotnet/bicep/modules/managed-identity.bicep | Adds Bicep module for ACR pull identity. |
| samples/web-app-custom-image/dotnet/bicep/modules/log-analytics.bicep | Adds Bicep module for Log Analytics workspace. |
| samples/web-app-custom-image/dotnet/bicep/main.bicepparam | Adds Bicep parameters for image deployment. |
| samples/web-app-custom-image/dotnet/bicep/acr.bicepparam | Adds Bicep parameters for ACR provisioning. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/VacationPlanner.csproj | Introduces .NET 10 web project and Cosmos SDK deps. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Services/StoreInitializer.cs | Adds hosted startup initialization/retry helper. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Services/IActivityStore.cs | Defines activity store abstraction. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Services/CosmosOptions.cs | Reads and validates env-var configuration. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Services/ActivityId.cs | Implements shared activity ID generation. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Services/ActivityDocument.cs | Defines Cosmos document shape shared with Python. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Program.cs | Configures Razor Pages app, access logging, /health. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Pages/Index.cshtml.cs | Implements list/add/update UI handler logic. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Pages/Delete.cshtml.cs | Implements delete handler logic. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Pages/Delete.cshtml | Adds Razor page route for delete. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Pages/_ViewImports.cshtml | Adds Razor imports/tag helpers. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/Models/Activity.cs | Introduces shared activity model. |
| samples/web-app-cosmosdb-nosql-api/dotnet/src/appsettings.json | Adds ASP.NET Core logging defaults. |
| samples/web-app-cosmosdb-nosql-api/dotnet/scripts/validate.sh | Adds CLI validation script for deployed resources. |
| samples/web-app-cosmosdb-mongodb-api/python/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-cosmosdb-mongodb-api/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/terraform.tfvars | Adds prefix/suffix/location inputs for Terraform. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/providers.tf | Adds Terraform provider configuration for .NET sample. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/outputs.tf | Exposes Terraform outputs for deployed resources. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/web_app/outputs.tf | Outputs for web app module resources. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/virtual_network/variables.tf | Inputs for virtual network module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/virtual_network/outputs.tf | Outputs for virtual network module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/virtual_network/main.tf | Defines virtual network/subnets/diagnostics. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/storage_account/outputs.tf | Outputs for storage account module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/storage_account/main.tf | Defines storage account with network rules + identity. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/private_endpoint/outputs.tf | Outputs for private endpoint module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/private_endpoint/main.tf | Defines Private Endpoint + DNS zone group. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/private_dns_zone/variables.tf | Inputs for private DNS zone module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/private_dns_zone/outputs.tf | Outputs for private DNS zone module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/private_dns_zone/main.tf | Creates private DNS zone and VNet links. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/network_security_group/variables.tf | Inputs for NSG module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/network_security_group/outputs.tf | Outputs for NSG module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/nat_gateway/variables.tf | Inputs for NAT gateway module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/nat_gateway/output.tf | Outputs for NAT gateway module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/nat_gateway/main.tf | Defines NAT gateway + associations. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/log_analytics/variables.tf | Inputs for Log Analytics module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/log_analytics/output.tf | Outputs for Log Analytics module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/log_analytics/main.tf | Defines Log Analytics workspace. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/cosmosdb_mongodb/outputs.tf | Outputs for Cosmos Mongo module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/app_service_plan/variables.tf | Inputs for App Service Plan module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/app_service_plan/outputs.tf | Outputs for App Service Plan module. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/terraform/modules/app_service_plan/main.tf | Defines service plan + diagnostics. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/VacationPlanner.csproj | Introduces .NET 10 web project and MongoDB.Driver dependency. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Services/StoreInitializer.cs | Adds hosted startup initialization/retry helper. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Services/MongoOptions.cs | Reads and validates env-var configuration. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Services/IActivityStore.cs | Defines activity store abstraction. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Services/ActivityId.cs | Implements shared activity ID generation. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Program.cs | Configures Razor Pages app, access logging, /health. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Pages/Index.cshtml.cs | Implements list/add/update UI handler logic. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Pages/Delete.cshtml.cs | Implements delete handler logic. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Pages/Delete.cshtml | Adds Razor page route for delete. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Pages/_ViewImports.cshtml | Adds Razor imports/tag helpers. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/Models/Activity.cs | Introduces shared activity model. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/src/appsettings.json | Adds ASP.NET Core logging defaults. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/bicep/modules/private-dns-zone.bicep | Adds Bicep module for private DNS zone. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/bicep/modules/log-analytics.bicep | Adds Bicep module for Log Analytics workspace. |
| samples/web-app-cosmosdb-mongodb-api/dotnet/bicep/main.bicepparam | Adds Bicep parameterization for .NET runtime and Cosmos settings. |
| samples/url-shortener/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/servicebus/java/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/servicebus/java/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/function-app-storage-http/dotnet/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/function-app-storage-http/dotnet/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/function-app-service-bus/dotnet/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/function-app-service-bus/dotnet/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/function-app-managed-identity/python/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/function-app-managed-identity/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/eventhubs/python/terraform/README.md | Updates README reference to new metadata_host. |
| samples/eventhubs/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/eventhubs-eventgrid/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/container-apps-blob-storage/python/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/container-apps-blob-storage/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| samples/aci-blob-storage/python/terraform/README.md | Updates azurerm metadata_host for emulator usage. |
| samples/aci-blob-storage/python/terraform/providers.tf | Updates azurerm metadata_host for emulator usage. |
| .gitattributes | Enforces LF EOL for C# source/project/Razor files. |
Review details
- Files reviewed: 226/411 changed files
- Comments generated: 5
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| resource_group_name = var.resource_group_name | ||
| sku = var.sku | ||
| tags = var.tags | ||
| retention_in_days = var.retention_in_days != "" ? var.retention_in_days : null |
There was a problem hiding this comment.
Not applying this one: the expression is byte-identical to the Python module it was copied from (samples/web-app-cosmosdb-mongodb-api/python/terraform/modules/log_analytics/main.tf), which runs terraform apply in CI on every push, and terraform validate passes on this module too. Terraform's equality operators are type-tolerant — unlike arithmetic, ==/!= across mismatched primitive types evaluate to "not equal" rather than erroring — so with the number default of 30 the guard is simply always true and retention_in_days = 30 is applied. Changing it only in the .NET copy would make the two language variants diverge for no behavioural gain; if the guard should become != null, that is a cleanup worth doing across both variants in its own PR.
| resource_group_name = var.resource_group_name | ||
| sku = var.sku | ||
| tags = var.tags | ||
| retention_in_days = var.retention_in_days != "" ? var.retention_in_days : null |
There was a problem hiding this comment.
Not applying this one: the expression is byte-identical to the Python module it was copied from (samples/web-app-mysql-flexible-server/python/terraform/modules/log_analytics/main.tf), which runs terraform apply in CI on every push, and terraform validate passes on this module too. Terraform's equality operators are type-tolerant — unlike arithmetic, ==/!= across mismatched primitive types evaluate to "not equal" rather than erroring — so with the number default of 30 the guard is simply always true and retention_in_days = 30 is applied. Changing it only in the .NET copy would make the two language variants diverge for no behavioural gain; if the guard should become != null, that is a cleanup worth doing across both variants in its own PR.
| resource_group_name = var.resource_group_name | ||
| sku = var.sku | ||
| tags = var.tags | ||
| retention_in_days = var.retention_in_days != "" ? var.retention_in_days : null |
There was a problem hiding this comment.
Not applying this one: the expression is byte-identical to the Python module it was copied from (samples/web-app-postgresql-flexible-server/python/terraform/modules/log_analytics/main.tf), which runs terraform apply in CI on every push, and terraform validate passes on this module too. Terraform's equality operators are type-tolerant — unlike arithmetic, ==/!= across mismatched primitive types evaluate to "not equal" rather than erroring — so with the number default of 30 the guard is simply always true and retention_in_days = 30 is applied. Changing it only in the .NET copy would make the two language variants diverge for no behavioural gain; if the guard should become != null, that is a cleanup worth doing across both variants in its own PR.
…ubject check Two CI failures that survived four re-runs were deterministic, not flaky: - web-app-cosmosdb-nosql-api/scripts/deploy.sh did `cd "../src"` without anchoring to the script's own location, so it worked when run from scripts/ but not as `bash scripts/deploy.sh` from the sample root, which is how run-samples.sh invokes it: `cd: ../src: No such file or directory`. Both language variants now set CURRENT_DIR the way every other sample does. - The SQL Database certificate check compared distinguished names literally, so OpenSSL 3's "CN = sample-web-app-sql" never matched Key Vault's "CN=sample-web-app-sql". Both are normalized before comparing (leading "/" and the spaces around "=" of the OpenSSL 1 and 3 spellings), and the match is a fixed-string one so a CN with regex metacharacters cannot misfire. The Python copy of that check also stops reporting success when there is nothing to check: its app only serves HTTPS on 8443 when started directly, so under gunicorn the old code compared two empty thumbprints and called them equal. It now says the port is not served and skips. From the Copilot review: the NoSQL delete flash message reads "Activity deleted." like the Python sample, and the unused Docker helper functions are gone from the custom-image call script. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…g the job Of the 11 jobs that failed on the first run of the samples workflow, 8 were in samples this branch does not touch and went green when re-run by hand: two never reached the sample at all (`localstack wait -t 600` expired while ~80 jobs competed for runner I/O and image pulls) and one hit a transient 500 from the emulator while creating a MySQL firewall rule. Automate what the manual re-runs were doing: - the emulator start gets one clean retry, printing the container's last log lines when the first wait expires; - the sample runs with continue-on-error and, on failure, once more against a freshly restarted emulator, because the deploy scripts are not idempotent and would otherwise re-run against half-provisioned resources. A genuinely broken sample fails both attempts, so it still fails the job. The job also gets a 90-minute bound: a sample takes 10-25 minutes, a retry doubles the worst case, and a hung deployment would otherwise hold a runner for GitHub's 6-hour default. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ator start The samples workflow came back with 2 failures out of 78 (from 11), and both were emulator-side transients rather than sample defects: - web-app-mysql-flexible-server/dotnet failed twice, both times on `az mysql flexible-server firewall-rule create` answering 500. The Azure CLI's own retries all land within ~5 seconds of each other, which is too early: the PUT succeeds once the server finishes provisioning. The create is now retried five times at 10-second intervals in the MySQL and PostgreSQL samples (both languages, since the blocks were identical), and a persistent failure warns instead of aborting: the rule only governs public network access, which the emulator does not enforce, and the database bootstrap a few lines later fails loudly if the server is genuinely unreachable. - aci-blob-storage/python/bicep failed on an arm64 runner because the emulator never became ready - the container logged nothing for the last ten minutes of each 600-second wait, so the boot had stalled rather than slowed. The readiness retry now makes three 400-second attempts instead of two 600-second ones: the same overall budget, one more chance, and a stalled container is replaced sooner. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Motivation
Every "Vacation Planner" web app sample existed only in Python, while the two Azure Functions samples were already .NET. This PR ports all seven
web-app-*permutations to .NET 10 so each one ships in both languages, with the same deployment options (Azure CLI scripts, Terraform, Bicep) and the same validation scripts.The emulator could not run a .NET Linux web app deployed as code until two changes landed in
localstack-pro, both merged: #8734 (acceptDOTNETCORE|<major.minor>, use theoryx/dotnetcoreruntime images, build intooryx_publish_output) and #8749 (preserve repeatedSet-Cookieheaders, without which a Razor Pages form POST fails with 400 through the emulator endpoint). These samples therefore require an emulator image built fromlocalstack-promain.Fixes SMF-877
Changes
Seven new
samples/web-app-*/dotnetsamples — ASP.NET Core Razor Pages ports of the Vacation Planner, one per storage backend: Cosmos DB for MongoDB (MongoDB.Driver), Cosmos DB for NoSQL (Microsoft.Azure.Cosmos, Gateway mode), Blob Storage with managed identity (Azure.Identity), Azure SQL Database (Microsoft.Data.SqlClient + Key Vault secret and certificate, HTTPS on 8443), MySQL flexible server (MySqlConnector), PostgreSQL flexible server (Npgsql) and a custom container image. Each keeps the Python routes, form fields, flash messages, environment variable names andWEBSITES_PORT, and adds aGET /healthendpoint.python app.py.Activity added/updated/deletedfrom the page handlers — the three layers the Flask samples produce.scripts/deploy with--runtime DOTNETCORE:10.0and zip the project source (the emulator, like App Service with build-during-deployment, runs the Oryx build), Terraform usesdotnet_version, Bicep usesruntimeName = 'dotnetcore'.run-samples.sh, which is what the generated matrix reads —.github/workflows/run-samples.ymlneeds no change. The matrix now builds 17web-app-*/dotnetjobs (8 scripts, 5 Terraform, 4 Bicep; the custom-image sample also runs on arm64, the code-deployment ones are amd64-only because the Oryx build image is).call-web-app.shin both languages — the name every other sample uses and the one the Python README already documented — and the .NET copy exits non-zero when the certificate endpoint, the thumbprint or the TLS certificate is missing.metadata_hostpoints atazure.localhost.localstack.cloud:4566in every sample'sproviders.tfand in the Terraform READMEs.Testing
Every .NET sample was deployed against the emulator and exercised through the emulator endpoint (
https://<app>.azurewebsites.azure.localhost.localstack.cloud:4566), not only against the container port:deploy.sh→validate.sh→call-web-app.sh, plus a functional check of add / list / update / delete (with the Razor antiforgery token) andGET /health.web-app-managed-identitywas additionally verified end to end throughterraform/deploy.shandbicep/deploy.sh, which confirmsdotnet_version = "10.0"on azurerm 5.1.0 andDOTNETCORE|10.0from Bicep.web-app-sql-databasewas verified including the strict certificate check (the thumbprint from/api/certificatematches the certificate served on 8443).dotnet build -c Releasewith zero warnings.🤖 Generated with Claude Code