GitHub Actions を使用して Cloud Run にデプロイする
Google Cloud Japan Team
※この投稿は米国時間 2023 年 9 月 29 日に、Google Cloud blog に投稿されたものの抄訳です。
Google Cloud のお客様は、Google Cloud サービスとサードパーティ ソフトウェアを組み合わせて利用しています。本ブログ記事では、Google によりビルドされたワークフロー サンプルから取得したコードを使用して GitHub Actions から Google Cloud Run をデプロイする方法を説明します。今回は、宣言型サービス YAML によって複数の環境に Cloud Run をデプロイする方法に重点を置いています。
Google ワークフロー サンプル リポジトリでは、イメージをビルドし、ビルドパックを使用してソース(または Docker)から Google Cloud Run をデプロイする方法に関するガイダンスを確認できます。本ブログ記事の例では、これらのワークフローのうち 1 つを、複数のプロジェクトにデプロイできるよう設定しながら使用する方法について詳しく取り上げます。本ブログ記事は Cloud Deploy を利用していないユーザー向けです。Cloud Deploy をご利用の場合、使用方法に関するブログ記事 GitHub Actions と Google Cloud Deploy が連携を参照することをおすすめします。
典型的なワークフロー
典型的な GitHub Actions ワークフローでは、以下に示す手順で Cloud Run へのデプロイを行います。
継続的インテグレーション
- アーティファクト ビルドステージ: 言語に特化したツール(maven、gradle、sbt、npm など)を使用して、アプリケーション アーティファクトをビルドします。
- パッケージ化&コンテナ化ステージ: 対象となるアプリケーション アーティファクトに関する必須コンポーネントや依存関係をすべて収集し、コンテナ化後にそのイメージを既存の Artifact Registry(Docker、Buildpack)に push します。
継続的デプロイ
- リリース承認: 新規コンテナ アーティファクトを移行先となる既存の環境にリリースすることをリクエストし、承認を得ます。リリース プロセスの管理には、GitHub 環境とあわせて再利用可能なデプロイ ワークフローを使用してください。リリース管理では、サードパーティ ツールも使用可能です。Google Cloud Deploy はリリースをシームレスに処理します。ですが Google は、お客様によっては、前述したようなデプロイで異なるツールを使用したい場合があることにも気づきました。
- デプロイ ステージ: リリースから移行先の環境に、新しいコードをデプロイします。
- ロールアウト ステージ: 一連の Cloud Run 移行先環境に対して、段階的ロールアウトまたはカナリア デプロイを進めます。
前提条件
- プールを使用して Workload Identity 連携を設定し、GitHub シークレットとして保存されたサービス アカウントに接続します。Google Cloud への認証を行うには Workload Identity 連携プールと接続済みサービス アカウントが必要です。設定の詳細については、こちらのブログ記事を参照してください。
- サービス アカウントには、イメージを push し、Cloud Run サービス アカウントの権限を借用して Cloud Run をデプロイできるロールが必要とされます。以下のロールが必要です。
- roles/artifactregistry.writer
- roles/iam.serviceAccountUser
- roles/run.admin
- roles/iam.workloadIdentityUser
GitHub Actions ワークフロー
環境ベースデプロイの呼び出し元ワークフロー
以下のワークフローはベース ワークフローを再利用する呼び出し元ワークフローとなるよう設計されており、環境ごとにさまざまな変数を有効にします。このワークフローは、Google Cloud プロジェクト間で分割された複数の環境に対してデプロイする際にも使用できます。
このワークフローはコンテナ イメージをビルドし、Artifact Registry に push したうえで Cloud Run にデプロイします。ワークフローはリポジトリへの push によりトリガーされ、別個の Google Cloud プロジェクトに存在する「develop」、「stage」、「main」環境に対するデプロイを行います。利用可能なトリガーには、他にスケジュール設定や手動トリガーなどがあります。また、環境を使用する変数を定義することもできます。
ワークフローの内容について、以下に詳しく説明します。
- 「develop」、「stage」、または「main」への push を起点として、ワークフローがトリガーされます。
- Dockerfile を使用してコンテナ イメージをビルドします。
- コンテナ イメージを Artifact Registry に push します。
- 該当する Google Cloud プロジェクト内の Cloud Run にコンテナ イメージをデプロイします。
省略可能な手順:
- pull リクエストに対して、コードスキャンとコードの単体テストを実施します。
- 環境を使用する変数を定義します。
- スケジュール設定または手動によるトリガーを適用します。
呼び出し元ワークフローは、複数の環境に対するデプロイで役立ちます。その際、ユーザーは同じベース ワークフローをデプロイに使用する各環境に対して、さまざまな属性を定義できます。下記の呼び出し元ワークフローは、「uses」ブロック内で参照されるワークフローを呼び出します。
再利用可能なワークフロー
再利用可能なワークフローは、呼び出し元ワークフローに対する入力を定義します。これにより、ユーザーは再利用可能なワークフローに変数を渡せるようになります。「workflow_call」属性を使用すると、他のワークフローからこのワークフローを呼び出せるようになります。
また、このワークフローでは、環境ベースの Secret や変数も呼び出しています。この例で定義されている変数は以下のとおりです。
継続的インテグレーション
アーティファクト ビルドステージとパッケージ化ステージ
以下のワークフローは、Google Cloud に対する認証を行い、アーティファクト ビルドステージとパッケージ化ステージの前にイメージを Artifact Registry へ push する方法を示しています。
本ワークフローのステップ 1 では、「checkout」、「auth」アクションを使用します。これらの手順により、リポジトリをチェックアウトして Google Cloud に対する認証を行えます。ゼロトラストの原則に準拠するために Open Authorization(OAuth)を活用する際には、Workload Identity 連携を使用します。
前のステップで生成した OAuth トークンを使用して Docker に対する認証を行います。
Docker ビルドの場合、Dockerfile によりアーティファクトがビルドされ、その後にそのアーティファクトがイメージにパッケージ化されます。Google Cloud Platform の Java コードサンプルでは、Java アプリケーションをコンテナ イメージにパッケージ化する Dockerfile サンプルを参照できます。
以下のワークフロー ステップでは、コンテナ イメージをビルドしてから GitHub 参照の commit ハッシュにタグ付けしています。このタグ付けは、最新のイメージを追跡しながら、commit の履歴とイメージの整合性を保つために行います。本ステップの「context」属性が、現在の作業ディレクトリに関連するソースコードを探し出すためのアクションを示している点に注意してください。Docker イメージのビルドと push を行うアクションの詳細については、こちらのリポジトリを参照してください。
継続的デプロイ
リリース承認ステージ
あらゆるアプリケーション デプロイにおいて、本番環境へのデプロイ権限を付与する対象とデプロイ時期を管理することは一般的です。チェンジ マネジメントの処理が可能なツールは、数多く存在します。GitHub 環境での管理方法について説明しましょう。以下の例では、Cloud Run デプロイに対して 3 種類の環境を定義しています。
数多くのブランチ保護ルールが存在しており、各環境に対してデプロイ基準を適用するために使用できます。ブランチ保護ルールの統合は、リリースを管理して本番環境に対する不用意なデプロイを防止するために役立ちます。以下の例では、デプロイ前に承認を求めるルールを定義しています。
デプロイ ステージ
承認の次は、Cloud Run へデプロイするステージです。本ステップでは環境変数をエクスポートします。これにより、ワークフロー内で変数をローカルで定義できます。「envsubst」コマンドを使用すると、サービス テンプレート YAML ファイル内の値をトークン化して置換できます。サービス テンプレート YAML のサンプルについては、Google ワークフロー サンプル リポジトリで確認できます。サービス YAML の全属性一覧については、Google Cloud Run YAML リファレンスを参照してください。
次のステップでは、Google Cloud Run GitHub Action を使用して Cloud Run デプロイを実施します。ファイル名のトークン化により、開発者は下位の環境ではトラフィックが分割されないようにしながら、本番環境でのみ分割されるようにできます。
段階的ロールアウト ステージ
段階的ロールアウトを活用すると、新しいリリースを移行先の環境に対して部分的にデプロイできます。このような部分的デプロイでは、サービス YAML ファイル内でトラフィックを分割します。トラフィックはコンソールから変更することもできます。トラフィック管理の詳細は、Google Cloud におけるロールバック、段階的ロールアウト、トラフィックの移行に関するドキュメントを参照してください。
これで、GitHub Actions を使用した Cloud Run インスタンスのデプロイが完了しました。Cloud Run GitHub Action についてはこちらのドキュメントから、その他の GitHub Actions サンプルについてはこちらからご覧いただけます。今すぐ、このデプロイをテストしてみましょう。
- Google Cloud、クラウド インフラストラクチャ エンジニア、Andrew Chasin
- サイト信頼性エンジニア、Rawan Badawi