astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

Gitlab CIからGoogle Cloud Buildを実行してみた

お久しぶりです。開発部のyanagitaです。
弊社ではGitリポジトリにGitlabを採用していて、CIはプロジェクトによってGitlab CIやJenkins、またその2つを組み合わせて使用しています。
今回は、Google CloudでCIサービスとして提供されているGoogle Cloud BuildをGitlab CIから実行するところまでを紹介します。

お詫び

Google Cloud Buildの実行には事前にサービスを有効にしておいたり、使用するアカウントにGoogle Cloud Buildの実行権限を与える必要がありますが、そのあたりは今回省略します。

Gitlab CIからGoogle Cloud Buildを実行する

以下は、.gitlab-ci.ymlです。下記の例はGoogle Cloud Buildを実行するただけの記述になります。

stages:
  - google_cloud_build

.google_cloud_build_template:
  stage: google_cloud_build
  image: google/cloud-sdk:313.0.0-alpine
  script:
    - echo $GCLOUD_AUTH_CODE | base64 -d > ./gcloud_auth.json
    - gcloud auth activate-service-account --key-file ./gcloud_auth.json
    - rm -f ./gcloud_auth.json
    - gcloud config set project $GCLOUD_PROJECT
    - gcloud builds submit . 

build_staging:
  variables:
    GCLOUD_PROJECT: stg_project
    GCLOUD_AUTH_CODE: $GCLOUD_AUTH_STG
  extends: .google_cloud_build_template
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^(release|hotfix)_/

build_production:
  variables:
    GCLOUD_PROJECT: prd_project
    GCLOUD_AUTH_CODE: $GCLOUD_AUTH_PRD
  extends: .google_cloud_build_template
  rules:
    - if: $CI_COMMIT_TAG =~ /^\d{6}\.\d+-(release|hotfix)$/

流れに沿って解説します。
まずは、一番のキーとなるGoogle Cloud Buildの実行部分です。この部分はテンプレート形式で記述しています。理由についてはjobの解説時に説明します。

.google_cloud_build_template:
  stage: google_cloud_build
  image: google/cloud-sdk:313.0.0-alpine # 解説1
  script:
    - echo $GCLOUD_AUTH_CODE | base64 -d > ./gcloud_auth.json            #
    - gcloud auth activate-service-account --key-file ./gcloud_auth.json # 解説2
    - rm -f ./gcloud_auth.json                                           #
    - gcloud config set project $GCLOUD_PROJECT                          #
    - gcloud builds submit .                                             # 解説3

Google Cloud Buildの実行はgcloudコマンドを使用するためgoogle/cloud-sdkのイメージを使用します。(解説1)
gcloudコマンドの実行には事前に認証とGoogle Cloudのプロジェクトの紐付けを行う必要があります。ローカル等で認証を通す場合はブラウザの起動を挟んだりするのですが、gitlab ci上では行えないため認証情報が記述されたjsonファイルを使って認証を行います。その際、認証に必要なjsonを直接git上で管理するのは社内のGitリポジトリだとしても不安があるため、認証用のJsonの内容をBase64でエンコードした状態で環境変数($GCLOUD_AUTH_CODE)に格納しておき、認証直前でデコードした結果を認証用jsonとして復元する方式を取っています。 上記流れで復元した認証Jsonとプロジェクトの紐付けをgcloudコマンドで行います。(解説2)
記述中で2箇所環境変数を使用しています。理由についてはjobの解説時に説明します。
以下は、base64エンコードのコマンド例

$ base64 -i 認証用のjsonファイル
~~~~ エンコード結果 ~~~~~ # ← この結果を環境変数に実行時に格納しておきます。

最後にGoogle Cloud Buildの実行を行います。例だとcloudbuild.yamlをプロジェクトルートに配置しています。(解説3)

次に、jobの解説です。
弊社に限らずだと思いますが、ステージング環境と本番環境でGoogle Cloudのプロジェクトを分けて運用しているため、Google Cloud Buildを実行する環境ごとにプロジェクトや認証情報が変わってくることになります。
上記の環境差分を解消するため、Google Cloud Buildの実行環境ごとにJobを定義しています。例ではステージング環境向けと本番環境向けのJobを記述しています。

stages:
  - google_cloud_build

build_staging:  # ステージング環境向け
  variables:
    GCLOUD_PROJECT: stg_project
    GCLOUD_AUTH_CODE: $GCLOUD_AUTH_STG
  extends: .google_cloud_build_template  # 解説4
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^(release|hotfix)_/

build_production: # 本番環境向け
  variables:
    GCLOUD_PROJECT: prd_project
    GCLOUD_AUTH_CODE: $GCLOUD_AUTH_PRD
  extends: .google_cloud_build_template # 解説4
  rules:
    - if: $CI_COMMIT_TAG =~ /^\d{6}\.\d+-(release|hotfix)$/

差分以外の定義に関しては、最初に解説したテンプレート形式での記述にすることで各Jobはテンプレートを継承し差分のみの記述で済むようになります。(解説4)
差分となる環境変数はvariablesで定義されています。

  • GCLOUD_PROJECT = Google Cloud Buildを実行するプロジェクト名
  • GCLOUD_AUTH_CODE = base64でエンコードされた認証Json

ここで、GCLOUD_AUTH_CODEは別の環境変数から値を定義する形を取っています。これはテンプレート側で同じ名前の環境変数を使用するために環境変数名の変更を行っています。
GCLOUD_AUTH_CODEに与えた環境変数の内容はProjectの Setting > CI/CD > Variablesで定義していて、内容はbase64でエンコードされた認証用のJson情報になっています。これで認証用のJsonをgit管理することなくGitla CI上の使用することができるようになります。

f:id:astamuse:20210707015648p:plain

以上でGitlab CIからGoogle Cloud Buildを実行する解説は終了です。

最後に

今回Gitlab CIからGoogle Cloud Buildの実行を解説しました。実際、Gitlab CIだけでも十分完結させることは可能です。ただ、うまく組み合わせることでより強力な環境でのビルドやGoogle Cloudの他サービスに柔軟に対応することができるようになります。

それではまたいつの日か

Copyright © astamuse company, ltd. all rights reserved.