GitLab CI / CD と Cloud Deploy を使用した Google Cloud での継続的デリバリー
Giovanni Galloro
Customer Engineer
※この投稿は米国時間 2024 年 8 月 6 日に、Google Cloud blog に投稿されたものの抄訳です。
継続的デリバリー(CD)とは、パイプラインを使用してソフトウェア リリース プロセス全体を自動化することにより、ソフトウェアを迅速に、高い信頼性で提供するための実践と原則です。この記事では、最近リリースされた GitLab と Google Cloud のインテグレーションを活用し、Cloud Run でコードの commit から本番環境のリリースまでのソフトウェア デリバリーを自動化する継続的デリバリー パイプラインを、GitLab CI / CD と Cloud Deploy を使用して作成する方法について説明します。
ソリューションの要素
GitLab CI / CD
GitLab CI / CD は、GitLab 内に統合された継続的インテグレーションと継続的デリバリーのプラットフォームです。コード変更のビルド、テスト、デプロイを自動化し、開発ワークフローを効率化します。詳細については、GitLab CI / CD に関するドキュメントをご覧ください。
Cloud Deploy
Cloud Deploy は、異なるステージにわたって、アプリケーションを一連のランタイム環境にデプロイする方法を自動化できる Google マネージド サービスです。Cloud Deploy を使用すると、コンテナ イメージを所定のシーケンスで GKE ターゲットおよび Cloud Run ターゲットにデプロイするデリバリー パイプラインを定義できます。Cloud Deploy は、段階的リリース、承認、デプロイ検証、並列デプロイなど、高度なデプロイ戦略をサポートします。
Google Cloud と GitLab のインテグレーション
GitLab と Google Cloud は最近、GitLab のコードをより簡単かつ安全に Google Cloud にデプロイ可能なインテグレーションをリリースしました。以下は、この記事で説明するインテグレーション領域です。
-
認証: GitLab と Google Cloud のインテグレーションは、Workload Identity 連携を利用して、CI / CD ジョブである GitLab ワークロードを安全に Google Cloud で認可および認証します。これにより、サービス アカウントやサービス アカウント キーの管理が不要になり、プロセスが効率化され、セキュリティ リスクが軽減します。以下で説明する他のインテグレーション領域はすべて、この認証メカニズムを利用します。
-
Artifact Registry: このインテグレーションを使用すると、GitLab アーティファクトを Artifact Registry にアップロードして、GitLab UI からアクセスできます。
-
Cloud Deploy: この GitLab コンポーネントを使用すると、GitLab CI / CD パイプラインから Cloud Deploy リリースを簡単に作成できます。
-
Gcloud: このコンポーネントを使用すると、GitLab CI / CD パイプラインで gcloud コマンドを簡単に実行できます。
-
Google Cloud 上の GitLab ランナー: このインテグレーションを使用すると、GitLab UI からランナー設定を構成し、Terraform で Google Cloud プロジェクトにデプロイできます。
最新の Google Cloud GitLab コンポーネントのリストは、こちらから入手できます。
必要なもの
この記事の手順に沿うために以下のものが必要です。
-
GitLab アカウント(Free、Premium、Ultimate)
-
プロジェクト オーナー アクセス権のある Google Cloud プロジェクト
-
https://gitlab.com/galloro/cd-on-gcp-gl にある、サンプルコードを含む GitLab リポジトリを、ローカルのワークステーションにクローンした独自アカウントのフォーク
パイプライン フロー
パイプラインは、リポジトリのルートにある .gitlab-ci.yml ファイルで、または GitLab Pipeline エディタを使用して確認できます。
この記事の指示に沿って、以下の手順で、エンドツーエンドのソフトウェア デリバリー パイプラインを作成して実行します。
-
開発者がアプリケーション リポジトリから機能ブランチを作成します。
-
開発者は、コードに変更を加えた後に、更新したコードをメインブランチにマージするマージ リクエストを作成します。
-
GitLab パイプラインは、いずれもマージ リクエストが次のルールを通じて作成された場合に実行するように構成された、以下の各ジョブを実行します。
- if: $CI_PIPELINE_SOURCE == 'merge_request_event
':
a. image-build
ジョブは、build ステージにおいて、コンテナ イメージが更新されたコードでビルドします。
b. upload-artifact-registry
コンポーネントは、push
ステージにおいて、他のすべての後続コンポーネントと同じように事前構成した Google Cloud IAM とのインテグレーションを活用して、イメージを Artifact Registry に push します。このジョブの構成は、ジョブ実行のルールを設定するために、コンポーネントと明示的なジョブ定義に分割されており、以下で説明する他のコンポーネントにおいても同様です。
c. create-cloud-deploy-release
コンポーネントは、deploy-to-qa
ステージにおいて、Cloud Deploy にリリースを作成し、また QA ステージへのロールアウトを作成して、QA チームがユーザー受け入れテストを行う cdongcp-app-qa
Cloud Run サービスにマッピングします。
4. テスト完了後に、QA チームが MR をマージすると、run-gcloud
コンポーネントが promote-to-prod
ステージにおいて実行され、これにより、リリースが本番環境ステージにプロモートされ、cdongcp-app-prod
Cloud Run サービスにマッピングされます。この場合、ジョブは、次のルールを通じてメインブランチへの push において実行するように構成されます。
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
:
5. Cloud Deploy の本番環境のターゲットは承認が必要なため、承認リクエストがトリガーされ、アプリケーションのプロダクト マネージャーがロールアウトをチェックして承認すると、アプリがカナリア リリースで本番環境にリリースされます。これにより、cdongcp-app-prod
Cloud Run サービスの新しいリビジョンが作成されて、トラフィックの 50% が送信されます。本番環境のデプロイに必要なカナリア戦略と承認が含まれる、Cloud Deploy のデリバリー パイプラインとターゲットの構成を以下に示します(リポジトリの cr-delivery-pipeline.yaml ファイル)。トラフィック分割の可視性を高めるためにカナリア戦略を 50% に構成していますが、実際の本番環境ではより小さな値になります。
6. アプリリリース チームが、カナリア リリースをチェックした後に、ロールアウトを 100% に進行させます。
上記のすべてのロール(開発者、QA チームのメンバー、アプリリリース チームのメンバー、プロダクト マネージャー)を、単一の GitLab アカウントとプロジェクト / リポジトリで担うことができます。実際のシナリオでは、複数のアカウントが使用されます。
下図はパイプライン フローを示しています。
上記のジョブとステージに加え、.gitlab-ci.yml パイプラインには、first-release
ステージにおける、他の類似のジョブのインスタンスが含まれており、GitLab ウェブ UI の [Run pipeline] ボタンでパイプラインを手動実行する場合にのみ実行するように、ルールを通じて構成されます。上記のフローを実行する前に最初のリリースを手動で作成するためにこれを行います。
環境を準備する
パイプラインを実行する環境を準備するために、以下のタスクを行います。
-
目的のリージョンで Google Cloud プロジェクトに、Docker イメージ用の Artifact Registry 標準リポジトリを作成します。
-
ローカル リポジトリ クローンの setup フォルダにある
setup.sh
を実行し、プロンプトに沿って Google Cloud プロジェクト、Cloud Run と Cloud Deploy のリージョン、Artifact Registry リポジトリを挿入します。.gitlab-ci.yml
ファイルとsetup/cr-delivery-pipeline.yaml
ファイルに加えた変更を commit し、フォークに push します。 - setup フォルダが開いていることを確認して、用意されているマニフェストを使用し、Cloud Deploy デリバリー パイプラインを作成します(
yourregion
とyourproject
を実際の値に置き換えます)。
これにより、qa と prod の 2 つのステージを持つパイプラインが作成されます。いずれのステージも同一の名前のプロファイルを使用し、2 つのターゲットは 2 つの Cloud Run サービスをパイプライン ステージにマッピングします。
4. GitLab ドキュメントに沿って、Google Cloud の Workload Identity 連携と、Google Cloud サービスで GitLab の認証に使用される Workload Identity プールを設定します。
5. GitLab ドキュメントに沿って、Google Artifact Registry のインテグレーションを設定します。その後、GitLab UI から、サイドバーの [Deploy] にある [Google Artifact Registry] エントリを通じて、Google AR リポジトリにアクセスできます。
6. (任意)GitLab ドキュメントに沿って、Google Cloud にランナーを設定します。Gitlab.com を使用している場合、GitLab がホストするランナーを使用するデフォルト構成も維持できますが、Google Cloud のランナーでは、マシンタイプや自動スケーリングのようなパラメータをカスタマイズできます。
7. 各コンポーネントの関連する README に記載されているとおり、GitLab の Google Cloud コンポーネントの権限を設定します。このパイプラインのジョブを実行するには、GitLab の Workload Identity プールに以下の Google Cloud IAM のロールが最低限必要です。
-
roles/artifactregistry.reader
-
roles/artifactregistry.writer
-
roles/clouddeploy.approver
-
roles/clouddeploy.releaser
-
roles/iam.serviceAccountUser
-
roles/run.admin
-
roles/storage.admin
8. GitLab ウェブ UI から [Build] -> [Pipelines] -> [Run pipeline] でパイプラインを手動で実行し、最初のリリースと、QA および本番環境の 2 つの Cloud Run サービスを作成します。これにより、first-release
ステージに含まれるすべてのジョブが実行されます。パイプラインの実行が完了するまで待機し、その後に次のステップに進みます。
9. Google Cloud コンソールから、cdongcp-app-qa と cdongcp-app-prod の Cloud Run サービスの URL を取得してウェブブラウザで開き、アプリケーションがデプロイされていることを確認します。
パイプラインを実行する
開発者の立場でコードを更新する
- リポジトリ クローンのルートに移動し、リポジトリの新しいブランチを「new feature」という名前で作成して、チェックアウトします。
2. コードを更新する: cdongcp-app フォルダの app.go ファイルを開いて、25 行目のメッセージを “cd-on-gcp app UPDATED in target: …” に変更します。
3. 変更を commit して new-feature ブランチに push します。
4. コードをマージするためにマージ リクエストを作成する: ターミナル出力の URL をコピーしてブラウザに貼り付けることが可能です。また、GitLab ページで [Create merge request] ボタンをクリックすると、パイプラインが開始します。
アーティファクトの自動ビルドを実行する
1. GitLab で [Build] > [Pipelines] を確認し、最後のパイプラインの実行 ID をクリックします。3 つのステージが表示され、各ステージにジョブが 1 つ含まれています。
2. パイプラインが完了するまで待機します。各ジョブをクリックすると、実行ログが表示されます。最後のジョブは、cdongcp-$COMMIT_SHA リリース($COMMIT_SHA は commit の短縮 SHA)を作成し、QA ステージにロールアウトします。
3. ブラウザで cdongcp-app-qa URL を開くか更新すると、更新されたアプリケーションが QA ステージにデプロイされているのを確認できます。
4. 実際のシナリオでは、QA チームがこの環境でユーザビリティ テストを行います。テストが正常に完了し、今度は QA チームのメンバーの立場で、変更されたコードをメインブランチにマージすると想定します。GitLab のマージ リクエスト ページに移動し、[Merge] をクリックします。
リリースを承認し、本番環境にロールアウトする
1. run-gcloud
コンポーネントのジョブを 1 つだけ含む新しいパイプラインが実行されます。実行は GitLab パイプライン リストに表示されます。
2. パイプラインが完了すると、リリースは prod ステージにプロモートされて承認待ちとなり、コンソールの Cloud Deploy ページに表示されます。
3. 本番環境のデプロイを承認する必要のある、アプリケーションのプロダクト マネージャーの立場で、[Review] をクリックすると、承認が必要なロールアウトが表示されます。もう一度 [REVIEW] をクリックします。
4. 「Approve rollout to prod」ページで [APPROVE] ボタンをクリックして、prod ステージへのプロモーションを最終的に承認します。prod ステージのカナリア フェーズへのロールアウトが開始され、しばらくするとロールアウトはカナリア フェーズで安定します。
5. このフェーズでトラフィックがどのように管理されるかを観察する: 以下のコマンド(cdongcp-app-prod-url
を実際のサービス URL に置き換えます)で、cdongcp-app-prod URL サービスへのリクエストを生成します。
6. しばらくすると、以前のリリースと新しい(カナリア)リリースの両方のレスポンスが表示されます。
7. アプリリリース チームがカナリアから指標やその他の観測可能なデータを取得すると想定します。アプリケーションが正しく動作していることを確認したら、他のすべてのユーザーにデプロイします。アプリリリース チームのメンバーの立場で、Cloud Deploy コンソールに移動して、[Advance to stable] をクリックし、次に確認ポップアップの [ADVANCE] をクリックすると、ロールアウトが安定します。進行が安定すると、すべてのリクエストが更新されたバージョンのアプリケーションで処理されていることを curl 出力で確認できます。
まとめ
最近リリースされた Google Cloud と GitLab のインテグレーションを利用して、以下の項目を満たす GitLab CI / CD パイプラインの例を紹介しました。
-
Workload Identity 連携を使用して、GitLab の Google Cloud での認証を構成する
-
GitLab と Artifact Registry を統合する
-
GitLab CI / CD と Cloud Deploy を使用して、マージ リクエストの作成時に自動的にソフトウェアをビルドし、QA Cloud Run サービスにデプロイする
-
マージ リクエストがメインブランチにマージされると、自動的にソフトウェアが本番環境の Cloud Run サービスにプロモートされる
-
Cloud Deploy で承認を使用する
-
Cloud Deploy でカナリア リリースを利用して、アプリケーションを段階的にユーザーにリリースする
この記事、および GitLab CI / CD、Google Cloud と GitLab のインテグレーション、Cloud Deploy、Cloud Run のドキュメントを参照して、GitLab と Google Cloud を活用したエンドツーエンドのパイプラインを構成できるようになりました。
ー カスタマー エンジニア、Giovanni Galloro