EC2インスタンスを夜になったら自動で停止する 前編
背景
個人のAWS環境のインスタンスを止め忘れてしまうことが度々あるので、この仕組みを作ることにしました。
方法を考える
1. Lambdaを使う方法
インスタンスを停止する関数を作り、CloudWatch Eventのcronで毎晩起動してあげればできそうです。
"Lambda EC2"でググったら公式のQ&Aもありました。
2. Systems Managerを使う方法
Systems ManagerのAutomationドキュメントに"AWS-StopEC2Instance"というのがあります。
これをMaintenance Windowで毎晩実行するように指定してあげればできそうです。
実装
今回はLambdaの勉強も兼ねて、1. の方法で実装したいと思います。
上で載せたQ&Aを参考に進めていきます。
Lambda関数の作成
Lambda関数を作ります。
「一から作成」を選択して、関数名とランタイムを下記のように設定します。
関数名: StopEc2Instances
ランタイム: Python3.7
アクセス権限については今回はカスタムロールを作るので、
「関数のアクセス権限を定義するロールを選択します。カスタムロールを作成するには、IAM コンソールに移動します。」
からIAMコンソールに移動してロールを作ります。
IAMロールの作成
IAMロールを作ります。
「信頼されたエンティティ」は「AWSサービス」、「このロールを使用するサービス」は"AWS Lambda"を選択し、「次のステップ: アクセス権限」をクリック。
今回はカスタムポリシーを使うので、「ポリシーの作成」をクリックしてポリシーの作成ページに飛びます。
"JSON"タブをクリックし、下記のポリシーを貼り付けます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "ec2:Start*", "ec2:Stop*" ], "Resource": "*" } ] }
「ポリシーの確認」をクリックし、名前をつけます。今回は"stop-instances-lambda-policy"にしました。
説明は入力しなくても良いので今回は省略します。
「ポリシーの作成」をクリックするとポリシーが作成されるので、作りかけになっていたロールの作成画面に戻ります。
更新ボタン(ぐるぐるしてる矢印マーク)を押して、先ほど作成したポリシーを探し、チェックボックスにチェックを入れます。
「アクセス権限の境界の設定」については今回は必要ないのでそのままで。
次のステップの「タグ」も現時点では必要ないのでスキップします。
ロールの名前をつけて、「ロールの作成」をクリックして終わりです。
Lambda関数の作成 続き
作りかけになっているLambda作成画面に戻ります。
「アクセス権限」 > 「実行ロールの選択または作成」> 「実行ロール」プルダウンから「既存のロールを使用する」を選びます。
更新ボタンを押して、プルダウンを開くと先ほど作成したロールが出てくるので、選択します。
これで関数の箱ができました。
トリガーの設定
Lambda関数を動かすためのトリガーを設定します。
今回は毎日夜0時にインスタンスを停止するように設定します。
Lambdaコンソールで、「トリガーの追加」から"CloudWatch Events"を選択します。
「トリガーの設定」 > 「ルール」で「新規ルールの作成」を選択します。
名前をつけ、ルールタイプの設定をします。
今回は定刻にLambdaを起動したいので、「スケジュール式」を選択します。
「スケジュール式」に下記のcron式を入力します。
cron(0 15 * * ? *)
※ここではタイムゾーンがUTCなので、-9した値を使います。
こんな感じです↓
次回: 関数の中身の作成
だいぶ長くなってしまったので、本題とも言えるLambda関数のコードを書くのは後編に分けようと思います。
東京リージョンのインスタンスをすべて停止するように、*とかで指定できるかなと思ったのですが、InstansIdsって必須なんですね…
IDのハードコードはなるべくしたくないので、一旦起動中のインスタンスのIDを持ってきて変数に入れるということが必要そうです。