CI/CD für Databricks-Apps mit GitHub Actions

Auf dieser Seite wird erläutert, wie Sie die Bereitstellung einer Databricks-App aus GitHub mit GitHub Actions und Declarative Automation Bundles automatisieren. Er umfasst den Workload-Identitätsverbund, den Workflow-YAML und eine Integritätsprüfung, die bestätigt, dass die App nach jeder Bereitstellung den neuesten Code bereitstellt.

Allgemeine GitHub Actions Anleitungen für Azure Databricks Aufträge und Pipelines finden Sie unter GitHub Actions. Informationen zur Einrichtung von Workload Identity Federation finden Sie unter Enable workload identity federation for GitHub Actions.

Requirements

Schritt 1. Workload Identity Federation konfigurieren

Der Workload-Identitätsverbund ermöglicht es dem GitHub Actions Läufer, sich mit Azure Databricks mithilfe eines kurzlebigen OIDC-Tokens zu authentifizieren, anstatt Anmeldeinformationen in Ihrem Repository zu speichern.

Führen Sie die Schritte in Enable workload identity federation for GitHub Actions aus, um eine GitHub Actions Verbundrichtlinie für Ihren Dienstprinzipal zu erstellen. Beachten Sie die Dienstprinzipalanwendungs-ID (UUID) und Ihre Arbeitsbereichs-URL. Sie benötigen beide als Variablen im Workflow.

Erteilen Sie dann dem Dienstprinzipal CAN MANAGE die Berechtigung für die App oder die Arbeitsbereichsberechtigung zum Erstellen von Apps, falls die App noch nicht existiert. Siehe Konfigurieren von Berechtigungen für eine Databricks-App.

Schritt 2. Konfigurieren des GitHub-Repositorys

Erstellen Sie in Ihrem GitHub-Repository eine Bereitstellungsumgebung zum Speichern der Arbeitsbereichsverbindungsvariablen. Durch die Verwendung einer Umgebung können Sie vor der Ausführung der Bereitstellungen auch eine manuelle Genehmigung anfordern.

  1. Unter Einstellungen>Umgebungen erstellen Sie eine Umgebung namens prod (oder einen beliebigen Namen, auf den Ihr Workflow verweist).
  2. Fügen Sie für Umgebungsvariablen Folgendes hinzu:
Variable Value
DATABRICKS_HOST Ihre Arbeitsbereichs-URL, z. B. https://my-workspace.cloud.databricks.com
DATABRICKS_CLIENT_ID Die Dienstprinzipalanwendungs-ID aus Schritt 1

Keiner der beiden Werte ist eine Anmeldeinformation. Die Verbundsrichtlinie für den Dienstprinzipal legt fest, wer sich als dieser authentifizieren kann; die Client-ID allein gewährt daher keinen Zugriff. Sie benötigen keinen geheimen Clientschlüssel.

Schritt 3. Konfigurieren Sie Ihr Paket für die Produktivbereitstellung

Deklarieren Sie in databricks.yml einen expliziten Arbeitsbereich host und root_path für Ihr prod-Ziel. Dadurch wird sichergestellt, dass das Bundle an demselben Speicherort bei jeder Ausführung bereitgestellt wird. Für die Validierung im Produktionsmodus sind beide Felder erforderlich, sofern run_as nicht auf einen Dienstprinzipal festgelegt ist. Sehen Sie sich Bereitstellungsmodi für deklarative Automatisierungs-Bundles an.

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

Ersetzen Sie durch <service-principal-or-owner> den Arbeitsbereichsbenutzer, der die Bündelartefakte besitzt, in der Regel die Dienstprinzipalanwendungs-ID.

Ersetzen Sie ./app durch den Pfad zum Quellcode Ihrer App relativ zu databricks.yml. Das source_code_path Feld ist erforderlich, wenn sich der App-Code im selben Repository wie das Bundle befindet. Wenn sich Ihr App-Code in einem separaten Repository befindet, verwenden Sie git_source stattdessen. Weitere Informationen finden Sie unter app.

Schritt 4. Hinzufügen des Bereitstellungsworkflows

Fügen Sie .github/workflows/deploy.yml Ihrem Repository hinzu:

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

Ersetzen Sie my_app im letzten Schritt durch den Ressourcenschlüssel, den Sie databricks.yml unter resources.appsverwenden.

Der Läufer benötigt die id-token: write Berechtigung, ein OIDC-Token anzufordern. Die databricks/setup-cli Aktion liest DATABRICKS_AUTH_TYPE=github-oidc und behandelt die Authentifizierung automatisch.

Warning

databricks bundle deploy lädt Quellcode hoch und aktualisiert Ressourcen, aber der App-Prozess wird nicht neu gestartet. Wenn Sie den letzten databricks bundle run-Schritt überspringen, läuft das Deployment in der CI erfolgreich durch, obwohl die App weiterhin den vorherigen Code ausliefert. Führen Sie die Bundleressource immer nach der Bereitstellung aus.

Schritt 5. Warten Sie, bis die App fehlerfrei ist.

Databricks empfiehlt, nach der Bereitstellung einen Statusabfragungsschritt hinzuzufügen. databricks bundle run wird beendet, sobald es signalisiert, dass die App gestartet werden soll, aber die App läuft möglicherweise noch nicht. Während des Starts kann es aufgrund von Problemen wie fehlenden Abhängigkeiten, einer fehlenden Umgebungsvariable oder einem Portkonflikt weiterhin fehlschlagen. Das Hinzufügen eines Abfrageschritts stellt sicher, dass bei einem fehlgeschlagenen Start auch der Workflow fehlschlägt:

- 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

Setzen Sie APP_NAME auf den Wert, den Ihr databricks.yml unter resources.apps.<key>.name deklariert, nicht auf den Bundle-Ressourcenschlüssel.

Behandeln einer vorhandenen App

App-Namen sind im gesamten Arbeitsbereich eindeutig. Der bundle deploy-Schritt schlägt mit An app with the same name already exists fehl, wenn ein anderes Paket (oder eine manuell erstellte App) bereits Inhaber einer App mit diesem Namen ist. Binden Sie Ihr Bündel an die vorhandene App, anstatt es neu zu erstellen.

Führen Sie dies einmal lokal aus, um das Bundle an die vorhandene App anzufügen:

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

Führen Sie dann den Workflow erneut aus. Nachfolgende Bereitstellungen verwenden die Bindung wieder.

Wenn die vorhandene App über serverseitige Konfigurationen verfügt (wie etwa budget_policy_id), die nicht in Ihrem databricks.yml enthalten sind, kopieren Sie diese vor der erneuten Bereitstellung in die Bundle-Datei. Fehlende Übereinstimmungen werden während des Bereitstellungsschritts als "inkonsistentes Ergebnis" des Terraform-Fehlers angezeigt.

Einen Trigger auswählen

Beginnen Sie mit workflow_dispatch, damit die erste Bereitstellung manuell erfolgt. Sobald ein paar Durchläufe erfolgreich sind, fügen Sie push: branches: [main] hinzu, um bei jedem Merge bereitzustellen.

Konfigurieren Sie die prod-Umgebung als zusätzliche Sicherheitsschranke mit erforderlichen Prüfern unter Settings>Environments>prod>Deployment protection rules. Jede Workflowausführung wartet auf eine Freigabe, bevor der Bereitstellungsauftrag startet.

Nächste Schritte