この記事は ミクシィグループ Advent Calendar 2019 の8日目の記事です。
初めましての方は初めまして、19新卒エンジニアの @Taillook です。
Qiitaで書くのは久しぶりです。
最近、仕事上でGoogle CloudのCloud Buildを初めて使う機会があったので書いてみます。
Cloud Buildとは
Cloud Build は、Google Cloud Platform のインフラストラクチャでビルドを行うサービスです。
Cloud Build は、さまざまなリポジトリやクラウド ストレージ スペースからソースコードをインポートし、仕様に合わせてビルドを実行し、Docker コンテナや Java アーカイブなどのアーティファクトを生成できます。
引用: Cloud Build の概要
やること
ここではCloud BuildでCloud SQLにCloud SQL Proxyで接続しマイグレーションしデプロイするstepを示し解説します。
step.yaml
steps:
# Test steps
- id: 'Test: Build Image: API'
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'asia.gcr.io/$PROJECT_ID/${_PRODUCT_NAME_API}-${_TEST_ENV}:$COMMIT_SHA', '-f', '${_TEST_DOCKER_FILE_API}', '.']
- id: 'Test: API'
name: 'gcr.io/cloud-builders/docker'
args: ['run', '--rm', 'asia.gcr.io/$PROJECT_ID/${_PRODUCT_NAME_API}-${_TEST_ENV}:$COMMIT_SHA', 'make', 'test']
# Migrate step
- id: 'Build Image: Migrator'
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'asia.gcr.io/$PROJECT_ID/${_PRODUCT_NAME_MIGRATE}:$COMMIT_SHA', '-f', '${_DOCKER_FILE_MIGRATE}', '.']
- id: 'Run: cloudsql-proxy'
name: 'gcr.io/cloudsql-docker/gce-proxy:1.15'
args: ['/cloud_sql_proxy', '-dir=/cloudsql', '-instances=$_CLOUD_SQL_CONNECTION_NAME']
volumes:
- name: cloudsql
path: /cloudsql
waitFor:
- 'Test: API'
- id: 'Migrate: Database'
name: 'gcr.io/cloud-builders/docker'
args: ['run','--rm', '-v', 'cloudsql:/cloudsql', '-e', 'ENV=${_DEPLOY_ENV}', '-e', 'DB_SOCKET=${_DB_SOCKET}', '-e', 'DB_USER=${_DB_USER}', '-e', 'DB_PASSWORD=${_DB_PASSWORD}', 'asia.gcr.io/$PROJECT_ID/${_PRODUCT_NAME_MIGRATE}:$COMMIT_SHA', 'make', 'db_migrate_execute']
volumes:
- name: cloudsql
path: /cloudsql
waitFor:
- 'Build Image: Migrator'
- id: 'Kill: cloudsql-proxy'
name: 'gcr.io/cloud-builders/docker'
waitFor:
- 'Migrate: Database'
entrypoint: 'sh'
args: ['-c', 'docker ps -q --filter ancestor="gcr.io/cloudsql-docker/gce-proxy:1.15"|xargs docker stop']
# Deploy steps
- id: 'Build Image: API'
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'asia.gcr.io/$PROJECT_ID/${_PRODUCT_NAME_API}-${_DEPLOY_ENV}:$COMMIT_SHA', '-f', '${_DOCKER_FILE_API}', '.']
- id: 'Push Image: API'
name: 'gcr.io/cloud-builders/docker'
args: ['push', 'asia.gcr.io/$PROJECT_ID/${_PRODUCT_NAME_API}-${_DEPLOY_ENV}:$COMMIT_SHA']
- id: 'Deploy: API'
name: 'gcr.io/cloud-builders/gcloud'
args: [
'beta', 'run', 'deploy', '${_PRODUCT_NAME_API}-${_DEPLOY_ENV}',
'--platform', 'managed',
'--allow-unauthenticated',
'--project', '$PROJECT_ID',
'--region', '${_REGION}',
'--image', 'asia.gcr.io/$PROJECT_ID/${_PRODUCT_NAME_API}-${_DEPLOY_ENV}:$COMMIT_SHA',
'--set-env-vars', 'ENV=${_DEPLOY_ENV},DB_USER=${_DB_USER},DB_SOCKET=${_DB_SOCKET},DB_NAME=${_DB_NAME},DB_PASSWORD=${_DB_PASSWORD}'
]
timeout: 1000s
解説
stepは大きく3つに分かれ、test、migrate、deployとなります。
ここではmigrateについて解説します。
migrateの流れ
- Migratorのビルド
- cloudsql-proxyを
Test: API
の終了をトリガーに実行 -
Build Image: Migrator
の終了をトリガーにマイグレーションを実行 -
Migrate: Database
の終了をトリガーにcloudsql-proxyを終了
waitForについて
ビルドステップの順序の構成にある様にビルドステップのwaitForフィールドを使用してステップの順序を指定することができます。また、waitForを指定しない場合は先行するステップが終了するまで待機し実行されます。
ちなみに3でBuild Image: Migrator
の終了をトリガーにする理由はcloudsql-proxyと並列に実行されないとCloud SQLとの接続が出来ないためです。
volumesについて
volumesではCloud SQL ProxyのソケットをMigratorに対して共有するための記述です。
これによりMigratorはCloud SQLへの接続を可能にしています。
所感
おそらくdocker composeでやればよくないか?との指摘があるかと思います。今回はCloud Buildの機能を活用したい+docker-composeのyamlを書かなくてよいのでdocker composeを用いずに行いました。
また、cloudsql-proxyを終了をする処理はfilterを用いずにできた気がするのでやり直したいといった思いです。