LoginSignup
1
0

More than 1 year has passed since last update.

Databricks の CI (Continuous Integration(継続的インテグレーション)) パイプラインを Azure DevOps (Pipelines) にて構築する手順

Last updated at Posted at 2022-10-01

概要

Databricks の CI (Continuous Integration(継続的インテグレーション)) パイプラインを Azure DevOps (Pipelines) にて構築する手順を紹介します。Databricks ノートブックで開発することを前提としており、Databricks Repos における Databricks Workspace 上ではノートブック形式となるが Git 上では Python ファイルとなる仕様に基づいたパイプラインとなっております。継続的な品質保証に必要となる、テスト結果の発行だけでなく、コードカバレッジの発行も実施できるようになっております。

本手順で構築できるパイプラインの概要は次のようになっております。

  • カレントブランチのコードに対してテストを、PR 時や CI トリガーなどにより並列で実行が可能
  • パイプライン実行の並列性を高めるために、テストケースの作成方法の工夫、Databricks Workflows 上でのテスト実行、及び、Azure Pipelines の エージェントレスジョブの活用を実施
  • tests/unit 配下のテストケースのテストをDatabricks 上でノートブックとしてのテスト実行だけでなく、Python ファイルとしてのテスト実行も行うことで、パイプライン実行後にテスト結果とコードカバレッジの確認が可能

パイプラインの全体像を、次の画像で示します。

image.png

Azure DevOps(Piplines)上で、テスト結果やコードカバレッジを下記画像のように確認できます。

image.png

image.png

image.png

Azure DevOps のパブリックプロジェクトとして公開しており、下記の URL にてパイプラインの実行結果を確認できます。

本手順で利用するレポジトリーは、 Github 上に配置してあります。

本記事の位置付け

次の開発ガイドシリーズにおける DevOps 分野の1記事であり、リンク先には記事にて記事の全体像を整理している。

GroupID 分野
T10 Spark概要
T20 データエンジニアリング
T30 データ品質チェック
T40 データサイエンス
T50 メタデータデプロイ
T60 テスト
T70 DevOps

Azure Pipeline 定義

1. 処理概要

Databricks CI パイプラインとしては、次の処理を実施します。

  1. ノートブックでの単体テストの実施
    • Databricks Repos を作成
    • Databricks Workflows(Notbook Type) でのテストの実施とテスト結果の発行
      • Databricks Workflows(Notbook Type) の作成と実行
      • Databricks Workflows 処理の完了確認
      • テスト結果(JUnit 形式の XML ファイル)を Azure Pipelines に発行
  2. Python スクリプトでの単体テストの実施
    • コードを DBFS にコピー
    • Databricks Workflows(Python script type)でのテストの実施とテスト結果の発行
      • Databricks Workflows(Python script type)の作成と実行
      • Databricks Workflows 処理の完了確認
      • テスト結果(JUnit 形式の XML ファイル)を Azure Pipelines に発行
  3. 単体テストのコードカバレッジの発行
    • コードカバレッジ結果の統合と発行
      • DBFS からコードカバレッジ結果(.coverage)をコピー
      • コードカバレッジ結果の統合( combine )
      • コードカバレッジ結果を Cobertura 形式の XML ファイルへ変換
      • コードカバレッジ結果を発行
  4. 事後処理
    • DBFS 上のコード等を削除
    • Databricks Repos 上のディレクトリを削除

2. 定義概要

Azure Pipelines にてci__execute_unit_test_on_databricks.yml を CI パイプラインとして登録しており、複数の YAML ファイルを定義しています。YAML ファイルにおける処理フローと留意事項を下記に示します。

ci__execute_unit_test_on_databricks.yml

  • 処理フロー
    • templates/jobs/create_databricks_repos_for_test.yml を呼び出し、Databricks Repos を作成
    • templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml を呼び出し、Databricks Workflows(Notbook Type) でのテストの実施とテスト結果の発行
    • templates/jobs/copy_codes_to_dbfs.yml を呼び出し、コードを DBFS 上にコピー
    • templates/stages/execute_databricks_workflows_for_test_by_python_type.yml を呼び出し、Databricks Workflows(Python script type)でのテストの実施とテスト結果の発行
    • templates/jobs/publish_code_coverage.yml を呼び出し、コードカバレッジ結果の統合と発行
    • templates/jobs/delete_codes_on_dbfs.yml を呼び出し、DBFS 上のコード等を削除
    • templates/jobs/delete_codes_on_dbfs.yml を呼び出し、Databricks Repos 上のディレクトリを削除
  • 留意事項
    • パイプライン外部で定義する必要がある変数をコメントアウトしており、databricks_dev変数グループを定義することが前提
    • template により他 YAML ファイルを呼び出す
    • ノートブックでのテスト、および、Python スクリプトでのテストは複数バージョンの実施が可能

templates/jobs/create_databricks_repos_for_test.yml

  • 処理フロー
    • Databricks repos API により、Databricks 上の Repos 上にディレクトリを作成
    • Databricks repos API により、Databricks 上の Repos を作成
    • Databricks repos API により、Databricks 上の Repos における、ブランチ、あるいは、タグを更新
  • 留意事項
    • 特になし

templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml

  • 処理フロー
    • templates/jobs/execute_databricks_notobook_task_workflows_for_unit_test.yml を呼び出し、Databricks Workflows の作成と実行を実施
    • templates/jobs/check_status_on_databricks_workflows.yml を呼び出し、Databricks Workflows の完了を監視
    • templates/jobs/publish_test_results_of_unittest.yml を呼び出し、テスト結果のファイルを DBFS からコピーし、Azure Pipelines に公開
    • templates/jobs/delete_databricks_workflows.yml を呼び出し、Databricks Workflows を削除
  • 留意事項
    • /runs/submit API が共有ジョブクラスターをサポートしていないため(ドキュメントへのリンク)、Databricks Workflows の作成・実行・削除を実施

templates/stages/execute_databricks_workflows_for_test_by_python_type.yml

  • 処理フロー
    • templates/jobs/execute_databricks_python_task_workflows_for_unit_test.yml を呼び出し、Databricks Workflows の作成と実行を実施
    • templates/jobs/check_status_on_databricks_workflows.yml を呼び出し、Databricks Workflowsの完了を監視
    • templates/jobs/publish_test_results_of_pytest.yml を呼び出し、テスト結果のファイルを DBFS からコピーし、Azure Pipelines に公開
    • templates/jobs/delete_databricks_workflows.yml を呼び出し、Databricks Workflows を削除
  • 留意事項
    • /runs/submit API が共有ジョブクラスターをサポートしていないため(ドキュメントへのリンク)、Databricks Workflows の作成・実行・削除を実施

templates/jobs/execute_databricks_notobook_task_workflows_for_unit_test.yml

  • 処理フロー
    • Databricks REST API により、1タスクをもつ Databricks Workflows を作成
    • Databricks REST API により、前の手順で作成した Databricks Workflows を実行
  • 留意事項
    • 特になし

templates/jobs/execute_databricks_python_task_workflows_for_unit_test.yml

  • 処理フロー
    • Databricks REST API により、10タスクをもつ Databricks Workflows を作成
    • Databricks REST API により、前の手順で作成した Databricks Workflows を実行
  • 留意事項
    • 特になし

templates/jobs/check_status_on_databricks_workflows.yml

  • 処理フロー
    • Databricks REST API により、Databrikcs Workflows が成功(SUCCESS)したことを確認
    • Databrikcs Workflows が実行されない(state.life_cycle_stateRUNNING 、あるいは、TERMINATED とならない)場合にエラー終了とする
    • SUCCESSとならない場合には、エージェントレスジョブの Delay タスクにより指定分(delay_for_minutesパラメータ値)待機後に、再度ステータスを確認(最大20回)
    • 20回待機しても処理が完了しない場合にエラー終了となる
  • 留意事項
    • カウンターによるループ処理を実施できないため、job_names パラメータ項目によるループ処理を実施

templates/jobs/publish_test_results_of_unittest

  • 処理フロー
    • databricks-cli や pytest などの Python ライブラリをインストール
    • Databricks CLI にて、DBFS から テスト結果のファイルをコピー
    • PublishTestResultsタスクにより、テスト結果を表示
  • 留意事項
    • pytest により出力されるテスト結果ファイルの命名規則に合わせて発行を行う
    • テスト実施環境ごとにまとめるためにテスト環境のテスト結果ごとに発行処理を行う

templates/jobs/publish_test_results_of_pytest.yml

  • 処理フロー
    • databricks-cli や pytest などの Python ライブラリをインストール
    • Databricks CLI にて、DBFS から テスト結果のファイルをコピー
    • PublishTestResultsタスクにより、テスト結果を表示
  • 留意事項
    • unittest-xml-reporting による出力されるテスト結果ファイルの命名規則に合わせて発行を行う
    • テスト実施環境ごとにまとめるためにテスト環境のテスト結果ごとに発行処理を行う

templates/jobs/publish_code_coverage.yml

  • 処理フロー
    • databricks-cli や pytest などの Python ライブラリをインストール
    • Databricks CLI にて、DBFS から コードカバレッジ結果のファイルをコピー
    • Coverageコマンドにて、複数のコードカバレッジ結果ファイルを単一ファイルに統合し、Cobertura 形式の XML ファイルに変換
    • PublishCodeCoverageResultsタスクにより、コードカバレッジ結果を表示
  • 留意事項
    • PublishCodeCoverageResultsタスクにて、複数ファイルの公開に対応していない(ドキュメントへの)ため、単一ファイルに統合
    • カバレッジ生成対象ディレクトリ(--cov)とカバレッジ発行時の設定(PublishCodeCoverageResultsにおけるpathToSources)を同一のディレクトリに設定
    • Azure Pipelines 上で コードカバレッジ結果を確認する際には、日本語は文字化けする場合がある

templates/jobs/delete_databricks_workflows.yml

  • 処理フロー
    • Databricks REST API にて、Databricks Workflows を削除
  • 留意事項
    • conditionalways に設定することで、パイプラインの成功有無に関わらず処理を実行

templates/jobs/delete_codes_on_dbfs.yml

  • 処理フロー
    • Databricks REST API にて、DBFS 上に配置したファイルを削除
  • 留意事項
    • conditionalways に設定することで、パイプラインの成功有無に関わらず処理を実行

templates/jobs/delete_databricks_respos_for_test.yml

  • 処理フロー
    • Databricks REST API にて、Repos 上に作成したディレクトリを削除
  • 留意事項
    • conditionalways に設定することで、パイプラインの成功有無に関わらず処理を実行

3. CI パイプラインにおける Databricks ランタイムの変更手順

3-1. ノートブックでの単体テストにおける Databricks ランタイムの変更手順

1. Databricks Runtime のバージョン変更

templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml を呼び出す際の変数を変更する。

  - template: templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml
    parameters:
      job_suffix_name: notebook_11_5
      databricks_cluster_runtime_version: 11.5.x-scala2.12
      test_results_path: $(TEST_CODE_PATH_ON_DBFS)/$(PIPELINE_ID)/.test_results/notebook_11_5
      delay_for_minutes: 5

依存関係がある GetAndPublishCodeCoverage ステージの dependsOn の項目(GetAndPublishTestResults_*)を変更する。

  - stage: GetAndPublishCodeCoverage
    displayName: Get and publish code coverage
    condition: succeededOrFailed()
    dependsOn:
      - GetAndPublishTestResults_python_9_1
      - GetAndPublishTestResults_python_10_4
      - GetAndPublishTestResults_notebook_11_5
    jobs:
      - template: templates/jobs/publish_code_coverage.yml

2. ノートブックでの単体テスト

templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml を呼び出すテンプレートを追加。

  - template: templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml
    parameters:
      job_suffix_name: notebook_11_5
      databricks_cluster_runtime_version: 11.5.x-scala2.12
      test_results_path: $(TEST_CODE_PATH_ON_DBFS)/$(PIPELINE_ID)/.test_results/notebook_11_5
      delay_for_minutes: 5

依存関係がある GetAndPublishCodeCoverage ステージの dependsOn に項目(GetAndPublishTestResults_*)を追加する。

  - stage: GetAndPublishCodeCoverage
    displayName: Get and publish code coverage
    condition: succeededOrFailed()
    dependsOn:
      - GetAndPublishTestResults_python_9_1
      - GetAndPublishTestResults_python_10_4
      - GetAndPublishTestResults_notebook_10_4
      - GetAndPublishTestResults_notebook_11_5
    jobs:
      - template: templates/jobs/publish_code_coverage.yml

3-2. Python スクリプトでの単体テストの実における Databricks ランタイムの変更手順

1. Databricks Runtime のバージョン変更

templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml を呼び出す際の変数を変更する。

  - template: templates/stages/execute_databricks_workflows_for_test_by_python_type.yml
    parameters:
      job_suffix_name: python_11_5
      databricks_cluster_runtime_version: 11.5.x-scala2.12
      delay_for_minutes: 5

依存関係がある GetAndPublishCodeCoverage ステージの dependsOn の項目(GetAndPublishTestResults_*)を変更する。

  - stage: GetAndPublishCodeCoverage
    displayName: Get and publish code coverage
    condition: succeededOrFailed()
    dependsOn:
      - GetAndPublishTestResults_python_10_4
      - GetAndPublishTestResults_python_11_5
      - GetAndPublishTestResults_notebook_10_4
    jobs:
      - template: templates/jobs/publish_code_coverage.yml

2. ノートブックでの単体テスト

templates/stages/execute_databricks_workflows_for_test_by_notebook_type.yml を呼び出すテンプレートを追加。

  - template: templates/stages/execute_databricks_workflows_for_test_by_python_type.yml
    parameters:
      job_suffix_name: python_11_5
      databricks_cluster_runtime_version: 11.5.x-scala2.12
      delay_for_minutes: 5

依存関係がある GetAndPublishCodeCoverage ステージの dependsOn に項目(GetAndPublishTestResults_*)を追加する。

  - stage: GetAndPublishCodeCoverage
    displayName: Get and publish code coverage
    condition: succeededOrFailed()
    dependsOn:
      - GetAndPublishTestResults_python_9_1
      - GetAndPublishTestResults_python_10_4
      - GetAndPublishTestResults_python_11_5
      - GetAndPublishTestResults_notebook_10_4
    jobs:
      - template: templates/jobs/publish_code_coverage.yml

構築手順

0. 事前準備

1. 変数の設定について

変数グループ、あるいは、Pipeline にて、次の変数を設定。

# 変数名 設定値例 概要
1 DATABRICKS_WORKSPACE_URL tps://adb-5555555555555555.19.azuredatabricks.net Databricks Workspace URL を指定。
2 DATABRICKS_TOKEN dapi1234 Databricks トークン を指定。
3 TARGET_TEST_PATH tests/unit Python script type の Databricks Workflows を実行する際のテストケースを保持したディレクトリを指定。
4 TEST_MAIN_NOTEBOOK_PATH tests/unit/main__ut__v1 Notebook Type の Databricks Workflows を実行するノートブックのパスを指定。

次の変数は、YAML 上で定義しており、必要に応じて変更。

# 変数名 設定値例 概要
5 PIPELINE_ID $(System.TeamProjectId)$(System.DefinitionId)$(Build.BuildNumber) パイプライン実行時の一意の値を指定。
6 TEST_CODE_PATH_ON_DBFS /FileStore/unit テスト実行時に利用する DBFS 上のディレクトリを指定。

1. Databricks 上で Git 認証情報の登録

1. Azure DevOps にて、Personal access token を取得

image.png

2. Databricks に接続後、右上のアカウント名 -> User Setting を選択

image.png

3. Git integration タブにて、Git の認証情報を設定

image.png

4. Repos を追加できることを確認

image.png

2. 変数グループを作成

1. Azure DevOps に接続後、Library -> + Variable Groupを選択

image.png

2. Variable group name にて、databricks_dev と入力

image.png

3. + Addを選択し変数を追加後 ,Save を選択

image.png

3. パイプラインを作成

1. Azure DevOps に接続後、Piplines -> create pipline を選択

image.png

2. Where is your code? にて Azure Repos Git を 選択

image.png

3. Select a repository にて、Azure pipelines の YAML 定義を保持しているレポジトリーを選択

image.png

4. Configure your pipeline にて、Existing Azure Pipelines YAML fileを選択

image.png

5. Select an existing YAML fileにて、Branch にて main を選択後、Path.azuredevops/ci__execute_unit_test_on_databricks.yml と入力し、Continue を選択

image.png

6. Variables を選択し、変数を追加後、 Save を選択。

image.png

7. Save を選択。

image.png

4. パイプラインを実行

1. 作成した pipelines の画面にて、Run pipelines を選択

image.png

2. Branch/tag にて main を設定後、Run を選択

image.png

3. すべての処理が完了し、publish_test_results がエラーとなる想定。

image.png

image.png

4. パイプラインの実行結果画面にて、Tests タブ、および、Code Coverage タブを確認

image.png

image.png

image.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0