GWで世間はお休みモードですが、GCPは一生懸命動いててくれて大変助かります。ありがとう。
GCPのCloud Buildを利用して、普通のVPSなどにデプロイする際、ssh接続がしたくなることがある。こいつをCloud Buildで実現する際には、
- 秘密鍵をKMSで暗号化
- sshのknowns host を設定
- ビルドタスク内で秘密鍵を復号化
- 復号した鍵でssh接続する
以上のようなことが実現できれば良い。
こんなことができるビルドタスクを組んでみたので公開したいと思います。
ちょくちょくCloud Buildを運用で使ってますが、なにぶん手探りなので、
もっとこうしたほうがいい、こうするべきだ的なのありましたらご教授お願いします。
質問/苦情等ありましたらコメントへよろしくお願いします。
事前準備
- あらかじめ、対象のサーバーに接続できるか手元で試す。
- (リモート作業で云々するのにそもそも元から接続できませんでしたってなるとガックリするので)
- 接続に利用した鍵をKMSで暗号化する
- 接続先の情報が入ったknown_hostsを用意する
- tarとsshが入ったイメージを作成してsubmitしておく
APIを有効化
下記のAPIを Google Cloud Platform Console で有効にする。
- Cloud Build API
cloudbuild.yaml
steps:
# ①暗号鍵を復号化する
- id: decryptkey
name: 'gcr.io/cloud-builders/gcloud'
args:
- kms
- decrypt
- --ciphertext-file=id_rsa_some_vps.encrypted
- --plaintext-file=/root/.ssh/id_rsa_some_vps
- --location=global
- --keyring=deploy
- --key=some_vps
volumes:
- name: 'ssh'
path: /root/.ssh
# ②ssh接続用設定
- id: sshconfig
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: bash
args:
- '-c'
- |
# 鍵のパーミッション設定
chmod 600 /root/.ssh/id_rsa_some_vps
# ssh接続用configファイルの生成
cat <<EOF >/root/.ssh/config
Host somevps
HostName xxx.xxx.xxx.xxx
User deployer
IdentityFile /root/.ssh/id_rsa_some_vps
IdentitiesOnly yes
EOF
# known_hostsの設定
mv known_hosts /root/.ssh/known_hosts
volumes:
- name: 'ssh'
path: /root/.ssh
# ③デプロイ
- id: deploy
name: gcr.io/$PROJECT_ID/tarssh
dir: 'src'
entrypoint: bash
args:
- '-c'
- |
tar cvz ./ | ssh somevps tar zxv -C /home/ubuntu/dist/
volumes:
- name: 'ssh'
path: /root/.ssh
①暗号鍵を復号化する
イメージには gcr.io/cloud-builders/gcloud を利用
事前に暗号化したファイルを --ciphertext-file で指定
--plaintext-file=/root/.ssh/{ファイル名} 出力するファイル名はなんでもいいけど、あとでマウントできるようにボリュームのパスに含めるようにする。
...
volumes:
- name: 'ssh'
path: /root/.ssh
...
この場合 /root/.ssh 後続のタスクで、このボリュームをマウントするようにして、復号化した鍵を利用する
その他、KMSのオプションについては公式参照。
②ssh接続用設定
ここでは、各種ssh接続用の設定を入れていく。具体的には、
- 鍵のパーミッション設定
- ssh接続用configファイルの生成
- known_hostsの設定
をbashで実行する。
注意点としては、先のタスクで作った鍵を利用したいので、先のタスクでマウントしたボリュームを同様にこのタスクでもマウントするようにすること。
...
volumes:
- name: 'ssh'
path: /root/.ssh
...
イメージはシェルが動かせればなんでも良いので、とりあえず、先のタスクで利用した gcr.io/cloud-builders/gcloud を使う。別途イメージをpullしてくるビルド時間が節約できる(と思う)
shell自体はbashを entrypoint に指定すればいい。
...
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: bash
...
続けて、
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: bash
args:
- '-c'
- |
echo "some shell command here~"
echo "more..."
のように、シェルで実行するコマンドを args に書けるのでよしなに。
③デプロイ
tar をssh接続で実行する。
イメージにはお手製のtarとsshが入っただけ(bashも)のイメージを事前にpushしておきそれを利用する。
gcr.io/$PROJECT_ID/tarssh
ここでも、ボリュームをマウントして参照できるようにしておく。
...
volumes:
- name: 'ssh'
path: /root/.ssh
...
感想
ビルドタスクで一時的なファイルの置き場として適当なボリュームを作って、それをマウントして持ち回ることで、
大概のタスクはできるのではと思われる。
ビルドタスク以外の部分にもTipsが必要そうなので別記事でまとめようと思う。