Gap-2: Container Apps Develop (C → A) — Templates + Dapr + Jobs + Functions-on-ACA#1636
Gap-2: Container Apps Develop (C → A) — Templates + Dapr + Jobs + Functions-on-ACA#1636
Conversation
15 template files for Container Apps development scaffolding: - selection.md decision tree - 6 base templates (web-app, api, microservice, worker, job, functions-on-aca) - 6 recipe templates (Dapr, Cosmos, Service Bus, Redis, ACR, PostgreSQL) - Composition algorithm Closes #1610 Parent: #1608 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds “reference only” documentation for Azure Container Apps base templates and composable integration recipes, plus a documented composition algorithm and selection decision tree to guide template/recipe choice.
Changes:
- Added base template docs for common Container Apps workloads (web app, API, worker, job, microservices, Functions on ACA)
- Added integration recipe docs (Dapr, Cosmos DB, Service Bus, Redis, ACR, PostgreSQL) with Bicep snippets, env vars, RBAC guidance, and scaling patterns
- Added a workload selection decision tree and a step-by-step composition/merge algorithm
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| plugin/skills/azure-prepare/references/services/container-apps/templates/worker.md | New worker template doc with Bicep example and KEDA scaling patterns |
| plugin/skills/azure-prepare/references/services/container-apps/templates/web-app.md | New web app template doc with ingress, scaling, and health probe examples |
| plugin/skills/azure-prepare/references/services/container-apps/templates/selection.md | New decision tree for selecting base templates and recipes |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/servicebus/README.md | New Service Bus recipe doc (Bicep + RBAC + KEDA rule + SDK example) |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/redis/README.md | New Redis recipe doc (Bicep + RBAC + SDK example + Dapr component snippet) |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/postgres/README.md | New PostgreSQL recipe doc (Bicep + Entra auth examples + firewall snippet) |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/dapr/README.md | New Dapr recipe doc (enablement + components examples) |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/cosmos/README.md | New Cosmos DB recipe doc (Bicep + RBAC + SDK example) |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/composition.md | New authoritative composition algorithm doc |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/acr/README.md | New ACR recipe doc (Bicep + RBAC + build workflow) |
| plugin/skills/azure-prepare/references/services/container-apps/templates/recipes/README.md | New recipes index/overview doc |
| plugin/skills/azure-prepare/references/services/container-apps/templates/microservice.md | New microservices template doc with service discovery guidance |
| plugin/skills/azure-prepare/references/services/container-apps/templates/job.md | New jobs template doc (scheduled/event/manual) with Bicep examples |
| plugin/skills/azure-prepare/references/services/container-apps/templates/functions-on-aca.md | New Functions-on-ACA template doc with Dockerfile/Bicep guidance |
| plugin/skills/azure-prepare/references/services/container-apps/templates/api.md | New API template doc with gRPC toggle and CORS example |
| kind: 'GlobalDocumentDB' | ||
| properties: { | ||
| databaseAccountOfferType: 'Standard' | ||
| disableLocalAuthentication: true |
There was a problem hiding this comment.
Microsoft.DocumentDB/databaseAccounts uses disableLocalAuth (not disableLocalAuthentication) to disable key-based/local auth. As written, this property is likely ignored by ARM, resulting in local auth remaining enabled despite the guidance.
| { | ||
| name: 'AZURE_CLIENT_ID' | ||
| value: '' // Set to UAMI client ID | ||
| } |
There was a problem hiding this comment.
This template mixes a managed-identity posture (UAMI client id) with a KEDA scaler auth pattern that implies a connection-string secret (secretRef: 'sb-connection'). That’s inconsistent with the docs’ “never connection strings” rule and also leaves AZURE_CLIENT_ID blank in the example. Recommend updating the scaling rule example to a managed-identity-based authentication pattern (and documenting the exact ACA/KEDA fields required), or explicitly documenting the required secret creation if connection strings are intended for this reference template.
| auth: [ | ||
| { | ||
| secretRef: 'sb-connection' | ||
| triggerParameter: 'connection' | ||
| } | ||
| ] |
There was a problem hiding this comment.
This template mixes a managed-identity posture (UAMI client id) with a KEDA scaler auth pattern that implies a connection-string secret (secretRef: 'sb-connection'). That’s inconsistent with the docs’ “never connection strings” rule and also leaves AZURE_CLIENT_ID blank in the example. Recommend updating the scaling rule example to a managed-identity-based authentication pattern (and documenting the exact ACA/KEDA fields required), or explicitly documenting the required secret creation if connection strings are intended for this reference template.
| tags: tags | ||
| sku: { name: 'Standard', tier: 'Standard' } | ||
| properties: { | ||
| disableLocalAuth: true |
There was a problem hiding this comment.
The recipe sets disableLocalAuth: true (good), but the KEDA rule still references a secret named sb-identity with triggerParameter: 'connection', which typically maps to a connection string/SAS key. Either document how that secret is produced using identity (if supported by ACA/KEDA in this context), or adjust the example to a managed-identity-native scaler configuration so the recipe remains internally consistent with the RBAC-only guidance.
| secretRef: 'sb-identity' | ||
| triggerParameter: 'connection' |
There was a problem hiding this comment.
The recipe sets disableLocalAuth: true (good), but the KEDA rule still references a secret named sb-identity with triggerParameter: 'connection', which typically maps to a connection string/SAS key. Either document how that secret is produced using identity (if supported by ACA/KEDA in this context), or adjust the example to a managed-identity-native scaler configuration so the recipe remains internally consistent with the RBAC-only guidance.
| secretRef: 'sb-identity' | |
| triggerParameter: 'connection' | |
| // Use the Container App's managed identity for RBAC-based authentication | |
| // 'system' for system-assigned, or a user-assigned client ID if preferred | |
| identity: 'system' |
| const client = createClient({ | ||
| url: `rediss://${process.env.REDIS_HOSTNAME}:${process.env.REDIS_PORT}`, | ||
| credential, | ||
| }); |
There was a problem hiding this comment.
The Node redis client configuration shown here is not a valid API for node-redis (there is no credential option like this). If the intent is Entra ID/OAuth-based auth, the example should show how to obtain the token and pass it using the client’s supported auth fields (and document the expected Redis username/token format for the chosen Redis offering).
| const client = createClient({ | |
| url: `rediss://${process.env.REDIS_HOSTNAME}:${process.env.REDIS_PORT}`, | |
| credential, | |
| }); | |
| async function createRedisClient() { | |
| // Acquire an Entra ID access token for Azure Cache for Redis | |
| const { token } = await credential.getToken("https://redis.azure.com/.default"); | |
| const client = createClient({ | |
| url: `rediss://${process.env.REDIS_HOSTNAME}:${process.env.REDIS_PORT}`, | |
| // For Azure Cache for Redis with Entra ID, the username is typically "default" | |
| username: "default", | |
| password: token, | |
| }); | |
| await client.connect(); | |
| return client; | |
| } | |
| // Example usage | |
| createRedisClient() | |
| .then((client) => { | |
| // Use the client instance here | |
| }) | |
| .catch((err) => { | |
| console.error("Error connecting to Redis:", err); | |
| }); |
| conn = psycopg2.connect( | ||
| host=os.environ["PGHOST"], | ||
| database=os.environ["PGDATABASE"], | ||
| user=os.environ["AZURE_CLIENT_ID"], | ||
| password=token.token, | ||
| sslmode="require", | ||
| ) |
There was a problem hiding this comment.
For PostgreSQL Entra ID auth, user should be the PostgreSQL role / Entra principal name configured on the server (often the AAD admin name or mapped role), not the application’s AZURE_CLIENT_ID. Using the client ID here is unlikely to authenticate. Consider adding an explicit env var (e.g., PGUSER) sourced from principalName and updating the examples accordingly.
| const client = new Client({ | ||
| host: process.env.PGHOST, | ||
| database: process.env.PGDATABASE, | ||
| user: process.env.AZURE_CLIENT_ID, | ||
| password: token.token, | ||
| ssl: { rejectUnauthorized: true }, | ||
| port: 5432, | ||
| }); |
There was a problem hiding this comment.
Same issue as the Python snippet: user: process.env.AZURE_CLIENT_ID is unlikely to work for Postgres Entra ID auth because the username needs to match the configured AAD admin / mapped principal role name. Recommend documenting and using a dedicated PGUSER (or similar) aligned with the principalName configured in the Bicep module.
| name: name | ||
| location: location | ||
| tags: tags | ||
| containerAppPrincipalId: app.outputs.principalId |
There was a problem hiding this comment.
The module param name containerAppPrincipalId doesn’t match the recipe modules shown elsewhere (e.g., recipes typically declare param principalId string). This inconsistency will cause copy/paste errors. Recommend standardizing parameter names across all recipe docs and the composition algorithm.
| containerAppPrincipalId: app.outputs.principalId | |
| principalId: app.outputs.principalId |
| ## Critical Rules | ||
|
|
||
| 1. **Never synthesize IaC from scratch** — always extend base template | ||
| 2. **Never modify base IaC files** — only ADD recipe modules alongside them |
There was a problem hiding this comment.
This conflicts with Step 3, which instructs adding module references in infra/main.bicep (a base file). Recommend rewording rule #2 to reflect the actual intended constraint (e.g., “don’t rewrite/replace base resources; only add module references and additive resources”), otherwise readers may interpret the instructions as contradictory.
| 2. **Never modify base IaC files** — only ADD recipe modules alongside them | |
| 2. **Don’t replace or remove base IaC resources** — extend base files only by adding module references and other additive resources |
Details# 🔍 Token Analysis Report
fatal: path 'plugin/skills/azure-prepare/references/services/container-apps/templates/api.md' exists on disk, but not in 'origin/main' 📊 Token Change ReportComparing Summary
Changed Files
📊 Token Limit Check ReportChecked: 539 files
|
| File | Tokens | Limit | Over By |
|---|---|---|---|
.github/skills/analyze-test-run/SKILL.md |
2471 | 500 | +1971 |
.github/skills/file-test-bug/SKILL.md |
628 | 500 | +128 |
.github/skills/sensei/README.md |
3531 | 2000 | +1531 |
.github/skills/sensei/SKILL.md |
2382 | 500 | +1882 |
.github/skills/sensei/references/EXAMPLES.md |
3707 | 2000 | +1707 |
.github/skills/sensei/references/LOOP.md |
4181 | 2000 | +2181 |
.github/skills/sensei/references/SCORING.md |
3927 | 2000 | +1927 |
.github/skills/skill-authoring/SKILL.md |
817 | 500 | +317 |
plugin/skills/appinsights-instrumentation/SKILL.md |
908 | 500 | +408 |
plugin/skills/azure-ai/SKILL.md |
817 | 500 | +317 |
plugin/skills/azure-aigateway/SKILL.md |
1258 | 500 | +758 |
plugin/skills/azure-aigateway/references/policies.md |
2342 | 2000 | +342 |
plugin/skills/azure-cloud-migrate/references/services/functions/lambda-to-functions.md |
2600 | 2000 | +600 |
plugin/skills/azure-cloud-migrate/references/services/functions/runtimes/javascript.md |
2181 | 2000 | +181 |
plugin/skills/azure-compliance/SKILL.md |
1185 | 500 | +685 |
plugin/skills/azure-compute/SKILL.md |
755 | 500 | +255 |
plugin/skills/azure-compute/workflows/vm-recommender/vm-recommender.md |
2393 | 2000 | +393 |
plugin/skills/azure-compute/workflows/vm-troubleshooter/references/cannot-connect-to-vm.md |
7308 | 2000 | +5308 |
plugin/skills/azure-cost-optimization/SKILL.md |
3900 | 500 | +3400 |
plugin/skills/azure-deploy/SKILL.md |
1562 | 500 | +1062 |
plugin/skills/azure-diagnostics/SKILL.md |
1132 | 500 | +632 |
plugin/skills/azure-diagnostics/aks-troubleshooting/networking.md |
2147 | 2000 | +147 |
plugin/skills/azure-diagnostics/aks-troubleshooting/node-issues.md |
2003 | 2000 | +3 |
plugin/skills/azure-enterprise-infra-planner/SKILL.md |
991 | 500 | +491 |
plugin/skills/azure-enterprise-infra-planner/references/constraints/compute-apps.md |
2022 | 2000 | +22 |
plugin/skills/azure-hosted-copilot-sdk/SKILL.md |
608 | 500 | +108 |
plugin/skills/azure-kubernetes/SKILL.md |
2266 | 500 | +1766 |
plugin/skills/azure-kusto/SKILL.md |
2149 | 500 | +1649 |
plugin/skills/azure-messaging/SKILL.md |
967 | 500 | +467 |
plugin/skills/azure-prepare/SKILL.md |
2607 | 500 | +2107 |
plugin/skills/azure-prepare/references/aspire.md |
2991 | 2000 | +991 |
plugin/skills/azure-prepare/references/plan-template.md |
2559 | 2000 | +559 |
plugin/skills/azure-prepare/references/recipes/azd/terraform.md |
3012 | 2000 | +1012 |
plugin/skills/azure-prepare/references/resources-limits-quotas.md |
3322 | 2000 | +1322 |
plugin/skills/azure-prepare/references/security.md |
2092 | 2000 | +92 |
plugin/skills/azure-prepare/references/services/functions/bicep.md |
3065 | 2000 | +1065 |
plugin/skills/azure-prepare/references/services/functions/templates/SPEC-composable-templates.md |
6187 | 2000 | +4187 |
plugin/skills/azure-prepare/references/services/functions/templates/recipes/composition.md |
4649 | 2000 | +2649 |
plugin/skills/azure-prepare/references/services/functions/terraform.md |
3358 | 2000 | +1358 |
plugin/skills/azure-quotas/SKILL.md |
3445 | 500 | +2945 |
plugin/skills/azure-quotas/references/commands.md |
2644 | 2000 | +644 |
plugin/skills/azure-resource-lookup/SKILL.md |
1279 | 500 | +779 |
plugin/skills/azure-resource-visualizer/SKILL.md |
2054 | 500 | +1554 |
plugin/skills/azure-storage/SKILL.md |
1180 | 500 | +680 |
plugin/skills/azure-upgrade/SKILL.md |
1001 | 500 | +501 |
plugin/skills/azure-upgrade/references/services/functions/automation.md |
3463 | 2000 | +1463 |
plugin/skills/azure-upgrade/references/services/functions/consumption-to-flex.md |
2773 | 2000 | +773 |
plugin/skills/azure-validate/SKILL.md |
906 | 500 | +406 |
plugin/skills/entra-app-registration/SKILL.md |
2068 | 500 | +1568 |
plugin/skills/entra-app-registration/references/api-permissions.md |
2545 | 2000 | +545 |
plugin/skills/entra-app-registration/references/cli-commands.md |
2211 | 2000 | +211 |
plugin/skills/entra-app-registration/references/console-app-example.md |
2752 | 2000 | +752 |
plugin/skills/entra-app-registration/references/oauth-flows.md |
2375 | 2000 | +375 |
plugin/skills/microsoft-foundry/SKILL.md |
2870 | 500 | +2370 |
plugin/skills/microsoft-foundry/foundry-agent/create/create.md |
3016 | 2000 | +1016 |
plugin/skills/microsoft-foundry/foundry-agent/deploy/deploy.md |
5511 | 2000 | +3511 |
plugin/skills/microsoft-foundry/foundry-agent/eval-datasets/eval-datasets.md |
2342 | 2000 | +342 |
plugin/skills/microsoft-foundry/foundry-agent/eval-datasets/references/trace-to-dataset.md |
4268 | 2000 | +2268 |
plugin/skills/microsoft-foundry/foundry-agent/observe/observe.md |
2547 | 2000 | +547 |
plugin/skills/microsoft-foundry/foundry-agent/trace/references/kql-templates.md |
2701 | 2000 | +701 |
plugin/skills/microsoft-foundry/models/deploy-model/SKILL.md |
1640 | 500 | +1140 |
plugin/skills/microsoft-foundry/models/deploy-model/capacity/SKILL.md |
1739 | 500 | +1239 |
plugin/skills/microsoft-foundry/models/deploy-model/customize/SKILL.md |
2235 | 500 | +1735 |
plugin/skills/microsoft-foundry/models/deploy-model/customize/references/customize-workflow.md |
3335 | 2000 | +1335 |
plugin/skills/microsoft-foundry/models/deploy-model/preset/SKILL.md |
1226 | 500 | +726 |
plugin/skills/microsoft-foundry/models/deploy-model/preset/references/preset-workflow.md |
5534 | 2000 | +3534 |
plugin/skills/microsoft-foundry/quota/quota.md |
2129 | 2000 | +129 |
plugin/skills/microsoft-foundry/quota/references/capacity-planning.md |
2029 | 2000 | +29 |
plugin/skills/microsoft-foundry/references/sdk/foundry-sdk-py.md |
2162 | 2000 | +162 |
Consider moving content to
references/subdirectories.
Automated token analysis. See skill authoring guidelines for best practices.
Closes #1610 | Parent: #1608
15 template files: selection tree, 6 base templates (web-app, api, microservice, worker, job, functions-on-aca), 6 recipes (Dapr, Cosmos, Service Bus, Redis, ACR, PostgreSQL), composition algorithm.
Key: Container Apps is a general-purpose serverless container platform for any stack. Event-driven = Functions on Container Apps.