CI/CD para aplicações Databricks com GitHub Actions

Esta página explica como automatizar a implementação de uma aplicação Databricks a partir de GitHub utilizando GitHub Actions e Declarative Automation Bundles. Abrange a federação da identidade da carga de trabalho, o workflow YAML e uma verificação de estado que confirma que a aplicação está a servir o código mais recente após cada implementação.

Para obter orientações gerais sobre o GitHub Actions para tarefas e pipelines do Azure Databricks, consulte GitHub Actions. Para a configuração da federação da identidade da carga de trabalho, veja Ativar a federação da identidade da carga de trabalho para GitHub Actions.

Requirements

Passo 1. Configurar a federação de identidades de cargas de trabalho

A federação de identidade de carga de trabalho permite que o runner do GitHub Actions autentique com o Azure Databricks usando um token OIDC de curta duração em vez de armazenar credenciais no seu repositório.

Siga os passos em Ative a federação de identidades de carga de trabalho para GitHub Actions para criar uma política de federação GitHub Actions no seu principal de serviço. Note o ID da aplicação principal do serviço (UUID) e o URL do seu espaço de trabalho. Precisas de ambos como variáveis no fluxo de trabalho.

Depois, conceda à entidade de serviço CAN MANAGE permissão para a aplicação ou permissão no espaço de trabalho para criar aplicações, se a aplicação ainda não existir. Consulte Configurar permissões para um aplicativo Databricks.

Passo 2. Configure o repositório do GitHub

No teu repositório GitHub, cria um ambiente de implementação para armazenar as variáveis de ligação do espaço de trabalho. Usar um ambiente também permite exigir aprovação manual antes de as implementações serem executadas.

  1. Em Definições>Ambientes, crie um ambiente com o nome prod (ou qualquer nome a que o seu fluxo de trabalho faça referência).
  2. Para variáveis de Ambiente, adicione o seguinte:
Variable Value
DATABRICKS_HOST A URL do seu espaço de trabalho, por exemplo https://my-workspace.cloud.databricks.com
DATABRICKS_CLIENT_ID O ID da aplicação do principal de serviço da Etapa 1

Nenhum dos valores é uma credencial. A política de federação do principal de serviço controla quem se pode autenticar como ele, pelo que o ID de cliente, por si só, não concede acesso. Não precisas de um segredo de cliente.

Passo 3. Configure o seu bundle para implementações em produção

Em databricks.yml, declare um espaço de trabalho explícito host e root_path no seu prod destino. Isto garante que o pacote é implementado no mesmo local sempre que é executado. A validação em modo de produção requer ambos os campos, a menos que run_as esteja definido como um principal de serviço. Consulte os modos de implementação dos Pacotes de Automação Declarativa.

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

Substitua <service-principal-or-owner> pelo utilizador do espaço de trabalho que detém os artefactos do bundle, normalmente o ID da aplicação principal do serviço.

Substitua ./app pelo caminho para o código-fonte da sua aplicação em relação a databricks.yml. O source_code_path campo é obrigatório quando o código da aplicação está no mesmo repositório que o pacote. Se o código da sua aplicação estiver num repositório separado, use git_source em vez disso. Veja o aplicativo.

Passo 4. Adicionar o fluxo de trabalho de implementação

Adicione .github/workflows/deploy.yml ao seu repositório:

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

Substitua my_app no último passo pela chave de recurso que o seu databricks.yml utiliza em resources.apps.

O runner precisa da permissão id-token: write para solicitar um token OIDC. A databricks/setup-cli ação lê DATABRICKS_AUTH_TYPE=github-oidc e gere a autenticação automaticamente.

Advertência

databricks bundle deploy Carrega o código-fonte e atualiza os recursos, mas não reinicia o processo da aplicação. Se saltar o passo final databricks bundle run , a implementação passa no CI enquanto a aplicação continua a servir o código anterior. Executa sempre o recurso bundle depois de implementar.

Passo 5. Espera que a aplicação fique saudável

O Databricks recomenda adicionar uma etapa de sondagem de estado após a implementação. databricks bundle run Sai assim que sinaliza para a aplicação começar, mas a app pode ainda não estar a correr. Ainda assim, pode falhar durante o arranque devido a problemas como dependências em falta, uma variável de ambiente em falta ou um conflito de portas. Adicionar uma etapa de consulta garante que uma falha no arranque também faz falhar o fluxo de trabalho:

- 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

Defina APP_NAME para o valor que databricks.yml declara em resources.apps.<key>.name, e não para a chave de recursos do bundle.

Gestão de uma aplicação existente

Os nomes das apps são únicos em todo o espaço de trabalho. O passo bundle deploy falha com An app with the same name already exists quando outro bundle (ou uma aplicação criada manualmente) já é proprietário de uma aplicação com esse nome. Vincule o seu pacote à aplicação existente em vez de o recriar.

Executa isto uma vez localmente para ligar o bundle à aplicação existente:

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

Depois volta a executar o fluxo de trabalho. As implementações subsequentes reutilizam a associação.

Se a aplicação existente tiver uma configuração do lado do servidor (como budget_policy_id) que não está no seu databricks.yml, copie-a para o ficheiro bundle antes de voltar a implementar. As discrepâncias manifestam-se como um erro de "resultado inconsistente" do Terraform durante a etapa de implementação do bundle.

Escolher um acionador

Comece com workflow_dispatch para que a primeira implementação seja manual. Quando algumas execuções forem bem-sucedidas, adicione push: branches: [main] para fazer a implementação sempre que houver uma fusão.

Para uma camada adicional de segurança, configure o ambiente prod com revisores obrigatórios em Definições>Ambientes>prod>Regras de proteção da implementação. Cada execução do fluxo de trabalho aguarda a aprovação de um aprovador antes de a tarefa de implementação começar.

Passos seguintes