配置管道和推送更新

本文介绍如何使用 Azure Developer CLI (azd) 通过 CI/CD 管道(如 GitHub Actions 或 Azure DevOps)推送模板更改。 对于本例,你将使用在 Azure 上将 React Web 应用与 Node.js API 和 MongoDB 配合使用模板;但你可以将在本文中学到的原则应用于 Azure Developer CLI 模板中的任何一个。

注意

azd pipeline config 命令仍处于测试阶段。 有关 alpha 和 beta 功能支持的详细信息,请参阅功能版本控制和发布策略页面。

先决条件

azd 模板可能包含也可能不包含名为 azure-dev.yml 的默认 GitHub Actions 和/或 Azure DevOps 管道配置文件,这是设置 CI/CD 所必需的。 此配置文件预配 Azure 资源,并将代码部署到主分支。 你可以找到 azure-dev.yml

  • 对于 GitHub Actions:.github/workflows 目录中。
  • 对于 Azure DevOps:.azdo/pipelines 目录中。

可以按原样使用配置文件,也可以根据需要对其进行修改。

注意

在调用 azd pipeline config 之前,请确保模板具有管道定义 (azure-dev.yaml)。 azd 不会自动创建此文件。 请参阅下面的为 azd 创建管道定义

请使用 azd pipeline config 命令配置 CI/CD 管道,该命令处理以下任务:

  • 为 Azure 订阅上的应用创建和配置服务主体。 用户必须在 Azure 订阅中具有 Owner 角色或 Contributor + User Access Administrator 角色,因为要允许 azd 创建角色并将其分配给服务主体。
  • 引导你完成工作流,以创建和配置 GitHub 或 Azure DevOps 存储库,并将项目代码提交到其中。 还可以选择使用现有的存储库。
  • 在 Azure 和存储库之间创建安全连接。
  • 签入工作流文件时运行 GitHub 操作。

为了对这个过程进行更精细的控制,或者如果用户没有所需的角色,可以手动配置管道

选择首选管道提供程序以继续:

授权 GitHub 部署到 Azure

若要配置工作流,需要通过 GitHub Actions 授权服务主体代表你部署到 Azure。 azd 为其创建服务主体和联合凭据

  1. 运行以下命令,以创建 Azure 服务主体并配置管道:

    azd pipeline config
    

    此命令可选择创建 GitHub 存储库并将代码推送到新的存储库。

    注意

    默认情况下,azd pipeline config 使用 OpenID Connect (OIDC),称为联合凭据。 如果不想使用 OIDC,请运行 azd pipeline config --auth-type client-credentials

    Terraform 支持 OIDC/联合凭据。

    azd 中了解有关 OIDC 支持的详细信息。

  2. 提供请求的 GitHub 信息。

  3. 当系统提示提交和推送本地更改以启动新的 GitHub Actions 运行时,请指定 y

  4. 在终端窗口中,查看 azd pipeline config 命令的结果。 azd pipeline config 命令将输出项目的 GitHub 存储库名称。

  5. 使用浏览器打开项目的 GitHub 存储库。

  6. 选择操作查看工作流的运行情况。

    GitHub 工作流运行的屏幕截图。

进行代码更改并推送代码更改

  1. 在项目的 /src/web/src/layout 目录中,打开 header.tsx

  2. 找到行 <Text variant="xLarge">ToDo</Text>

  3. 将文本 ToDo 更改为 myTodo

  4. 保存文件。

  5. 提交更改。 提交更改将启动 GitHub Action 管道来部署更新。

    对测试文件进行更改和提交更改所需的步骤的屏幕截图。

  6. 使用浏览器打开项目的 GitHub 存储库,查看两者:

    • 你的提交
    • 正在设置的 GitHub Actions 的提交。

    GitHub 中已提交更改的屏幕截图。

  7. 选择操作以查看工作流中反映的测试更新。

    测试更新后运行的 GitHub 工作流的屏幕截图。

  8. 访问 Web 前端 URL 以检查更新。

azd 作为 GitHub 操作

azd 添加为 GitHub 操作。 此操作将安装 azd。 要使用它,可以在 .github\workflows\azure-dev.yml 中添加以下内容:

on: [push]

jobs:
   build:
      runs-on: ubuntu-latest
      steps:
         - name: Install azd
         uses: Azure/setup-azd@v0.1.0

清理资源

当不再需要本文中创建的 Azure 资源时,请运行以下命令:

azd down

高级功能

可以根据特定的模板方案或要求扩展 azd pipeline config 命令,如以下部分所述。

其他机密或变量

默认情况下,azd 设置管道的变量和机密。 例如,每当执行 azd pipeline config 命令时,它都会将 subscription idenvironment nameregion 创建为管道变量。 然后,管道定义引用这些变量:

env:
   AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}
   AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
   AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }}
   AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }}
   AZURE_LOCATION: ${{ vars.AZURE_LOCATION }}

管道运行时,azd 从环境获取值,这些值映射到变量和机密。 根据模板,可能会有一些设置可以使用环境变量进行控制。 例如,可以设置名为 KEY_VAULT_NAME 的环境变量来定义模板基础结构中密钥保管库资源的名称。 对于此类情况,模板可以使用 azure.yaml 定义变量和机密列表。 例如,请考虑以下 azure.yaml 配置:

pipeline:
  variables:
    - KEY_VAULT_NAME
    - STORAGE_NAME
  secrets:
    - CONNECTION_STRING

使用此配置,azd 检查环境中是否有任何变量或机密具有非空值。 然后,azd 使用配置中的键名称作为变量或机密的名称,并使用环境中的非字符串值作为值,为管道创建变量或机密。

然后,azure-dev.yaml 管道定义可以引用变量或机密:

- name: Provision Infrastructure
   run: azd provision --no-prompt
   env:
      KEY_VAULT_NAME: ${{ variables.KEY_VAULT_NAME }}
      STORAGE_NAME: ${{ variables.STORAGE_NAME }}
      CONNECTION_STRING: ${{ secrets.CONNECTION_STRING }}

注意

在更新 azure.yaml 中的机密或变量列表后,必须运行 azd pipeline config,以便 azd 重置管道值。

基础结构参数

请考虑以下 bicep 示例:

@secure()
param BlobStorageConnection string

参数 BlobStorageConnection 未设置默认值,因此 azd 会提示用户输入值。 但是,CI/CD 期间没有交互式提示。 azd 必须在运行 azd pipeline config 时请求参数的值,将该值保存在管道中,然后在管道运行时再次获取该值。

azd 使用名为 AZD_INITIAL_ENVIRONMENT_CONFIG 的管道机密来自动保存和设置管道中所有必需参数的值。 只需在管道中引用此机密:

- name: Provision Infrastructure
   run: azd provision --no-prompt
   env:
      AZD_INITIAL_ENVIRONMENT_CONFIG: ${{ secrets.AZD_INITIAL_ENVIRONMENT_CONFIG }}

管道运行时,azd 从机密中获取参数的值,从而不需要交互式提示。

注意

如果添加新参数,则必须重新运行 azd pipeline config

创建管道定义

如果 azd 模板还没有 CI/CD 管道定义文件,可以自行创建一个。 CI/CD 管道定义通常有 4 个主要部分:

  • 触发器
  • 权限
  • 操作系统或池
  • 要运行的步骤

以下示例演示如何为 GitHub Actions 和 Azure Pipelines 创建定义文件和相关配置。

在 GitHub Actions 中运行 azd 需要以下配置:

  • 授予 id-token: writecontents: read 访问范围。
  • 安装 azd 操作,除非你使用的是已经安装了 azd 的 docker 映像。

可以使用以下模板作为自己的管道定义的起点:

on:
  workflow_dispatch:
  push:
    # Run when commits are pushed to mainline branch (main or master)
    # Set this to the mainline branch you are using
    branches:
      - main
      - master

# Set this permission if you are using a Federated Credential.
permissions:
  id-token: write
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    # azd build-in variables.
    # This variables are always set by `azd pipeline config`
    # You can set them as global env (apply to all steps) or you can add them to individual steps' environment
    env:
      AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}
      AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}
      AZURE_SUBSCRIPTION_ID: ${{ vars.AZURE_SUBSCRIPTION_ID }}
      AZURE_ENV_NAME: ${{ vars.AZURE_ENV_NAME }}
      AZURE_LOCATION: ${{ vars.AZURE_LOCATION }}
      ## Define the additional variables or secrets that are required globally (provision and deploy)
      # ADDITIONAL_VARIABLE_PLACEHOLDER: ${{ variables.ADDITIONAL_VARIABLE_PLACEHOLDER }}
      # ADDITIONAL_SECRET_PLACEHOLDER: ${{ secrets.ADDITIONAL_SECRET_PLACEHOLDER }}      
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      # using the install-azd action
      - name: Install azd
        uses: Azure/setup-azd@v1.0.0

      # # If you want to use azd-daily build, or install it from a PR, you can remove previous step and
      # # use the next one:
      # - name: Install azd - daily or from PR
      #  # Update this scrip based on the OS - pool of your pipeline. This example is for a linux pipeline installing daily build
      #  run: curl -fsSL https://aka.ms/install-azd.sh | bash -s -- --version daily
      #  shell: pwsh

      # azd set up Federated Credential by default. You can remove this step if you are using Client Credentials
      - name: Log in with Azure (Federated Credentials)
        if: ${{ env.AZURE_CLIENT_ID != '' }}
        run: |
          azd auth login `
            --client-id "$Env:AZURE_CLIENT_ID" `
            --federated-credential-provider "github" `
            --tenant-id "$Env:AZURE_TENANT_ID"
        shell: pwsh

      ## If you set up your pipeline with Client Credentials, remove previous step and uncomment this one
      # - name: Log in with Azure (Client Credentials)
      #   if: ${{ env.AZURE_CREDENTIALS != '' }}
      #   run: |
      #     $info = $Env:AZURE_CREDENTIALS | ConvertFrom-Json -AsHashtable;
      #     Write-Host "::add-mask::$($info.clientSecret)"

      #     azd auth login `
      #       --client-id "$($info.clientId)" `
      #       --client-secret "$($info.clientSecret)" `
      #       --tenant-id "$($info.tenantId)"
      #   shell: pwsh
      #   env:
      #     AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Provision Infrastructure
        run: azd provision --no-prompt
        env:
         #  # uncomment this if you are using infrastructure parameters
         #  AZD_INITIAL_ENVIRONMENT_CONFIG: ${{ secrets.AZD_INITIAL_ENVIRONMENT_CONFIG }}
         ## Define the additional variables or secrets that are required only for provision 
         #  ADDITIONAL_VARIABLE_PLACEHOLDER: ${{ variables.ADDITIONAL_VARIABLE_PLACEHOLDER }}
         #  ADDITIONAL_SECRET_PLACEHOLDER: ${{ secrets.ADDITIONAL_SECRET_PLACEHOLDER }}

      - name: Deploy Application
        run: azd deploy --no-prompt
        env:
         ## Define the additional variables or secrets that are required only for deploy
         #  ADDITIONAL_VARIABLE_PLACEHOLDER: ${{ variables.ADDITIONAL_VARIABLE_PLACEHOLDER }}
         #  ADDITIONAL_SECRET_PLACEHOLDER: ${{ secrets.ADDITIONAL_SECRET_PLACEHOLDER }}