ステータスが cancelled の状態で動いている Spot Instance を terminate する
Jenkins EC2 Plugin を使っていたら、
ステータスが cancelled なのに動いたままのインスタンスがありました。
今まで cancelled になっていたら terminate されていたので、
cancel = terminate だと思っていたのですが、それは間違いなようです。
詳細は、スポット入札ステータス を参照していただきたいのですが、
スポット入札ステータスコードが、request-canceled-and-instance-running
の場合は、
スポットインスタンスがまだ実行されている間に、リクエストをキャンセルしました。リクエストは canceled ですが、インスタンスは running のままです。
となるようです。
ステータスメッセージには、Your Spot request is canceled, but your i-xxxxxxxx is still running.
と書かれます。
Spot Instance 自身にスポット入札ステータスを監視させて、request-canceled-and-instance-running
の場合は、terminate するようにすれば確実そうですので、
shellscript を書きました。
自分自身に監視させる場合
[ -n "$(aws ec2 describe-spot-instance-requests --filters Name=status-code,Values=request-canceled-and-instance-running Name=instance-id,Values=$(curl -s 169.254.169.254/latest/meta-data/instance-id) | jq .SpotInstanceRequests[])" ] && halt
別のサーバから監視する場合
INSTANCE_IDS=$(echo $(aws ec2 describe-spot-instance-requests --filters Name=status-code,Values=request-canceled-and-instance-running | jq -r .SpotInstanceRequests[].InstanceId)) [ -n "${INSTANCE_IDS}" ] && aws ec2 terminate-instances --instance-ids ${INSTANCE_IDS}
test -n で aws ec2 describe-spot-instance-requests
の結果が空かどうかチェックしています。
空だとステータスコード 1 が返るので、halt
も terminate-instances
も実行されません。
これを cron で数分毎に実行すれば良さそうです。
別のサーバから監視するスクリプトを改変する場合は、
失敗すると意図しないインスタンスが terminate される可能性がありますのでご注意ください。