{"id":"d20d6e8b-50f3-4718-b15d-8c480968e647","shortId":"32C96V","kind":"skill","title":"azd-deployment","tagline":"Deploy containerized frontend + backend applications to Azure Container Apps with remote builds, managed identity, and idempotent infrastructure.","description":"# Azure Developer CLI (azd) Container Apps Deployment\n\nDeploy containerized frontend + backend applications to Azure Container Apps with remote builds, managed identity, and idempotent infrastructure.\n\n## Quick Start\n\n```bash\n# Initialize and deploy\nazd auth login\nazd init                    # Creates azure.yaml and .azure/ folder\nazd env new <env-name>      # Create environment (dev, staging, prod)\nazd up                      # Provision infra + build + deploy\n```\n\n## Core File Structure\n\n```\nproject/\n├── azure.yaml              # azd service definitions + hooks\n├── infra/\n│   ├── main.bicep          # Root infrastructure module\n│   ├── main.parameters.json # Parameter injection from env vars\n│   └── modules/\n│       ├── container-apps-environment.bicep\n│       └── container-app.bicep\n├── .azure/\n│   ├── config.json         # Default environment pointer\n│   └── <env-name>/\n│       ├── .env            # Environment-specific values (azd-managed)\n│       └── config.json     # Environment metadata\n└── src/\n    ├── frontend/Dockerfile\n    └── backend/Dockerfile\n```\n\n## azure.yaml Configuration\n\n### Minimal Configuration\n\n```yaml\nname: azd-deployment\nservices:\n  backend:\n    project: ./src/backend\n    language: python\n    host: containerapp\n    docker:\n      path: ./Dockerfile\n      remoteBuild: true\n```\n\n### Full Configuration with Hooks\n\n```yaml\nname: azd-deployment\nmetadata:\n  template: my-project@1.0.0\n\ninfra:\n  provider: bicep\n  path: ./infra\n\nazure:\n  location: eastus2\n\nservices:\n  frontend:\n    project: ./src/frontend\n    language: ts\n    host: containerapp\n    docker:\n      path: ./Dockerfile\n      context: .\n      remoteBuild: true\n\n  backend:\n    project: ./src/backend\n    language: python\n    host: containerapp\n    docker:\n      path: ./Dockerfile\n      context: .\n      remoteBuild: true\n\nhooks:\n  preprovision:\n    shell: sh\n    run: |\n      echo \"Before provisioning...\"\n      \n  postprovision:\n    shell: sh\n    run: |\n      echo \"After provisioning - set up RBAC, etc.\"\n      \n  postdeploy:\n    shell: sh\n    run: |\n      echo \"Frontend: ${SERVICE_FRONTEND_URI}\"\n      echo \"Backend: ${SERVICE_BACKEND_URI}\"\n```\n\n### Key azure.yaml Options\n\n| Option | Description |\n|--------|-------------|\n| `remoteBuild: true` | Build images in Azure Container Registry (recommended) |\n| `context: .` | Docker build context relative to project path |\n| `host: containerapp` | Deploy to Azure Container Apps |\n| `infra.provider: bicep` | Use Bicep for infrastructure |\n\n## Environment Variables Flow\n\n### Three-Level Configuration\n\n1. **Local `.env`** - For local development only\n2. **`.azure/<env>/.env`** - azd-managed, auto-populated from Bicep outputs\n3. **`main.parameters.json`** - Maps env vars to Bicep parameters\n\n### Parameter Injection Pattern\n\n```json\n// infra/main.parameters.json\n{\n  \"parameters\": {\n    \"environmentName\": { \"value\": \"${AZURE_ENV_NAME}\" },\n    \"location\": { \"value\": \"${AZURE_LOCATION=eastus2}\" },\n    \"azureOpenAiEndpoint\": { \"value\": \"${AZURE_OPENAI_ENDPOINT}\" }\n  }\n}\n```\n\nSyntax: `${VAR_NAME}` or `${VAR_NAME=default_value}`\n\n### Setting Environment Variables\n\n```bash\n# Set for current environment\nazd env set AZURE_OPENAI_ENDPOINT \"https://my-openai.openai.azure.com\"\nazd env set AZURE_SEARCH_ENDPOINT \"https://my-search.search.windows.net\"\n\n# Set during init\nazd env new prod\nazd env set AZURE_OPENAI_ENDPOINT \"...\" \n```\n\n### Bicep Output → Environment Variable\n\n```bicep\n// In main.bicep - outputs auto-populate .azure/<env>/.env\noutput SERVICE_FRONTEND_URI string = frontend.outputs.uri\noutput SERVICE_BACKEND_URI string = backend.outputs.uri\noutput BACKEND_PRINCIPAL_ID string = backend.outputs.principalId\n```\n\n## Idempotent Deployments\n\n### Why azd up is Idempotent\n\n1. **Bicep is declarative** - Resources reconcile to desired state\n2. **Remote builds tag uniquely** - Image tags include deployment timestamp\n3. **ACR reuses layers** - Only changed layers upload\n\n### Preserving Manual Changes\n\nCustom domains added via Portal can be lost on redeploy. Preserve with hooks:\n\n```yaml\nhooks:\n  preprovision:\n    shell: sh\n    run: |\n      # Save custom domains before provision\n      if az containerapp show --name \"$FRONTEND_NAME\" -g \"$RG\" &>/dev/null; then\n        az containerapp show --name \"$FRONTEND_NAME\" -g \"$RG\" \\\n          --query \"properties.configuration.ingress.customDomains\" \\\n          -o json > /tmp/domains.json\n      fi\n\n  postprovision:\n    shell: sh\n    run: |\n      # Verify/restore custom domains\n      if [ -f /tmp/domains.json ]; then\n        echo \"Saved domains: $(cat /tmp/domains.json)\"\n      fi\n```\n\n### Handling Existing Resources\n\n```bicep\n// Reference existing ACR (don't recreate)\nresource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = {\n  name: containerRegistryName\n}\n\n// Set customDomains to null to preserve Portal-added domains\ncustomDomains: empty(customDomainsParam) ? null : customDomainsParam\n```\n\n## Container App Service Discovery\n\nInternal HTTP routing between Container Apps in same environment:\n\n```bicep\n// Backend reference in frontend env vars\nenv: [\n  {\n    name: 'BACKEND_URL'\n    value: 'http://ca-backend-${resourceToken}'  // Internal DNS\n  }\n]\n```\n\nFrontend nginx proxies to internal URL:\n```nginx\nlocation /api {\n    proxy_pass $BACKEND_URL;\n}\n```\n\n## Managed Identity & RBAC\n\n### Enable System-Assigned Identity\n\n```bicep\nresource containerApp 'Microsoft.App/containerApps@2024-03-01' = {\n  identity: {\n    type: 'SystemAssigned'\n  }\n}\n\noutput principalId string = containerApp.identity.principalId\n```\n\n### Post-Provision RBAC Assignment\n\n```yaml\nhooks:\n  postprovision:\n    shell: sh\n    run: |\n      PRINCIPAL_ID=\"${BACKEND_PRINCIPAL_ID}\"\n      \n      # Azure OpenAI access\n      az role assignment create \\\n        --assignee-object-id \"$PRINCIPAL_ID\" \\\n        --assignee-principal-type ServicePrincipal \\\n        --role \"Cognitive Services OpenAI User\" \\\n        --scope \"$OPENAI_RESOURCE_ID\" 2>/dev/null || true\n      \n      # Azure AI Search access\n      az role assignment create \\\n        --assignee-object-id \"$PRINCIPAL_ID\" \\\n        --role \"Search Index Data Reader\" \\\n        --scope \"$SEARCH_RESOURCE_ID\" 2>/dev/null || true\n```\n\n## Common Commands\n\n```bash\n# Environment management\nazd env list                        # List environments\nazd env select <name>               # Switch environment\nazd env get-values                  # Show all env vars\nazd env set KEY value               # Set variable\n\n# Deployment\nazd up                              # Full provision + deploy\nazd provision                       # Infrastructure only\nazd deploy                          # Code deployment only\nazd deploy --service backend        # Deploy single service\n\n# Debugging\nazd show                            # Show project status\naz containerapp logs show -n <app> -g <rg> --follow  # Stream logs\n```\n\n## Reference Files\n\n- **Bicep patterns**: See references/bicep-patterns.md for Container Apps modules\n- **Troubleshooting**: See references/troubleshooting.md for common issues\n- **azure.yaml schema**: See references/azure-yaml-schema.md for full options\n\n## Critical Reminders\n\n1. **Always use `remoteBuild: true`** - Local builds fail on M1/ARM Macs deploying to AMD64\n2. **Bicep outputs auto-populate .azure/<env>/.env** - Don't manually edit\n3. **Use `azd env set` for secrets** - Not main.parameters.json defaults\n4. **Service tags (`azd-service-name`)** - Required for azd to find Container Apps\n5. **`|| true` in hooks** - Prevent RBAC \"already exists\" errors from failing deploy\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["azd","deployment","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows"],"capabilities":["skill","source-sickn33","skill-azd-deployment","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/azd-deployment","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34964 github stars · SKILL.md body (7,983 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-25T00:50:30.251Z","embedding":null,"createdAt":"2026-04-18T21:31:47.965Z","updatedAt":"2026-04-25T00:50:30.251Z","lastSeenAt":"2026-04-25T00:50:30.251Z","tsv":"'/.env':273,367,773 '/api':561 '/containerapps@2024-03-01''':579 '/dev/null':456,631,657 '/dockerfile':136,172,185 '/infra':158 '/registries@2023-07-01''':503 '/src/backend':129,178 '/src/frontend':165 '/tmp/domains.json':470,481,487 '1':264,393,752 '1.0.0':153 '2':271,402,630,656,766 '3':283,412,778 '4':788 '5':802 'access':605,636 'acr':413,495 'action':826 'ad':425,515 'ai':634 'alreadi':808 'alway':753 'amd64':765 'app':12,26,36,250,523,531,735,801 'applic':8,32,820 'ask':864 'assign':572,591,608,639 'assigne':611,617,642 'assignee-object-id':610,641 'assignee-principal-typ':616 'auth':52 'auto':278,364,770 'auto-popul':277,363,769 'az':448,458,606,637,718 'azd':2,24,51,54,61,69,80,109,124,146,275,328,335,345,349,389,664,669,674,683,691,696,700,705,713,780,792,797 'azd-deploy':1,123,145 'azd-manag':108,274 'azd-service-nam':791 'azur':10,21,34,59,98,159,232,248,272,299,304,309,331,338,352,366,603,633,772 'azure.yaml':57,79,117,223,743 'azureopenaiendpoint':307 'backend':7,31,127,176,218,220,376,381,536,544,549,564,600,708 'backend.outputs.principalid':385 'backend.outputs.uri':379 'backend/dockerfile':116 'bash':47,323,661 'bicep':156,252,254,281,289,355,359,394,492,535,574,729,767 'boundari':872 'build':15,39,73,229,238,404,758 'ca':548 'ca-backend':547 'cat':486 'chang':417,422 'clarif':866 'clear':839 'cli':23 'code':702 'cognit':622 'command':660 'common':659,741 'config.json':99,111 'configur':118,120,140,263 'contain':11,25,35,233,249,522,530,734,800 'container':5,29 'container-app.bicep':97 'container-apps-environment.bicep':96 'containerapp':133,169,182,245,449,459,576,719 'containerapp.identity.principalid':586 'containerregistri':500 'containerregistrynam':506 'context':173,186,236,239 'core':75 'creat':56,64,609,640 'criteria':875 'critic':750 'current':326 'custom':423,443,477 'customdomain':508,517 'customdomainsparam':519,521 'data':650 'debug':712 'declar':396 'default':100,318,787 'definit':82 'deploy':3,4,27,28,50,74,125,147,246,387,410,690,695,701,703,706,709,763,813 'describ':827,843 'descript':226 'desir':400 'dev':66 'develop':22,269 'discoveri':525 'dns':552 'docker':134,170,183,237 'domain':424,444,478,485,516 'eastus2':161,306 'echo':194,201,212,217,483 'edit':777 'empti':518 'enabl':569 'endpoint':311,333,340,354 'env':62,93,103,266,286,300,329,336,346,350,540,542,665,670,675,681,684,781 'environ':65,101,105,112,257,321,327,357,534,662,668,673,855 'environment-specif':104,854 'environmentnam':297 'error':810 'etc':207 'execut':822 'exist':490,494,504,809 'expert':860 'f':480 'fail':759,812 'fi':471,488 'file':76,728 'find':799 'flow':259 'folder':60 'follow':724 'frontend':6,30,163,213,215,370,452,462,539,553 'frontend.outputs.uri':373 'frontend/dockerfile':115 'full':139,693,748 'g':454,464,723 'get':677 'get-valu':676 'handl':489 'hook':83,142,189,435,437,593,805 'host':132,168,181,244 'http':527 'id':383,599,602,613,615,629,644,646,655 'idempot':19,43,386,392 'ident':17,41,567,573,580 'imag':230,407 'includ':409 'index':649 'infra':72,84,154 'infra.provider':251 'infra/main.parameters.json':295 'infrastructur':20,44,87,256,698 'init':55,344 'initi':48 'inject':91,292 'input':869 'intern':526,551,557 'issu':742 'json':294,469 'key':222,686 'languag':130,166,179 'layer':415,418 'level':262 'limit':831 'list':666,667 'local':265,268,757 'locat':160,302,305,560 'log':720,726 'login':53 'lost':430 'm1/arm':761 'mac':762 'main.bicep':85,361 'main.parameters.json':89,284,786 'manag':16,40,110,276,566,663 'manual':421,776 'map':285 'match':840 'metadata':113,148 'microsoft.app':578 'microsoft.app/containerapps@2024-03-01''':577 'microsoft.containerregistry':502 'microsoft.containerregistry/registries@2023-07-01''':501 'minim':119 'miss':877 'modul':88,95,736 'my-openai.openai.azure.com':334 'my-project':150 'my-search.search.windows.net':341 'n':722 'name':122,144,301,314,317,451,453,461,463,505,543,794 'new':63,347 'nginx':554,559 'null':510,520 'o':468 'object':612,643 'openai':310,332,353,604,624,627 'option':224,225,749 'output':282,356,362,368,374,380,583,768,849 'overview':830 'paramet':90,290,291,296 'pass':563 'path':135,157,171,184,243 'pattern':293,730 'permiss':870 'pointer':102 'popul':279,365,771 'portal':427,514 'portal-ad':513 'post':588 'post-provis':587 'postdeploy':208 'postprovis':197,472,594 'preprovis':190,438 'preserv':420,433,512 'prevent':806 'princip':382,598,601,614,618,645 'principalid':584 'prod':68,348 'project':78,128,152,164,177,242,716 'properties.configuration.ingress.customdomains':467 'provid':155 'provis':71,196,203,446,589,694,697 'proxi':555,562 'python':131,180 'queri':466 'quick':45 'rbac':206,568,590,807 'reader':651 'recommend':235 'reconcil':398 'recreat':498 'redeploy':432 'refer':493,537,727 'references/azure-yaml-schema.md':746 'references/bicep-patterns.md':732 'references/troubleshooting.md':739 'registri':234 'relat':240 'remind':751 'remot':14,38,403 'remotebuild':137,174,187,227,755 'requir':795,868 'resourc':397,491,499,575,628,654 'resourcetoken':550 'reus':414 'review':861 'rg':455,465 'role':607,621,638,647 'root':86 'rout':528 'run':193,200,211,441,475,597 'safeti':871 'save':442,484 'schema':744 'scope':626,652,842 'search':339,635,648,653 'secret':784 'see':731,738,745 'select':671 'servic':81,126,162,214,219,369,375,524,623,707,711,789,793 'serviceprincip':620 'set':204,320,324,330,337,342,351,507,685,688,782 'sh':192,199,210,440,474,596 'shell':191,198,209,439,473,595 'show':450,460,679,714,715,721 'singl':710 'skill':818,834 'skill-azd-deployment' 'source-sickn33' 'specif':106,856 'src':114 'stage':67 'start':46 'state':401 'status':717 'stop':862 'stream':725 'string':372,378,384,585 'structur':77 'substitut':852 'success':874 'switch':672 'syntax':312 'system':571 'system-assign':570 'systemassign':582 'tag':405,408,790 'task':838 'templat':149 'test':858 'three':261 'three-level':260 'timestamp':411 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'treat':847 'troubleshoot':737 'true':138,175,188,228,632,658,756,803 'ts':167 'type':581,619 'uniqu':406 'upload':419 'uri':216,221,371,377 'url':545,558,565 'use':253,754,779,816,832 'user':625 'valid':857 'valu':107,298,303,308,319,546,678,687 'var':94,287,313,316,541,682 'variabl':258,322,358,689 'verify/restore':476 'via':426 'workflow':824 'yaml':121,143,436,592","prices":[{"id":"888a06cd-418d-4c0c-8aa7-6fea1b7eb0d8","listingId":"d20d6e8b-50f3-4718-b15d-8c480968e647","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:31:47.965Z"}],"sources":[{"listingId":"d20d6e8b-50f3-4718-b15d-8c480968e647","source":"github","sourceId":"sickn33/antigravity-awesome-skills/azd-deployment","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/azd-deployment","isPrimary":false,"firstSeenAt":"2026-04-18T21:31:47.965Z","lastSeenAt":"2026-04-25T00:50:30.251Z"}],"details":{"listingId":"d20d6e8b-50f3-4718-b15d-8c480968e647","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"azd-deployment","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34964,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-24T06:41:17Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"9c023ae32f1f73a14b81277319b66927dce71763","skill_md_path":"skills/azd-deployment/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/azd-deployment"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"azd-deployment","description":"Deploy containerized frontend + backend applications to Azure Container Apps with remote builds, managed identity, and idempotent infrastructure."},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/azd-deployment"},"updatedAt":"2026-04-25T00:50:30.251Z"}}