TL;DR
metadata_startup_script = <<-EOF
#!/bin/bash
TARGET_REPOSITORY_URL=github.com/... # ここは適宜差し替えてください
TARGET_BIN_NAME=... # ここも
mkdir /home/user
export HOME=/home/user
cd /usr/local/src
wget https://go.dev/dl/go1.17.7.linux-amd64.tar.gz > /dev/null 2>&1
tar -C /usr/local/ -xzf go*.tar.gz > /dev/null 2>&1
GOCACHE=/usr/local/go/cache GOBIN=/usr/local/go/bin GOPATH=/usr/local/go /usr/local/go/bin/go install -v ${TARGET_REPOSITORY_URL}@latest
/usr/local/go/bin/${TARGET_BIN_NAME}
EOF
はじめに
Google Compute Engine には VM が起動する時に実行されるコマンドである startup script
を設定できます。
最近は Terraform による GCP リソースの宣言的な管理をされることが増えてきたため、この機能を利用する方も増えてきたのではないでしょうか?
私もその1人だったのですが、下記の通り書いただけでは起動してくれませんでした。なお、これらのインストールコマンドは Go の公式インストール方法 を引用しています。
metadata_startup_script = <<-EOF
#!/bin/bash
TARGET_REPOSITORY_URL=github.com/... # ここは適宜差し替えてください
TARGET_BIN_NAME=... # ここも
wget https://go.dev/dl/go1.17.8.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.8.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
export GOBIN=~/go/bin
go install -v ${TARGET_REPOSITORY_URL}@latest
${TARGET_BIN_NAME}
EOF
最終的に解決できたものの、同じ問題に対して記事を書いている方が見当たらなかったため、本記事では
- 実行できなかった原因と解決策
- startup script のデバッグ方法
の2つに絞って紹介します。
とはいえ、ドキュメントに全部書いてあったので、こんな記事読むより公式のドキュメント読んでください。
実行できなかった原因
startup script
が root ユーザ として実行されており、 $HOME
等の環境変数も利用できなかったためです。
ドキュメントには、下記の通り書かれています。
Compute Engine は次の処理を行います。
- 起動スクリプトを VM にコピーする
- 起動スクリプトの実行権限を設定する
- VM の起動時に root ユーザーとして起動スクリプトを実行する
そのため、環境変数 HOME
や GOPATH
、GOBIN
、 GOCACHE
あたりを明示的に書けば良いです1。
startup script のデバッグ方法
公式ドキュメントを読んでください。
起動スクリプトが失敗した原因は、 ssh 等で VM に入ってから下記コマンドを実行してください。
sudo journalctl -u google-startup-scripts.service
また、この journalctl
のログは、 wget
や tar
の解凍時のログ出力により、読みたい部分が消えていることがあります(ありました)。そのため、 冗長なログ出力をするコマンドがある場合は、検証中のみ startup sciprt
における出力を > /dev/null 2>&1
を末尾につけて消すことが効果的です。
ただし、実行に失敗していることも気づけなくなるので、問題の切り分けを行った上で実施してください。
おわりに
冒頭で提示したスクリプトはあくまでシュッと書いたものなので、もっとイケてる書き方があれば教えてください。
この記事が少しでも参考になれば幸いです。