Azure Developer CLI (azd) Container Apps Deployment Deploy containerized frontend + backend applications to Azure Container Apps with remote builds, managed identity, and idempotent infrastructure. Quick Start
Initialize and deploy
azd auth login azd init
Creates azure.yaml and .azure/ folder
azd env new < env-name
Create environment (dev, staging, prod)
azd up
Provision infra + build + deploy
Core File Structure
project/
├── azure.yaml # azd service definitions + hooks
├── infra/
│ ├── main.bicep # Root infrastructure module
│ ├── main.parameters.json # Parameter injection from env vars
│ └── modules/
│ ├── container-apps-environment.bicep
│ └── container-app.bicep
├── .azure/
│ ├── config.json # Default environment pointer
│ └──
Set for current environment
azd env set AZURE_OPENAI_ENDPOINT "https://my-openai.openai.azure.com" azd env set AZURE_SEARCH_ENDPOINT "https://my-search.search.windows.net"
Set during init
azd
env
new prod
azd
env
set
AZURE_OPENAI_ENDPOINT
"..."
Bicep Output → Environment Variable
// In main.bicep - outputs auto-populate .azure/
Save custom domains before provision
if az containerapp show --name "$FRONTEND_NAME" -g "$RG" &>/dev/null; then az containerapp show --name "$FRONTEND_NAME" -g "$RG" \ --query "properties.configuration.ingress.customDomains" \ -o json > /tmp/domains.json fi postprovision : shell : sh run : |
Verify/restore custom domains
if [ -f /tmp/domains.json ]; then echo "Saved domains: $(cat /tmp/domains.json)" fi Handling Existing Resources // Reference existing ACR (don't recreate) resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = { name : containerRegistryName } // Set customDomains to null to preserve Portal-added domains customDomains : empty ( customDomainsParam ) ? null : customDomainsParam Container App Service Discovery Internal HTTP routing between Container Apps in same environment: // Backend reference in frontend env vars env : [ { name : 'BACKEND_URL' value : 'http://ca-backend- ${ resourceToken } ' // Internal DNS } ] Frontend nginx proxies to internal URL: location /api { proxy_pass $BACKEND_URL ; } Managed Identity & RBAC Enable System-Assigned Identity resource containerApp 'Microsoft.App/containerApps@2024-03-01' = { identity : { type : 'SystemAssigned' } } output principalId string = containerApp . identity . principalId Post-Provision RBAC Assignment hooks : postprovision : shell : sh run : | PRINCIPAL_ID="${BACKEND_PRINCIPAL_ID}"
Azure OpenAI access
az role assignment create \
- assignee - object - id "$PRINCIPAL_ID" \ - - assignee - principal - type ServicePrincipal \ - - role "Cognitive Services OpenAI User" \ - - scope "$OPENAI_RESOURCE_ID" 2
/dev/null | | true
Azure AI Search access
az role assignment create \
- assignee - object - id "$PRINCIPAL_ID" \ - - role "Search Index Data Reader" \ - - scope "$SEARCH_RESOURCE_ID" 2
/dev/null | | true Common Commands
Environment management
azd env list
List environments
azd env select < name
Switch environment
azd env get-values
Show all env vars
azd env set KEY value
Set variable
Deployment
azd up
Full provision + deploy
azd provision
Infrastructure only
azd deploy
Code deployment only
azd deploy --service backend
Deploy single service
Debugging
azd show
Show project status
az containerapp logs show -n < app
-g < rg
--follow
Stream logs
- Reference Files
- Bicep patterns
-
- See references/bicep-patterns.md for Container Apps modules
- Troubleshooting
-
- See references/troubleshooting.md for common issues
- azure.yaml schema
- See references/azure-yaml-schema.md for full options Critical Reminders Always use remoteBuild: true - Local builds fail on M1/ARM Macs deploying to AMD64 Bicep outputs auto-populate .azure//.env - Don't manually edit Use azd env set for secrets - Not main.parameters.json defaults Service tags ( azd-service-name ) - Required for azd to find Container Apps || true in hooks - Prevent RBAC "already exists" errors from failing deploy When to Use This skill is applicable to execute the workflow or actions described in the overview.