はじめに
bocci bocciを運営している@shoji-kaiです。
前回の記事ではCloud Runを使って無料でリダイレクトサーバを立ち上げる記事を書きましたが、すべてgcloudコマンドを使って手動で実行していました。
私は、いちおうDevOpsエンジニアでありますので、ここはしっかりとCI/CD環境を用意して自動化したいところです。
そこで今回は、CircleCI + Cloud Buildを使用してCloud Runへのデプロイを自動化してみたいと思います。
APIの有効化
最初にCloud Build APIを有効にしておきます。
その他、足りないAPIがあれば適宜有効にしてください。
gcloud services enable cloudbuild.googleapis.com
Cloud Buildのハマリポイント
実際にCloud Buildを動かす前にハマリポイントを解消しておきます。
私が最初に手動でClould Buildを実行した際に以下のようなエラーが発生しました。
Step #2: ERROR: (gcloud.run.deploy) PERMISSION_DENIED: Permission 'run.services.get' denied on resource ...
Owner権限で実行しているにも関わらず"PERMISSION_DENIED"とは何ぞや?と思い調べてみたところ、Cloud Buildするには以下の設定が必要なようです。
というわけで、Cloud BuildサービスアカウントにCloud Run管理者ロールとサービスアカウントユーザーロールを割り当てます。
上記URLにあるようにGCPコンソールでやってもいいのですが、ここではgcloudコマンドを使ってやってみます。
roles=(run.admin iam.serviceAccountUser)
for role in $roles; do
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member serviceAccount:<PROJECT_NUMBER>@cloudbuild.gserviceaccount.com \
--role roles/$role
done
これでCloud Build時のPERMISSION DENIEDエラーが解消されました。
毎度のことながら、ドキュメントはきちんと読みましょうということですね。
手動でCloud Buildしてみる
前回は自分のMacBook AirでDockerイメージをビルドしていましたが、今回はCloud Buildを使用してビルドします。
まずは試しに手動で実行してみます。
Cloud Buildでビルドするには、cloudbuild.yamlと呼ばれるビルド構成ファイルを用意します。
steps:
# ビルド
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', '<REGISTRY_NAME>/<PROJECT_ID>/<REPOSITORY_NAME>/<CONTAINER_NAME>', '.']
# プッシュ
- name: 'gcr.io/cloud-builders/docker'
args: ['push', '<REGISTRY_NAME>/<PROJECT_ID>/<REPOSITORY_NAME>/<CONTAINER_NAME>']
# デプロイ
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args: ['run', 'deploy', '<SERVICE_NAME>', '--image', '<REGISTRY_NAME>/<PROJECT_ID>/<REPOSITORY_NAME>/<CONTAINER_NAME>', '--region', '<REGION>', '--allow-unauthenticated']
# Artifact Registryに保存。プッシュとの違いは下記URLを参照
# ref. https://cloud.google.com/build/docs/building/build-containers?hl=ja#store-images
images: ['<REGISTRY_NAME>/<PROJECT_ID>/<REPOSITORY_NAME>/<CONTAINER_NAME>']
# ロギング設定
# ref. https://cloud.google.com/build/docs/api/reference/rest/v1/projects.builds#loggingmode
options:
logging: CLOUD_LOGGING_ONLY
Artifact RegistryにDockerリポジトリをまだ作っていない場合は先に作成します。
gcloud artifacts repositories create <REPOSITORY_NAME> --location=<REGION> --repository-format=Docker
Cloud Buildでビルドします。
% cd <path/to/docker>
% ls -1
Dockerfile
cloudbuild.yaml
default.conf
nginx.conf
% gcloud builds submit .
正常に終了すると以下のようなメッセージが表示されます。
% gcloud builds submit .
:
(snip)
:
DONE
--------------------------------------- ...
ID ... STATUS
7cd4a829-f1a0-4c36-b7e8-93bf64eb3ef4 ... SUCCESS
CircleCIでビルド〜デプロイまでを自動化する
Cloud Buildの使い方が分かったところで、次にCircleCIで自動化していきます。
CircleCI自体のセットアップや詳細な使い方などについては割愛しますので、他のドキュメントをご参照ください。
ここでは、当該GitHubリポジトリとCircleCIプロジェクトとの連携が済んでいる前提で話しを進めます。
サービスアカウントの作成
まずはCircleCI用のサービスアカウントを用意します。
gcloud iam service-accounts create circleci --display-name circleci
次にサービスアカウトにビルド〜デプロイで必要なロールを付与します。
roles=(cloudbuild.builds.editor storage.admin artifactregistry.admin)
for role in $roles; do
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member serviceAccount:circleci@<PROJECT_ID>.iam.gserviceaccount.com \
--role roles/$role
done
最後にサービスアカウントのキーファイル(JSON)を作成しておきます。後でCircleCIに登録します。
gcloud iam service-accounts keys create circleci-key.json \
--iam-account circleci@<PROJECT_ID>.iam.gserviceaccount.com
CircleCIの設定
今回はcircleci/gcp-cloud-runというCircleCI Orbsを利用してCloud Runへデプロイします。
circleci/gcp-cloud-runの細かな設定などについてはドキュメントをご参照ください。
まずはCircleCIプロジェクトに以下の環境変数を登録します。
- GOOGLE_PROJECT_ID # プロジェクトID
- GOOGLE_COMPUTE_ZONE # ゾーン e.g. us-central1-c, etc
- GCLOUD_SERVICE_KEY # 先に作成した circleci-key.json の中身
- REGION # リージョン e.g. us-central1, etc
- REPOSITORY # Aritfact RegistoryのDockerリポジトリ名
.circleci/config.ymlは以下のようにします。
version: 2.1
orbs:
cloudrun: circleci/gcp-cloud-run@1.0.2
jobs:
build_and_deploy:
docker:
- image: 'cimg/base:stable'
steps:
- checkout
- cloudrun/init
- run:
name: Create a docker repository if not exists.
shell: /bin/bash
command: |
gcloud artifacts repositories create $REPOSITORY \
--location=$REGION \
--repository-format=Docker 2>/dev/null || echo 'already exists'
- cloudrun/build:
config: docker/nginx/cloudbuild.yaml
source: docker/nginx/
workflows:
build-and-deploy:
jobs:
- build_and_deploy
CircleCIの実行
GitHubにコードをプッシュしてCircleCIを走らせます。
git add .
git commit -m '<コミットメッセージ>'
git push
CircleCIの画面から正常にデプロイされたことを確認できれば成功です。
おわりに
CircleCIもCloud Buildも個人で使うには十分な無料枠がありますので、これまた無料で運用できます。
自動化の設定は初回はやや手間がかかりますが、そこさえクリアすれば後は楽できますし、手作業がなくなるのでオペミスも減らせます。
エンジニアたるもの、やはりDRYに行きたいところです。
それでは、こちらの記事がどなたかの参考になれば幸いです。