- Add date_added to all 950+ skills for complete tracking - Update version to 6.5.0 in package.json and README - Regenerate all indexes and catalog - Sync all generated files Features from merged PR #150: - Stars/Upvotes system for community-driven discovery - Auto-update mechanism via START_APP.bat - Interactive Prompt Builder - Date tracking badges - Smart auto-categorization All skills validated and indexed. Made-with: Cursor
303 lines
7.9 KiB
Markdown
303 lines
7.9 KiB
Markdown
---
|
|
name: azd-deployment
|
|
description: "Deploy containerized applications to Azure Container Apps using Azure Developer CLI (azd). Use when setting up azd projects, writing azure.yaml configuration, creating Bicep infrastructure for Cont..."
|
|
risk: unknown
|
|
source: community
|
|
date_added: "2026-02-27"
|
|
---
|
|
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
│ └── <env-name>/
|
|
│ ├── .env # Environment-specific values (azd-managed)
|
|
│ └── config.json # Environment metadata
|
|
└── src/
|
|
├── frontend/Dockerfile
|
|
└── backend/Dockerfile
|
|
```
|
|
|
|
## azure.yaml Configuration
|
|
|
|
### Minimal Configuration
|
|
|
|
```yaml
|
|
name: azd-deployment
|
|
services:
|
|
backend:
|
|
project: ./src/backend
|
|
language: python
|
|
host: containerapp
|
|
docker:
|
|
path: ./Dockerfile
|
|
remoteBuild: true
|
|
```
|
|
|
|
### Full Configuration with Hooks
|
|
|
|
```yaml
|
|
name: azd-deployment
|
|
metadata:
|
|
template: my-project@1.0.0
|
|
|
|
infra:
|
|
provider: bicep
|
|
path: ./infra
|
|
|
|
azure:
|
|
location: eastus2
|
|
|
|
services:
|
|
frontend:
|
|
project: ./src/frontend
|
|
language: ts
|
|
host: containerapp
|
|
docker:
|
|
path: ./Dockerfile
|
|
context: .
|
|
remoteBuild: true
|
|
|
|
backend:
|
|
project: ./src/backend
|
|
language: python
|
|
host: containerapp
|
|
docker:
|
|
path: ./Dockerfile
|
|
context: .
|
|
remoteBuild: true
|
|
|
|
hooks:
|
|
preprovision:
|
|
shell: sh
|
|
run: |
|
|
echo "Before provisioning..."
|
|
|
|
postprovision:
|
|
shell: sh
|
|
run: |
|
|
echo "After provisioning - set up RBAC, etc."
|
|
|
|
postdeploy:
|
|
shell: sh
|
|
run: |
|
|
echo "Frontend: ${SERVICE_FRONTEND_URI}"
|
|
echo "Backend: ${SERVICE_BACKEND_URI}"
|
|
```
|
|
|
|
### Key azure.yaml Options
|
|
|
|
| Option | Description |
|
|
|--------|-------------|
|
|
| `remoteBuild: true` | Build images in Azure Container Registry (recommended) |
|
|
| `context: .` | Docker build context relative to project path |
|
|
| `host: containerapp` | Deploy to Azure Container Apps |
|
|
| `infra.provider: bicep` | Use Bicep for infrastructure |
|
|
|
|
## Environment Variables Flow
|
|
|
|
### Three-Level Configuration
|
|
|
|
1. **Local `.env`** - For local development only
|
|
2. **`.azure/<env>/.env`** - azd-managed, auto-populated from Bicep outputs
|
|
3. **`main.parameters.json`** - Maps env vars to Bicep parameters
|
|
|
|
### Parameter Injection Pattern
|
|
|
|
```json
|
|
// infra/main.parameters.json
|
|
{
|
|
"parameters": {
|
|
"environmentName": { "value": "${AZURE_ENV_NAME}" },
|
|
"location": { "value": "${AZURE_LOCATION=eastus2}" },
|
|
"azureOpenAiEndpoint": { "value": "${AZURE_OPENAI_ENDPOINT}" }
|
|
}
|
|
}
|
|
```
|
|
|
|
Syntax: `${VAR_NAME}` or `${VAR_NAME=default_value}`
|
|
|
|
### Setting Environment Variables
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bicep
|
|
// In main.bicep - outputs auto-populate .azure/<env>/.env
|
|
output SERVICE_FRONTEND_URI string = frontend.outputs.uri
|
|
output SERVICE_BACKEND_URI string = backend.outputs.uri
|
|
output BACKEND_PRINCIPAL_ID string = backend.outputs.principalId
|
|
```
|
|
|
|
## Idempotent Deployments
|
|
|
|
### Why azd up is Idempotent
|
|
|
|
1. **Bicep is declarative** - Resources reconcile to desired state
|
|
2. **Remote builds tag uniquely** - Image tags include deployment timestamp
|
|
3. **ACR reuses layers** - Only changed layers upload
|
|
|
|
### Preserving Manual Changes
|
|
|
|
Custom domains added via Portal can be lost on redeploy. Preserve with hooks:
|
|
|
|
```yaml
|
|
hooks:
|
|
preprovision:
|
|
shell: sh
|
|
run: |
|
|
# 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
|
|
|
|
```bicep
|
|
// 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:
|
|
|
|
```bicep
|
|
// Backend reference in frontend env vars
|
|
env: [
|
|
{
|
|
name: 'BACKEND_URL'
|
|
value: 'http://ca-backend-${resourceToken}' // Internal DNS
|
|
}
|
|
]
|
|
```
|
|
|
|
Frontend nginx proxies to internal URL:
|
|
```nginx
|
|
location /api {
|
|
proxy_pass $BACKEND_URL;
|
|
}
|
|
```
|
|
|
|
## Managed Identity & RBAC
|
|
|
|
### Enable System-Assigned Identity
|
|
|
|
```bicep
|
|
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
|
|
identity: {
|
|
type: 'SystemAssigned'
|
|
}
|
|
}
|
|
|
|
output principalId string = containerApp.identity.principalId
|
|
```
|
|
|
|
### Post-Provision RBAC Assignment
|
|
|
|
```yaml
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
1. **Always use `remoteBuild: true`** - Local builds fail on M1/ARM Macs deploying to AMD64
|
|
2. **Bicep outputs auto-populate .azure/<env>/.env** - Don't manually edit
|
|
3. **Use `azd env set` for secrets** - Not main.parameters.json defaults
|
|
4. **Service tags (`azd-service-name`)** - Required for azd to find Container Apps
|
|
5. **`|| 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.
|