azd 部署

azd-deployment
分类通用
作者Agentic Awesome Skills 社区
许可MIT
评分4.90/5
使用12.1K

Azure Developer CLI (azd) Container Apps 部署

将容器化前后端应用部署到 Azure Container Apps,支持远程构建、托管身份和幂等基础设施。

快速上手

bash
# 初始化并部署
azd auth login
azd init                    # 创建 azure.yaml 和 .azure/ 文件夹
azd env new <env-name>      # 创建环境 (dev, staging, prod)
azd up                      # 准备基础设施 + 构建 + 部署

核心文件结构

code
project/
├── azure.yaml              # azd 服务定义 + 钩子 (hooks)
├── 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/Dockerfile

azure.yaml 配置

最小化配置

yaml
name: azd-deployment
services:
  backend:
    project: ./src/backend
    language: python
    host: containerapp
    docker:
      path: ./Dockerfile
      remoteBuild: true

包含钩子的完整配置

yaml
name: azd-deployment
metadata:
  template: [email protected]

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 "Provisioning 之前..."

postprovision:
shell: sh
run: |
echo "Provisioning 之后 - 设置 RBAC 等"

postdeploy:
shell: sh
run: |
echo "Frontend: ${SERVICE_FRONTEND_URI}"
echo "Backend: ${SERVICE_BACKEND_URI}"

azure.yaml 关键选项

| 选项 | 描述 |
|--------|-------------|
| remoteBuild: true | 在 Azure Container Registry 中构建镜像 (推荐) |
| context: . | 相对于项目路径的 Docker 构建上下文 |
| host: containerapp | 部署到 Azure Container Apps |
| infra.provider: bicep | 使用 Bicep 管理基础设施 |

环境变量流转

三级配置

1. 本地 .env - 仅用于本地开发
2. .azure/<env>/.env - azd 管理,由 Bicep 输出自动填充
3. main.parameters.json - 将环境变量映射到 Bicep 参数

参数注入模式

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}

设置环境变量

bash
# 为当前环境设置
azd env set AZURE_OPENAI_ENDPOINT "https://my-openai.openai.azure.com"
azd env set AZURE_S
SEARCH_ENDPOINT "https://my-search.search.windows.net"

初始化时设置

azd env new prod azd env set AZURE_OPENAI_ENDPOINT "..."
code
### Bicep 输出 $\rightarrow$ 环境变量
bicep // 在 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.principalId
code
## 幂等部署

为什么 azd up 是幂等的

1. Bicep 是声明式的 - 资源会协调至期望状态
2. 远程构建具有唯一标签 - 镜像标签包含部署时间戳
3. ACR 复用层 - 仅上传变更的层

保留手动更改

通过 Portal 添加的自定义域名在重新部署时可能会丢失。可以使用 hooks 来保留:

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)"
fi

code
### 处理现有资源
bicep
// 引用现有的 ACR(不重新创建)
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = {
name: containerRegistryName
}

// 将 customDomains 设置为 null 以保留在 Portal 中添加的域名
customDomains: empty(customDomainsParam) ? null : customDomainsParam

code
## Container App 服务发现

同一环境内 Container App 之间的内部 HTTP 路由:

bicep
// 在前端环境变量中引用后端
env: [
{
name: 'BACKEND_URL'
value: 'http://ca-backend-${resourceToken}' // 内部 DNS
}
]
code
前端 nginx 代理至内部 URL:
nginx
location /api {
proxy_pass $BACKEND_URL;
}
code
## 托管标识与 RBAC

启用系统分配标识

bicep resource containerApp 'Microsoft.App/containerApps@2024-03-01' = { identity: { type: 'SystemAssigned' } }

output principalId string = containerApp.identity.principalId

code
### 配置后 RBAC 赋值
yaml
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 || true
code
## 常用命令
bash

环境管理


azd env list # 列出环境
azd env select <name> # 切换环境
azd env get-values # 显示所有环境变量
azd env set KEY value # 设置变量

部署

azd up # 完整配置 + 部署 azd provision # 仅基础设施配置 azd deploy # 仅代码部署 azd deploy --service backend # 部署单个服务

调试

azd sh
code
ow                            # 显示项目状态
az containerapp logs show -n <app> -g <rg> --follow  # 流式传输日志

参考文件

  • Bicep 模式:关于 Container Apps 模块,请参阅 references/bicep-patterns.md
  • 故障排除:关于常见问题,请参阅 references/troubleshooting.md
  • azure.yaml 架构:关于完整选项,请参阅 references/azure-yaml-schema.md

关键提醒

1. 务必使用 remoteBuild: true —— 在 M1/ARM Mac 上部署到 AMD64 时,本地构建会失败
2. Bicep 输出会自动填充到 .azure/<env>/.env —— 请勿手动编辑
3. 使用 azd env set 设置密钥 —— 不要将其放在 main.parameters.json 的默认值中
4. 服务标签 (azd-service-name) —— azd 查找 Container Apps 时必须提供
5. 在钩子中使用 || true —— 防止 RBAC “已存在”错误导致部署失败

适用场景

本技能适用于执行概览中所描述的工作流或操作。

局限性

  • 仅在任务明确符合上述范围时使用此技能。
  • 不要将输出结果视为针对特定环境的验证、测试或专家评审的替代方案。
  • 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。