借助 GitHub Actions 实现 Databricks 应用的 CI/CD

本页介绍如何使用 GitHub Actions 和 Declarative Automation Bundles0 从 GitHub 自动部署 Databricks 应用。 它涵盖工作负荷标识联合、工作流 YAML 和运行状况检查,用于确认应用在每个部署后提供最新代码。

有关Azure Databricks作业和管道的通用GitHub Actions指南,请参阅 GitHub Actions。 有关工作负荷标识联合设置,请参阅 为 GitHub Actions 提供工作负荷标识联合身份验证。

Requirements

  • 您 Azure Databricks 帐户中的、拥有已部署应用的服务主体。 请参阅 向帐户添加服务主体
  • GitHub存储库的根目录中的 databricks.yml 捆绑配置,将应用声明为资源。 请参阅应用
  • 为一次性安装任务在本地安装的 Databricks CLI。 请参阅安装或更新 Databricks CLI

第 1 步。 配置工作负载身份联合

工作负载身份联合使 GitHub Actions 运行器能够使用短期有效的 OIDC 令牌向 Azure Databricks 进行身份验证,而不是将凭据存储在代码库中。

按照 为 GitHub Actions 启用工作负载身份联合中的步骤,在您的服务主体上创建 GitHub Actions 联合策略。 记下服务主体应用程序 ID(UUID)和工作区 URL。 在工作流中,需要两者作为变量。

然后,向应用授予服务主体 CAN MANAGE 权限;如果应用尚不存在,则授予创建应用的工作区权限。 请参阅 配置 Databricks 应用的权限

第 2 步。 配置GitHub存储库

在GitHub存储库中,创建部署环境来存储工作区连接变量。 使用环境还可以要求在部署运行前进行手动审批。

  1. “设置环境”>中,创建一个名为prod(或工作流引用的任何名称)的环境。
  2. 对于 环境变量,请添加以下内容:
Variable Value
DATABRICKS_HOST 工作区 URL,例如 https://my-workspace.cloud.databricks.com
DATABRICKS_CLIENT_ID 步骤 1 中的服务主体应用程序 ID

两个值都不是凭据。 服务主体的联合身份验证策略控制谁可以作为该服务主体进行身份验证,因此仅凭客户端 ID 本身并不能授予访问权限。 不需要客户端密码。

步骤 3. 为生产环境部署配置软件包

databricks.yml 中,在你的 prod 目标上声明显式工作区 hostroot_path。 这可确保该包在每次运行时都部署到同一位置。 除非 run_as 设置为服务主体,否则生产模式验证需要这两个字段。 请参阅 声明性自动化捆绑包部署模式

targets:
  prod:
    mode: production
    workspace:
      host: https://my-workspace.cloud.databricks.com
      root_path: /Workspace/Users/<service-principal-or-owner>/.bundle/${bundle.name}/${bundle.target}
    resources:
      apps:
        my_app:
          name: my-app
          source_code_path: ./app

<service-principal-or-owner> 替换为拥有这些捆绑包构件的工作区用户,通常为服务主体应用程序 ID。

./app 替换为你的应用源代码相对于 databricks.yml 的路径。 当 source_code_path 应用代码与捆绑包位于同一存储库中时,该字段是必需的。 如果应用代码位于单独的存储库中,请改用 git_source 。 请参阅应用

步骤 4. 添加部署工作流

.github/workflows/deploy.yml 添加到您的存储库中:

name: Deploy to Databricks Apps

on:
  workflow_dispatch:
  # Uncomment to deploy on every push to main once the workflow is validated.
  # push:
  #   branches: [main]

permissions:
  id-token: write # required for OIDC federation
  contents: read

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment: prod
    env:
      DATABRICKS_AUTH_TYPE: github-oidc
      DATABRICKS_HOST: ${{ vars.DATABRICKS_HOST }}
      DATABRICKS_CLIENT_ID: ${{ vars.DATABRICKS_CLIENT_ID }}
    steps:
      - uses: actions/checkout@v4

      - name: Install Databricks CLI
        uses: databricks/setup-cli@main

      - name: Validate bundle
        run: databricks bundle validate --target prod

      - name: Deploy bundle
        run: databricks bundle deploy --target prod

      - name: Start or restart app
        run: databricks bundle run my_app --target prod

将最后一步中的 my_app 替换为你的 databricks.ymlresources.apps 下使用的资源键。

运行器需要拥有 id-token: write 权限才能请求 OIDC 令牌。 该 databricks/setup-cli 操作会自动读取 DATABRICKS_AUTH_TYPE=github-oidc 和处理身份验证。

Warning

databricks bundle deploy 上传源代码和更新资源,但不会重启应用进程。 如果跳过最后这一步 databricks bundle run,部署会在 CI 中通过,而应用仍会继续提供之前的代码。 部署后务必运行资源包。

步骤 5. 等待应用进入健康状态

Databricks 建议在部署后添加状态轮询步骤。 databricks bundle run 一旦它向应用发出启动信号,就会退出,但应用可能尚未运行。 由于缺少依赖项、缺少环境变量或端口冲突等问题,启动期间它仍可能会失败。 添加轮询步骤可确保启动失败时工作流也会失败:

- name: Wait for app to be running
  env:
    APP_NAME: my-app
  run: |
    for i in $(seq 1 20); do
      STATE=$(databricks apps get "$APP_NAME" --output json | jq -r '.app_status.state')
      echo "Attempt $i/20: state=$STATE"
      if [ "$STATE" = "RUNNING" ]; then
        exit 0
      fi
      sleep 15
    done
    echo "App did not reach RUNNING state within 5 minutes" >&2
    exit 1

APP_NAME 设置为您的 databricks.ymlresources.apps.<key>.name 下声明的值,而不是捆绑包资源键。

处理现有应用

应用名称在整个工作区中是唯一的。 当另一个软件包(或手动创建的应用)已拥有一个同名应用时,bundle deploy 步骤会因 An app with the same name already exists 而失败。 将捆绑包绑定到现有应用,而不是重新创建它。

在本地运行此包以将捆绑包附加到现有应用:

databricks bundle deployment bind my_app <existing-app-name> --target prod --auto-approve

然后重新运行工作流。 后续部署将重复使用绑定。

如果现有应用具有你的 databricks.yml 中没有的服务器端配置(例如 budget_policy_id),请在重新部署之前将其复制到捆绑包文件中。 出现不匹配时,在 bundle 部署步骤中会显示为 Terraform“结果不一致”错误。

选择触发器

workflow_dispatch 开始,以便首次部署为手动。 在成功运行几次之后,请添加 push: branches: [main],以便在每次合并时进行部署。

为了增加一道额外的安全关卡,请在 prod 环境的 设置>环境>prod>部署保护规则 中为其配置所需的审阅者。 每次工作流运行都会在部署作业开始前等待审批者批准。

后续步骤