デベロッパー

Cloud Build を使用して Composer 環境の Airflow オペレーターを常に最新の状態にする

#da

※この投稿は米国時間 2021 年 3 月 10 日に、Google Cloud blog に投稿されたものの抄訳です。

2020 年以前は、Airflow オペレーターを常に最新の状態にするには、Airflow の最新バージョンにアップグレードするか、バージョンの新しいオペレーターをプラグインとして取り込む必要がありました。現在では(Airflow 1.10.6 以降を使用している場合)、最新バージョンのオペレーターが PyPI モジュールとしてパッケージ化されており、これをお使いの Airflow 環境にインストールできます。今回の投稿では、Cloud Build および GitHub の自動化機能を利用して、Cloud Composer 環境のオペレーター(およびその他すべての PyPI パッケージ)を自動的に最新の状態にする方法をご紹介します。

注: Cloud Composer の環境によっては、バックポート パッケージがあらかじめインストールされている場合があります。実行中のバージョンのインストール内容について詳しくは、バージョン リストをご覧ください。

pasted_image_0_11

このチュートリアルを終えると、お使いのオペレーターの新バージョンがリリースされた際の開発フローは以下のようになります。

ステップ 0: オペレーターが更新される

ステップ 1: Renovate Bot が requirements-composer.txt ファイルに対して PR を開き、この更新を行う

ステップ 2: Cloud Build が単体テストを実行し、いずれの DAG もすぐに中断しないことを確認する

ステップ 3: PR が承認され main に統合される

ステップ 4: Cloud Build が開発環境を更新する

ステップ 5: 開発環境の DAG に問題がないか、担当者(人間)が確認する。問題がある場合は、手動で問題を解決し、要件ファイルを元に戻す必要がある。

ステップ 6: 担当者が本番環境の PyPI パッケージを手動で更新する

この投稿では、まず以下を行います。

  • Cloud Build が新しいバージョンのオペレーターで DAG を単体テストするために、また最終的に Composer 環境を更新するために使用する要件ファイルを作成する

  • DAG を単体テストするための Cloud Build ジョブを設定する

  • Composer 環境を更新するための Cloud Build ジョブを設定する

  • Airflow オペレーター(およびその他の依存関係)の更新を自動的にチェックする Renovate Bot を設定する

リポジトリの構成

このブログ投稿では、DAG とそのテストが GitHub リポジトリに保存されていると想定しています。サンプル リポジトリの中身はこのディレクトリに含まれています。DAG およびテストは、このディレクトリの dags フォルダに保存されており、要件ファイルと構成ファイルが最上位レベルにあります。

Cloud Build の設定

Cloud Build のステップは 2 つあります。1 つ目は、DAG を単体テストするための pull リクエストに応じて実行するもので、2 つ目は、最新の PyPI 依存関係を使用して Composer 環境を更新する "main" ブランチに PR が統合されたときに実行するものです。

作業 1 - DAG の単体テストの実行

要件ファイルの作成

Composer 環境にインストールされている PyPI モジュールを追跡するために私が使用しているのは、requirements-composer.txt という特殊なファイルです。このファイルは、私が DAG を保存している GitHub のリポジトリにあります。ここで、このファイルを作成しましょう。通常の requirements.txt ファイルと同じですが、特別な名前が付けられています。ここに、私が使用しているオペレーター パッケージの最新バージョンを追加しました。この場合は、apache-airflow-backport-providers-google です。オペレーターを特定のバージョンに固定することで、自分の環境にインストールされているバージョンが常に明確になります。

requirements-composer.txt

  apache-airflow-backport-providers-google==2020.11.23

Dockerfile の作成

単体テストを実行するには、コンテナ イメージを Cloud Build で実行できるように Dockerfile を作成します。この Dockerfile は、すべての関連する依存関係をインストールし、テストコマンドを実行します。

  FROM python:3.8

# Allow statements and log messages to immediately appear in the Cloud Run logs
ENV PYTHONUNBUFFERED True

COPY requirements.txt ./
COPY requirements-composer.txt ./
COPY requirements-test.txt ./

RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir -r requirements-test.txt
RUN pip install --no-cache-dir -r requirements-composer.txt

#copy dag code to container image
ENV DAGS /dags
WORKDIR $DAGS
COPY . ./
CMD ["pytest", "-s", "dags/example_dag_test.py"]

cloudbuild.yaml ファイルの作成

Cloud Build ジョブを設定するための test-dags.cloudbuild.yaml という名前の YAML ファイルを作成します。このファイルについては、以下の 2 つのステップがあります。

  1. まず、先ほど作成した Dockerfile から Docker イメージを構築します。この Docker イメージにはデフォルトの置換を使用してタグを付けます。タグ cicd と、UUID の役割を果たす commit SHA です。

  2. 次に、コンテナ イメージを実行し、DAG のテストを行います。

  steps:
  # build the docker image
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'gcr.io/${PROJECT_ID}/cicd:${SHORT_SHA}', '.'] # tag docker image with commit sha
    id: 'docker build'
  # run the dag tests
  - name: 'gcr.io/cloud-builders/docker'
    args: ['run', 'gcr.io/${PROJECT_ID}/cicd:${SHORT_SHA}']
    id: 'test-dags'

注: ワークフローの一環としてイメージを Container Registry に保存することもできます。


Cloud Build トリガーを作成する

こちらのガイドに従って、以下の設定の GitHub アプリベースのトリガーを作成します。

  • 名前: test-dags

  • イベント: pull リクエスト

  • ソース - リポジトリ: 自分のリポジトリを選択

  • ソース - ベースブランチ: ^main$(または、お使いのベースブランチの名前)

  • ソース - コメント制御: 不要(どのユーザーもビルドをトリガーする PR を送信可能)

  • ビルド構成 - Cloud Build 構成ファイル: /test-dags.cloudbuild.yaml(お使いのビルドファイルのパス)

ビルドをテストするには、main ブランチに対する pull リクエストを作成します - ご自身のチェックはこちらで確認できます。また、[Details] をクリックして [View more details on Google Cloud Build] を選択すると、ビルドのログが Cloud Console に表示されます。

Cloud Console

作業 2 - Composer 環境の更新

Cloud Build を使用して、DAG の単体テストをあらゆる要件変更に照らして実行できるようになりました。次は、Composer 環境の更新を自動化しましょう。


cloudbuild.yaml ファイルの作成

Cloud Build ジョブを設定するための YAML ファイルを作成し、update-composer.cloudbuild.yaml という名前を指定します。このファイルについては、1 つのステップがあります。gcloud composer environments update コマンドを呼び出し、requirements-composer.txt ファイルを渡して Python の依存関係をインストールするというものです。${_COMPOSER_NAME} と ${_COMPOSER_REGION} はユーザー定義の置換で、これらは次のセクションで定義します。この構成ファイルにはタイムアウトも含まれます。デフォルトの Cloud Build のタイムアウトは短すぎて長時間実行される Composer 環境の更新処理には対応できないため、このタイムアウトにより確実に処理を完了し、その終了ステータスを Cloud Build に戻すことができます。

  steps:
  #update the composer environment
  - name: 'gcr.io/cloud-builders/gcloud'
    args: ['composer', 'environments', 'update', '${_COMPOSER_NAME}', '--update-pypi-packages-from-file', 'requirements-composer.txt', '--location', '${_COMPOSER_REGION}']
    id: 'update-composer-env'
timeout: 3600s #1 hour timeout accommodates the long running Composer upgrade operation

Cloud Build トリガーを作成する

こちらのガイドに従って、以下の設定の GitHub アプリベースのトリガーを作成します。

  • 名前: update-composer-env

  • イベント: ブランチに push する

  • ソース - リポジトリ: 自分のリポジトリを選択

  • ソース - ベースブランチ: ^main$(または、お使いのベースブランチの名前)

  • ソース - 含まれるファイル フィルタ(glob): requirements-composer.txt(このファイルが変更された場合のみビルドを実行する必要がある)

  • ビルド構成 - Cloud Build 構成ファイル: /update-composer.cloudbuild.yaml(お使いのビルドファイルのパス)

詳細設定で 2 つの置換変数を追加します。

  • _COMPOSER_NAME - Composer 環境の名前

  • _COMPOSER_REGION - 環境がある Compute Engine リージョン

ビルドをテストするには、[Triggers] ページで新しく作成したトリガーの横にある [RUN] をクリックして、手動でトリガーします。また、main ブランチに対する pull リクエストを作成し、requirements-composer.txt ファイルを更新することもできます - ご自身の最初のチェックはこちらで確認できます。PR を main に統合すると、ビルドの開始がビルドの履歴に記録されます。

これをさらに自動化するには、bot を利用して依存関係を常に最新の状態にします。

依存関係 bot の設定

依存関係を常に最新の状態にする bot には複数の選択肢がありますが、個人的に好きなのは WhiteSource Renovate bot です。私が必要とする処理に対応しているだけでなく、問題を報告したときの開発者たちの反応が非常によく、また親切である点が気に入っています。

まず、Renovate GitHub App をインストールし、リポジトリに対する適切なアクセス権を設定します。その後、構成ファイル(renovate.json)を GitHub リポジトリに追加する必要があります。Renovate は通常の requirements.txt ファイルで自動的に変更を探しますが、その他の要件ファイルを監視対象とするように設定することもできます。今回は requirements-composer.txt ファイルを監視したいため、pip_requirements filematch オブジェクトにこのファイルを追加します。構成オプションは他にも数多くあります。ここで取り上げているものに加えて、他のオプションも検討してください。ご自身のニーズを満たすものは何か、試してみましょう。

  {
  "extends": [
    "config:base"
  ],
  "baseBranches": ["main"],
  "masterIssue": true,
  "pip_requirements": {
    "fileMatch": ["requirements-composer.txt"]
  }
}

すべてを組み合わせる

requirements-composer.txt のパッケージに更新があった場合、Renovate bot はリポジトリに対して PR を開きます。その PR が master に統合されると(構成で automerge を true に設定している場合は bot によって、そうでない場合は人間の手で)、Cloud Composer 環境を更新する Cloud Build のジョブがトリガーされます。今後は、この自動化のおかげで Airflow オペレーターの更新を見逃すことはなくなるでしょう。

注意点

  • Composer 環境の更新処理がエラーになった場合は、手動で解決する必要があります。また、requirements-composer.txt ファイルを、Composer 環境で使用されている依存関係に合わせて元に戻す必要があります。

  • DAG は Airflow UI を使用して確認する必要もあります。また、2 つの環境設定(開発環境と本番環境)を使用している場合は、開発環境でこの自動化を使用し、本番環境を更新するのはすべてが想定どおりに機能していることを確認してからとすることをおすすめします。

まとめ

このプロセスに従うと、Cloud Build および GitHub の自動化機能を利用して Cloud Composer 環境のオペレーター(およびその他すべての PyPI パッケージ)を自動的に最新の状態にすることができます。

このプロセスの自動化の続きに関心がある方は、Cloud Build のステータスに通知を追加する方法をご覧ください。

- Developer Relations エンジニア Leah Cole