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

株式会社ジラフ
6 min readNov 1, 2019

--

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 に繋げなかったり色々不便な箇所が目立ちます。今後の改善が期待されますね。

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

--

--