azd-deployment
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAzure Developer CLI (azd) Container Apps Deployment
Azure Developer CLI (azd) Container Apps 部署
Deploy containerized frontend + backend applications to Azure Container Apps with remote builds, managed identity, and idempotent infrastructure.
通过远程构建、托管标识和幂等基础设施,将容器化的前端+后端应用部署到Azure Container Apps。
Quick Start
快速开始
bash
undefinedbash
undefinedInitialize 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
undefinedazd auth login
azd init # 创建azure.yaml和.azure/文件夹
azd env new <env-name> # 创建环境(dev、staging、prod)
azd up # 预置基础设施 + 构建 + 部署
undefinedCore 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/Dockerfileproject/
├── azure.yaml # azd服务定义 + 钩子
├── infra/
│ ├── main.bicep # 根基础设施模块
│ ├── main.parameters.json # 从环境变量注入参数
│ └── modules/
│ ├── container-apps-environment.bicep
│ └── container-app.bicep
├── .azure/
│ ├── config.json # 默认环境指针
│ └── <env-name>/
│ ├── .env # 环境专属值(由azd管理)
│ └── config.json # 环境元数据
└── src/
├── frontend/Dockerfile
└── backend/Dockerfileazure.yaml Configuration
azure.yaml 配置
Minimal Configuration
最简配置
yaml
name: azd-deployment
services:
backend:
project: ./src/backend
language: python
host: containerapp
docker:
path: ./Dockerfile
remoteBuild: trueyaml
name: azd-deployment
services:
backend:
project: ./src/backend
language: python
host: containerapp
docker:
path: ./Dockerfile
remoteBuild: trueFull 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}"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
azure.yaml 关键选项
| Option | Description |
|---|---|
| Build images in Azure Container Registry (recommended) |
| Docker build context relative to project path |
| Deploy to Azure Container Apps |
| Use Bicep for infrastructure |
| 选项 | 描述 |
|---|---|
| 在Azure Container Registry中构建镜像(推荐) |
| 相对于项目路径的Docker构建上下文 |
| 部署到Azure Container Apps |
| 使用Bicep管理基础设施 |
Environment Variables Flow
环境变量流转
Three-Level Configuration
三级配置
- Local - For local development only
.env - - azd-managed, auto-populated from Bicep outputs
.azure/<env>/.env - - Maps env vars to Bicep parameters
main.parameters.json
- 本地 - 仅用于本地开发
.env - - 由azd管理,从Bicep输出自动填充
.azure/<env>/.env - - 将环境变量映射到Bicep参数
main.parameters.json
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: or
${VAR_NAME}${VAR_NAME=default_value}json
// infra/main.parameters.json
{
"parameters": {
"environmentName": { "value": "${AZURE_ENV_NAME}" },
"location": { "value": "${AZURE_LOCATION=eastus2}" },
"azureOpenAiEndpoint": { "value": "${AZURE_OPENAI_ENDPOINT}" }
}
}语法: 或
${VAR_NAME}${VAR_NAME=default_value}Setting Environment Variables
设置环境变量
bash
undefinedbash
undefinedSet 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"
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 "..."
undefinedazd env new prod
azd env set AZURE_OPENAI_ENDPOINT "..."
undefinedBicep Output → Environment Variable
Bicep 输出 → 环境变量
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.principalIdbicep
// 在main.bicep中 - 输出会自动填充.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.principalIdIdempotent Deployments
幂等部署
Why azd up is Idempotent
为什么azd up是幂等的
- Bicep is declarative - Resources reconcile to desired state
- Remote builds tag uniquely - Image tags include deployment timestamp
- ACR reuses layers - Only changed layers upload
- Bicep是声明式的 - 资源会协调至期望状态
- 远程构建生成唯一标签 - 镜像标签包含部署时间戳
- ACR复用镜像层 - 仅上传变更的层
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通过门户添加的自定义域名可能在重新部署时丢失,可通过钩子保留:
yaml
hooks:
preprovision:
shell: sh
run: |
# 预置前保存自定义域名
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: |
# 验证/恢复自定义域名
if [ -f /tmp/domains.json ]; then
echo "Saved domains: $(cat /tmp/domains.json)"
fiHandling 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 : customDomainsParambicep
// 引用现有ACR(不重新创建)
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = {
name: containerRegistryName
}
// 将customDomains设为null以保留门户添加的域名
customDomains: empty(customDomainsParam) ? null : customDomainsParamContainer App Service Discovery
Container App 服务发现
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;
}同一环境中Container Apps之间的内部HTTP路由:
bicep
// 前端环境变量中的后端引用
env: [
{
name: 'BACKEND_URL'
value: 'http://ca-backend-${resourceToken}' // 内部DNS
}
]前端nginx代理到内部URL:
nginx
location /api {
proxy_pass $BACKEND_URL;
}Managed Identity & RBAC
托管标识与RBAC
Enable System-Assigned Identity
启用系统分配的标识
bicep
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
identity: {
type: 'SystemAssigned'
}
}
output principalId string = containerApp.identity.principalIdbicep
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
identity: {
type: 'SystemAssigned'
}
}
output principalId string = containerApp.identity.principalIdPost-Provision RBAC Assignment
预置后RBAC分配
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 || trueyaml
hooks:
postprovision:
shell: sh
run: |
PRINCIPAL_ID="${BACKEND_PRINCIPAL_ID}"
# Azure OpenAI 访问权限
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 访问权限
az role assignment create \
--assignee-object-id "$PRINCIPAL_ID" \
--role "Search Index Data Reader" \
--scope "$SEARCH_RESOURCE_ID" 2>/dev/null || trueCommon Commands
常用命令
bash
undefinedbash
undefinedEnvironment 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
azd env list # 列出环境
azd env select <name> # 切换环境
azd env get-values # 显示所有环境变量
azd env set KEY value # 设置变量
Deployment
部署
azd up # Full provision + deploy
azd provision # Infrastructure only
azd deploy # Code deployment only
azd deploy --service backend # Deploy single service
azd up # 完整预置 + 部署
azd provision # 仅基础设施
azd deploy # 仅代码部署
azd deploy --service backend # 部署单个服务
Debugging
调试
azd show # Show project status
az containerapp logs show -n <app> -g <rg> --follow # Stream logs
undefinedazd show # 显示项目状态
az containerapp logs show -n <app> -g <rg> --follow # 流式查看日志
undefinedReference 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
- Bicep 模式: 查看 references/bicep-patterns.md 获取Container Apps模块
- 故障排查: 查看 references/troubleshooting.md 解决常见问题
- azure.yaml schema: 查看 references/azure-yaml-schema.md 获取完整选项
Critical Reminders
重要提醒
- Always use - Local builds fail on M1/ARM Macs deploying to AMD64
remoteBuild: true - Bicep outputs auto-populate .azure/<env>/.env - Don't manually edit
- Use for secrets - Not main.parameters.json defaults
azd env set - Service tags () - Required for azd to find Container Apps
azd-service-name - in hooks - Prevent RBAC "already exists" errors from failing deploy
|| true
- 始终使用 - M1/ARM Mac的本地构建部署到AMD64时会失败
remoteBuild: true - Bicep输出自动填充.azure/<env>/.env - 请勿手动编辑
- 使用 设置密钥 - 不要在main.parameters.json中设置默认值
azd env set - 服务标签 () - azd查找Container Apps必需
azd-service-name - 钩子中的 - 防止RBAC“已存在”错误导致部署失败
|| true