【使途】1時間で自滅するインスタンスを作ってみた【不明】

記事タイトルとURLをコピーする

こんにちは。クラウドインテグレーション本部 インプリメンテーション部 DB/APPプロフェッショナルチームの竹永です。
まだ部署名を覚えきれていません。

最近は真面目な文章ばかり書いていたので、息抜きにネタ成分50%のインスタンスを作ってみたいと思います。

概要

  • 1時間くらいでTerminateされるインスタンスを作ります
  • インスタンス単体で動作するようにします
  • インスタンスにAWSのアクセスキーを保存しません
  • 起動してからSSHで手を出すのは無し
  • 今のところAmazon Linuxだけ動作確認済み

とりあえずつくる

概要だけでは作り方がわからないので、とりあえず作ってみます。

IAM Roleをつくる

まずはAWS Management Consoleにログインして[IAM]をクリックします。
IAM Link

 

IAMの管理画面で[Create New Role]ボタンをクリックします。
Create IAM Role Button

 

Roleの名前を入力して[Next]ボタンを押します。
Enter Role Name

 

Role Typeは[Amazon EC2]を選択します。
Select Role Type

 

Set PermissionsではIAM Roleに設定する権限を選びますが、今回は[Custom Policy]を選択して手動入力してみます。
Select Permission Template

 

名前はわかりやすいものを、ポリシーはひとまずTerminateだけ出来るように設定して、[Next]をクリックします。
Enter Policy Name

 

今回は下記のポリシーを使いました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:TerminateInstances",
      "Resource": "*"
    }
  ]
}
 

最後にReview画面が出てきますが、IAM Roleはいくら作っても無料です。
難しいことは考えずに[Create Role]ボタンをクリックしましょう。
Create Role Button

EC2インスタンスをつくる

次に、EC2の管理画面を表示し、[Launch instance]ボタンで新しいインスタンスを作成します。
Launch Instance Button

 

Amazon Linuxを選んでいただければ、ほとんどのパラメーターはお好みで大丈夫ですが、IAM roleUser dataはお好み具合が少なくなります。

IAM roleは先ほど作成したものを指定します。
インスタンス作成後は変更できないので忘れたらダメです。
Select IAM Role

 

ユーザーデータにもスクリプトを仕込んでおきます。
インスタンス変更後も変更できますが、これが本体なので忘れたらダメです。
Input User Data

 

今回使用したスクリプトは下記のものになります。
Base64でエンコードされている箇所は、ちょこっと下の方で説明いたします。

#!/bin/sh
echo "IyEvYmluL3NoClVQVElNRT1gY2F0IC9wcm9jL3VwdGltZSB8IGF3ayAne3ByaW50ICQxICogMTAwMH0nYApSRUdJT049YGN1cmwgLXMgaHR0cDovLzE2OS4yNTQuMTY5LjI1NC8yMDE0LTAyLTI1L2R5bmFtaWMvaW5zdGFuY2UtaWRlbnRpdHkvZG9jdW1lbnQgfCBncmVwIHJlZ2lvbiB8IGF3ayAtRlwiICd7cHJpbnQgJDR9J2AKSU5TVEFOQ0VJRD1gY3VybCAtcyBodHRwOi8vMTY5LjI1NC4xNjkuMjU0LzIwMTQtMDItMjUvbWV0YS1kYXRhL2luc3RhbmNlLWlkYAppZiBbICR7VVBUSU1FfSAtZ3QgMzMwMDAwMCBdIDsgdGhlbgogIGF3cyBlYzIgdGVybWluYXRlLWluc3RhbmNlcyAtLXJlZ2lvbiAke1JFR0lPTn0gLS1pbnN0YW5jZS1pZHMgJHtJTlNUQU5DRUlEfQpmaQo=" | base64 -d > /tmp/self_terminate.sh
chmod +x /tmp/self_terminate.sh
echo "*/1 * * * * /tmp/self_terminate.sh" | crontab
 

あとは1時間分の料金を支払う覚悟をしてからインスタンスを起動すれば、自滅するインスタンスのできあがりです。
実際はタイムラグによる課金回避のために、生まれてから55分くらいで自滅しますが、あまり気にしないようにしましょう。

しくみ

Base64のなかみ

Base64はデコードするとただのシェルスクリプトです。シングルクォーテーションとかのエスケープが面倒くさくなってきたので、思い切ってBase64にしました。

#!/bin/sh
UPTIME=`cat /proc/uptime | awk '{print $1 * 1000}'`
REGION=`curl -s http://169.254.169.254/2014-02-25/dynamic/instance-identity/document | grep region | awk -F" '{print $4}'`
INSTANCEID=`curl -s http://169.254.169.254/2014-02-25/meta-data/instance-id`
if [ ${UPTIME} -gt 3300000 ] ; then
  aws ec2 terminate-instances --region ${REGION} --instance-ids ${INSTANCEID}
fi

「S3からダウンロードすればいいのでは?」と思った方は正しいです。curlwgetaws s3 cpを使えば、一発ですし、簡単ですし、おすすめです。

しかし、僕がBase64の気分でした。base64コマンドを使ってみたかったのです。

インスタンスのUptimeをもってくる

自滅するタイミングは/proc/uptimeで計測しています。
/proc/uptimeが返してくる時間が指定値以上になったら、自らをTerminateするコマンドを実行します。

今回は3300000ミリ秒(55分)を指定しました。
0を指定すれば、立ち上がって準備ができて1分ほどでTerminateするインスタンスができあがります。

AWSへのお布施にどうでしょうか。

なぞの curl -s http://169.254.169.254/

自滅するのに使用するaws ec2 terminate-instancesコマンドは、引数に--region--instance-idsが必要です。
Terminateするために必要な情報は、IMDS(Instance Meta Data Service)から取得してきます。

取得した情報を組み合わせると下記のようなコマンドができあがります。
aws ec2 terminate-instances --region ap-northeast-1 --instance-ids i-xyz12345

-sオプションはcurlをSilent modeで実行させているだけです。
とても元気だったので静かになってもらいました。

アクセスキーは?

AWS CLIは、インスタンスにIAM Roleを指定するとアクセスキー等を指定しなくても動くようになります。
APIを自力で叩こうとすると、IAM Roleから一時的なアクセスキーを取得するだけでも一苦労ですが、AWS CLIのお陰で簡単に使えます。

IAM Roleを間違えると、Terminateし放題のインスタンスが完成します。

最後の一手間

最後に、上記で解説したスクリプトを、cronで1分ごとに実行します。
インスタンスに負荷が掛かっているとスクリプトの実行に時間がかかりそうだったので、55分くらいでTerminateするようにしています。

余談

「インスタンスがいるリージョン名」を取得する箇所だけは、何故か苦労しました。
Availability Zoneは簡単に取得することが出来るのですが、後ろにくっついている"a"とか"b"とか"c"という1文字が少し厄介です。

AWK最強説。

ユースケースは?

正直に言うとジョークスクリプトの類です。1時間後には何も残っていないので、やたらとたちが悪いです。
Spot Instanceをいっぱい作ってバッチっぽい処理を動かすといいかもしれませんが、そのまま使うと1時間で中断されます。惜しい。

cronで1時間や1日毎に、TerminateではなくAMIを作成すればバックアップには使える可能性があります。

ただ、自分でスクリプトを書いて自動バックアップ環境を構築するよりCloud Automatorを使ったほうが早いです。

ちなみにテストは行っていますが動作保証はしていません。
10分で自滅するように設定したら、10分3秒で自滅したことはご報告いたします。

まとめ

無駄な動きをする無駄に手の込んだ無駄なスクリプトを作るのは楽しいです。
Base64の日報」を…思い出しました…。

…ごめんなさい、ごめんなさい…もうしません…。