先日、AWSのCloudFormationを使って、ステージング環境を必要な時だけ立ち上げる、ということを書きました。
CloudFormationでAWS上にステージング環境を必要な時だけ一発で立ち上げる。
CloudFormationは起動も一発ですし、削除も一発なので便利です。
いちいち起動するのが面倒くさい
この方法を使うと、普段はステージング環境を停止状態にできて、数万円のコスト削減ができます。
しかしながらデメリットもあります。ステージング環境で動作確認をしたいタイミングで、自ら起動ボタンを押しに行かなければならない、という問題です。
そこで、Jenkins!
Welcome to Jenkins CI! | Jenkins CI
ジョブチェーンにステージング環境の起動を追加
JenkinsにGitのリポジトリを監視させて、コミットがあったときに、ステージング環境が自動で立ち上がってくれたら楽ができます。
元々、Gitのコミットをフックにアプリケーションをビルドするように設定していたので、このビルドが成功した時にステージング環境の起動もするようにします。
ステージング環境を起動するというだけのジョブを作成して、それを呼び出すわけです。
このジョブからCloudFormationによるステージング環境の起動をします。
CloudFormationでステージング環境の起動
ステージング環境の起動のためのJenkinsジョブは、ただのシェルスクリプトです。
既にステージング環境が起動されていないか確認し、起動されていなければ新しく起動します。
aws cloudformation describe-stacks --stack-name my365-staging
if [ $? -eq 0 ]; then
exit 0
fi
TEMPLATE_BODY=`cat '/etc/my365/conf/cloudformation-staging.template'`
aws cloudformation create-stack --stack-name my365-staging --template-body "$TEMPLATE_BODY"
簡単です!
一定時間後にステージング環境の停止
起動するのは、Gitのコミットフックでおこなえるので、比較的簡単です。
むしろ難しいような気がするのは、使い終わった時にステージング環境を解放する作業です。でも、これが自動化されていないと、確実に起動したまま放置される未来が見えます。
それではダメなので、自動で解放されるようにします。AWSが1時間単位の課金なので、理想的には1時間弱で停止してくれると嬉しいです。
残念ながらあまりかっこいい方法ではありませんが、cronで定期的にステージング環境の起動状態をチェックして解放することにしました。
cat <<'EOT' | sudo tee /etc/cron.d/my365
*/1 * * * * root /var/lib/my365/script/delete-expired-staging >> /var/log/my365/delete-expired-staging.log 2>&1
EOT
1分に1回、ステージング環境の起動状態をチェックします。
起動して1分で停止されてしまったら困るので、Jenkinsのジョブが40分以内に存在するかを確認して、CloudFormationのスタックを削除するか決めています。
JOB_NAME='my365-launch-staging-environment'
DURATION_PERIOD=40
aws cloudformation describe-stacks --stack-name my365-staging
if [ $? -gt 0 ]; then
exit 0
fi
RECENT_LAUNCH=`find /var/lib/jenkins/jobs/"$JOB_NAME"/builds/ -mmin -"$DURATION_PERIOD" | wc -l`
if [ $RECENT_LAUNCH -gt 0 ]; then
exit 0
fi
aws cloudformation delete-stack --stack-name my365-staging
Jenkinsのジョブを監視しておくと良いのは、40分以内に立て続けにGitにコミットし続けると、ステージング環境を停止せずに生かし続けられることです。
おわりに
そんなわけで、JenkinsのジョブチェーンにCloudFormationによるステージング環境の起動設定を追加することで、必要な時に必要なだけステージング環境が使えるようになりました。
CloudFormationのスタックが完成するのに5分くらいかかることと、DNSまで貼り替えているので名前解決ができるまで少し時間がかかっているので、「コミットして即確認」というわけにはいかないのが、今の課題です。
コメント
[…] Jenkinsと連動させて起動・停止をするお話に続きます。→ステージング環境をGitフックでJenkinsから起動・停止してコスト削減! […]