実は難しい、 Cloud Build から Cloud SQL への接続

株式会社ジラフ
Nov 1 · 6 min read
Photo by eberhard grossgasteiger on Unsplash

エンジニアの桂です。

今日は Cloud Build から Cloud SQL に接続する方法について紹介していきます。

どちらも Google Cloud Platform 上のサービスなので一見簡単にできそうですが、 Cloud Build というサービスは予想外に不器用で、こういう作業はかなり苦手だったりします。

今回は Cloud SQL Proxy を立てながら並列的にSQL 接続を行う手法を使います。この手法は @kshibata101 氏の Cloud BuildでCloud SQLのマイグレーションをしたい をベースにしていますが、最近 Cloud SQL Proxy のイメージから sh が削除されたため、この手法は使えません。

docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown.
time="2019-11-01T07:13:46Z" level=error msg="error waiting for container: context canceled"

そこで、この GitHub Issue 内で ffjeremy 氏が提案している方法に近いものを紹介します。

Cloud Build 設定

Cloud SQL Proxy を起動して UNIX ソケットを介して Cloud SQL に接続すると言う流れですが、 Cloud SQL Proxy は SQL 実行の際にバックグラウンドで実行する必要があるので、工夫が必要です。

並列で実行するだけであれば、waitFor オプションを使って簡単に実現できますが、それだけだと Cloud SQL Proxy は永遠に終わらないので、用が終わってから docker kill を使って Cloud SQL Proxy のコンテナを終了させます。

これらを踏まえて、以下の cloudbuild.yaml を用意しました。『SQL 実行』と substitutions をタスクに合わせて変更して利用します。(_DB_USER_DB_PASS はコマンドラインから渡します。)

steps:
- id: Cloud SQL Proxy 起動
name: gcr.io/cloudsql-docker/gce-proxy
args:
- /cloud_sql_proxy
- -dir=/cloudsql
- -instances=${_INSTANCE_CONNECTION_NAME}
volumes:
- name: cloudsql
path: /cloudsql
- id: Cloud SQL Proxy 起動待機
name: mysql:5.7.28 # 『SQL 実行』で使うイメージをここで pull しておくとお得
entrypoint: bash
args:
- -c
- |
while [ ! -e "/cloudsql/${_INSTANCE_CONNECTION_NAME}" ]; do
sleep 1
done
volumes:
- name: cloudsql
path: /cloudsql
waitFor: ['-']
- id: SQL 実行
name: mysql:5.7.28
entrypoint: bash
args:
- -c
- |
# ここを目的に合わせて変更します
mysql -u"${_DB_USER}" -p"${_DB_PASS}" -S"/cloudsql/${_INSTANCE_CONNECTION_NAME}" -D"${_DB_NAME}" \
-e 'SHOW TABLES'
volumes:
- name: cloudsql
path: /cloudsql
waitFor: ['Cloud SQL Proxy 起動待機']
- id: Cloud SQL Proxy 終了
name: gcr.io/cloud-builders/docker
entrypoint: bash
args:
- -c
- docker kill -s TERM $$(docker ps -q --filter ancestor=gcr.io/cloudsql-docker/gce-proxy)
waitFor: ['SQL 実行']
substitutions:
_DB_NAME: <DB 名を指定>
_INSTANCE_CONNECTION_NAME: <Cloud SQL のインスタンス接続名を指定>

Cloud Build 実行の準備

Cloud SQL Proxy を使うために、まずこちらから Cloud SQL Admin API を有効にします。

また、 Cloud Build から Cloud SQL にアクセスするために、 サービスアカウントにroles/cloudsql.client を付与します。

$ PROJECT_NAME=$(gcloud projects list --filter="$(gcloud config get-value project)" --format="value(NAME)")
$ PROJECT_NUMBER=$(gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_NUMBER)")
$ gcloud projects add-iam-policy-binding ${PROJECT_NAME} --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com --role=roles/cloudsql.client

Cloud Build の実行

前述の通り、 _DB_USER_DB_PASS を渡して実行します。

$ gcloud builds submit --config=cloudbuild.yaml --substitutions=_DB_USER=<DB ユーザ名>,_DB_PASS=<DB パスワード>

終わりに

Cloud Build は便利ではありますが、 VPC に繋げなかったり色々不便な箇所が目立ちます。今後の改善が期待されますね。

さて、最後に、ジラフでは仲間を絶賛募集中ですので、興味がある方は是非ともご連絡ください。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade