またやられた。。。
EC2インスタンスが立ち上がりっぱなしになっていて、多額の請求が来た。。。という経験は誰にでもあるはず。
そこで、atコマンドとaws cliコマンドを組み合わせて、〇日後にインスタンスを自動的に停止するような防衛策を考えました。(〇日後に自動的にインスタンスが停止するだけです。)
10日後にインスタンスを自動的に停止するコマンド
自動的に停止したいインスタンスにログインして以下のコマンドを実行する。
$ at $(date -d '10 days' '+%Y-%m-%d')
するとat>
という入力待ちモードになるので、以下を入力してEnter
aws ec2 stop-instances --instance-ids $(curl -s http://169.254.169.254/latest/meta-data/instance-id)
最後にCtrl+Dで入力モードを抜けて終わりです。
要素技術の説明
atコマンド
at
コマンドは指定された日時にコマンドを自動実行してくれます。使い方は、
- 日時を指定して
at
コマンドを実行する。 -
at>
に実行したいコマンドを入力していく。 -
Ctrl+D
で終了する。
例えば、2020年1月1日の12時34分にtest.txtというファイルを生成するには以下のコマンドを実行します。
$ at 12:34 2020-1-1
at> touch test.txt
at> <EOT>
atq
コマンドでジョブができたか確認できます。
$ atq
1 2020-01-01 12:34 a ec2-user
at -c
コマンドでジョブの詳細を確認できます。
$ at -c 1
ジョブの削除はatrm
コマンドを使います。
$ atrm 1
dateコマンド
date
コマンドは現在日時を返してくれます。現在日時から〇分後、〇日後の日時や、フォーマットを指定して日時を返すこともできます。例えば、現在日時から10日後の日時であれば以下のコマンドで取得できます。
$ date -d '10 days' '+%H:%M %Y-%m-%d'
01:09 2018-01-12
'10 days'
の部分を必要に応じて変更して使ってください。
ちなみに、EC2インスタンスのTimeZoneを設定していない場合、日本時間ではなくUTCになっているかと思います。
aws ec2 stop-instancesコマンド
インスタンスの停止はaws ec2 stop-instances
コマンドを使います。例えば、インスタンスIDi-0xxxxyyyyzzzzwwww
のインスタンスを停止したい場合は、以下のコマンドで実行できます。
$ aws ec2 stop-instances --instance-ids i-0xxxxyyyyzzzzwwww
インスタンスIDをいちいちコピペするのはめんどくさいですが、自身のインスタンスIDであれば、以下のようにAWSのインスタンスメタデータサービスを利用することで取得できます。
$ curl -s http://169.254.169.254/latest/meta-data/instance-id
したがって、自身のインスタンスを停止するコマンドは以下になります。
$ aws ec2 stop-instances --instance-ids $(curl -s http://169.254.169.254/latest/meta-data/instance-id)
あとがき
atコマンドとaws cliコマンドをコマンドを組み合わせることで、〇日後にインスタンスを自動停止する仕組みができました。どのインスタンスであっても同じ手順で自動停止の仕組みを取り入れられることは便利かなと思いましたが、10台、20台となってくると、、、
もし継続的なコストを削減したいのであれば、lambdaやCloudWatchを使ったインスタンスの自動停止、自動起動が効果的かと思います。