Amazon EC2の自動起動・停止をAWS CloudFormationで実装してみた
はじめに
こんにちは、hengeです。
今回はEC2インスタンスの自動起動・停止という機能をCloudFormationで実装する方法についてまとめました。
皆様、AWSの利用料金…お困りではないですか?
AWSのコスト削減方法には、使用するリソースの設定見直しやログファイルなどのライフサイクルの設定など様々な方法があります。
それらの方法の1つに、EC2インスタンスの稼働時間の削減があります。
ご存じの通りEC2利用料金はインスタンスの稼働時間によって増加します。
そこで、インスタンスを利用しない時間にインスタンスを停止しておくことでコストの削減が見込めます。
今回はCloudFormationとEventBridgeを用いて、EC2インスタンスを自動的に停止・起動してくれる機能を楽に実装する方法をお伝えいたします。
EventBridgeによる自動化
いざコスト削減のためにEC2インスタンスを勤務時間外には停止しておくようにしよう!とルールを定めても、全てが上手くいくわけではありません。
手動でインスタンスを停止するということになると、
- 停止し忘れる
- 誤って停止ではなく終了(インスタンスの削除)してしまう
- インスタンス数が多い場合面倒
といった問題が考えられます。
そこで、こういった単純作業は自動化しましょう。
インスタンスの停止をシステム上で行うことで、人の手を介さないことからヒューマンエラーの防止になりますし、工数削減にもなります。
今回は自動化のためにEventBridgeというサービスを利用します。
EventBridgeでは予め「ルール」と「ターゲット」という設定をすると、ルールに従ってターゲットで記述された動作を実行します。
つまり、「指定の時刻になったらEC2インスタンスを起動・停止する」というルールを作成して、起動・停止を自動化したいEC2インスタンスをターゲットで指定すると、自動起動・停止が実現できるわけですね。
EventBridgeについて詳しく知りたい方は以下の記事をご覧ください。
Amazon EventBridge とは – Amazon EventBridge
CloudFormationによるリソースの作成
CloudFormationとは、コードによってAWSリソースを管理するサービスです。
初めてAWSを触る方はコンソール画面からぽちぽちとリソースの詳細設定を行うかと思いますが、毎回それを行うのは面倒ですよね。
一方でCloudFormationを利用すれば、予めリソースの詳細設定などを記述したファイルをアップロードするだけで複数のリソースを作成できます。
つまり、CloudFormationを利用することで、
- ヒューマンエラー防止
- 工数削減
といったメリットが見込めます。
この2つは自動化のメリットでもありましたね。
せっかく自動化でこれらのメリットを享受できてもその設定段階でミスをしたり手間がかかっては本末転倒ですから、設定から実際の稼働までメリットを生かしましょう。
CloudFormationについてより詳しく知りたい方は以下の記事をご覧ください。
テンプレート紹介
早速ですが、今回用いたテンプレートをご紹介します。
本テンプレートは東京リージョンでの使用を想定しています。
AWSTemplateFormatVersion: "2010-09-09" Description: EventBridge Rule Test # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# Resources: VPC: Type: "AWS::EC2::VPC" Properties: CidrBlock: "10.0.0.0/16" # ------------------------------------------------------------# # Subnet # ------------------------------------------------------------# PrivateSubnet: Type: "AWS::EC2::Subnet" Properties: AvailabilityZone: ap-northeast-1a CidrBlock: "10.0.0.0/24" VpcId: !Ref VPC # ------------------------------------------------------------# # EC2 # ------------------------------------------------------------# EC2Instance: Type: "AWS::EC2::Instance" Properties: ImageId: ami-0e1a141f1d5c52056 InstanceType: t2.micro SubnetId: !Ref PrivateSubnet Tags: - Key: Name Value: henge-test-instance # ------------------------------------------------------------# # EventBridge # ------------------------------------------------------------# # イベント実行に必要なIAMロールを作成 AmazonSSMAutomationRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: # EventBridgeのサービスプリンシパル - "events.amazonaws.com" Action: sts:AssumeRole ManagedPolicyArns: # オートメーションのためのIAMマネージドポリシー - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole # EC2インスタンスを自動起動するルール StartEC2InstanceRule: Type: AWS::Events::Rule Properties: Name: StartEC2Instance Description: StartEC2Instance # ルールを実行するスケジュール ScheduleExpression: cron(20 05 ? * * *) State: ENABLED Targets: # EventBridgeが呼び出す操作のARN - Arn: arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StartEC2Instance:$DEFAULT Id: StartEC2Instance # 先ほど作成したIAMロールのARN RoleArn: !Sub ${AmazonSSMAutomationRole.Arn} # EC2インスタンスの自動起動の操作時に入力するパラメータ Input: !Sub '{"InstanceId":["${EC2Instance}"]}' StopEC2InstanceRule: Type: AWS::Events::Rule Properties: Name: StopEC2Instance Description: StopEC2Instance ScheduleExpression: cron(25 05 ? * * *) State: ENABLED Targets: - Arn: "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StopEC2Instance:$DEFAULT" Id: StopEC2Instance RoleArn: !Sub ${AmazonSSMAutomationRole.Arn} Input: !Sub '{"InstanceId":["${EC2Instance}"]}'
以下で今回のポイントであるEventBridge関連の記述について解説いたします。
なお、インスタンス自動停止のルールについては、ほぼインスタンス自動起動のルールと同様であるため割愛いたします。
EventBridgeがイベントを実行するためのIAMロール作成
# ------------------------------------------------------------# # EventBridge # ------------------------------------------------------------# # イベント実行に必要なIAMロールを作成 AmazonSSMAutomationRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: # EventBridgeのサービスプリンシパル - "events.amazonaws.com" Action: sts:AssumeRole ManagedPolicyArns: # オートメーションのためのIAMマネージドポリシー - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole
本リソースではEventBridgeが自動的にEC2インスタンスを操作するためのIAMロールを作成しています。
これがないとIAM権限不足で自動起動・停止を行うことができません。
EventBridgeがイベントを実行するときに、本ロールを呼び出します。
本IAMロールにアタッチされたIAMマネージドポリシーの詳細については以下をご覧ください。
AmazonSSMAutomationRole – AWS マネージドポリシー
EC2インスタンス自動起動のルール作成
# EC2インスタンスを自動起動するルール StartEC2InstanceRule: Type: AWS::Events::Rule Properties: Name: StartEC2Instance Description: StartEC2Instance # ルールを実行するスケジュール ScheduleExpression: cron(20 05 ? * * *) State: ENABLED Targets: # EventBridgeが呼び出す操作のARN - Arn: arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StartEC2Instance:$DEFAULT Id: StartEC2Instance # 先ほど作成したIAMロールのARN RoleArn: !Sub ${AmazonSSMAutomationRole.Arn} # EC2インスタンスの自動起動の操作時に入力するパラメータ Input: !Sub '{"InstanceId":["${EC2Instance}"]}'
本リソースではEventBridgeがEC2インスタンスを自動起動するルールを作成しています。
仕組みとしては、cron式で記述されたScheduleExpression
で指定された時間になるとInstanceID
で指定されたEC2インスタンスを自動的に起動するようになっています。
しかし、EventBridgeが直接EC2インスタンスをどうこうするわけではありません。
インスタンスの起動・停止を行うのはSystems Manager Automationというサービスであり、EventBridgeはSystems Manager Automationを呼び出しているだけですのでご注意ください。
ちなみに、本リソース内のRoleArn
という変数に関する記述が今回の難所でした。
難所
RoleArn: !Sub ${AmazonSSMAutomationRole.Arn}
このRoleArn
という変数では作成したIAMロールのARNを参照したいのですが、リソース名のみではIAMロール名が戻り値として返されてしまいます。
そこで、このようにリソース名の後ろに.Arnと入力するとこのリソースのARNが返されるようになります。
今まで戻り値を気にしたことがあまりなかったので個人的には良い学びになりました。
${MyInstance.PublicIp} などのリソース属性を指定すると、CloudFormation は Fn::GetAtt 組み込み関数を使用した場合と同じ値を返します。
出典:Fn::Sub – AWS CloudFormation
検証
さて、ここまでテンプレートの解説をしてきましたが、百聞は一見に如かずということで検証を行ってみましょう。
検証手順は以下の通りです。
- CloudFormationでスタックを作成
- EC2インスタンスを手動で停止
- EC2インスタンスの稼働状況を監視
CloudFormationでスタックを作成
コンソール画面から「henge-test-for-blog」という名前のスタックを作成します。
念のため作成したリソースを確認します。
無事EventBridgeのルールが作成されました。
今回の検証ではインスタンスの起動時間を14時20分、停止時間を14時25分としています。
EC2インスタンスの稼働状況を監視
では、本当にEC2インスタンスが自動的に起動・停止されるのか確認しましょう。
14時18分現在、インスタンスの状態は「停止済み」です。
このまま14時20分まで待ってみると、インスタンスの状態が「保留中」に。
それから数十秒すると、インスタンスの状態が「実行中」に変化しました。
無事に自動起動できたようですね!
続いて14時25分まで待つと、今度はインスタンスの状態が「停止中」に。
それから数十秒すると、インスタンスの状態が「停止済み」に変化しました。
自動停止についても上手くいったようです!
まとめ
今回はEventBridgeによるEC2インスタンスの自動起動・停止をCloudFormationで実装しました。
CloudFormationはデプロイの手軽さやヒューマンエラー防止の観点から見れば非常に便利な概念ですので、是非ご活用いただければと思います。
EventBridgeによる自動化も工数の削減やヒューマンエラー防止のために積極的に活用したい機能ですね。
せっかくクラウドというサービスを利用しているからには楽できる部分はどんどん楽していきましょう!
ここまで読んでいただきありがとうございました!
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitter第二SAチームのhengeです。 ゲームとゴルフが好きなエンジニアです。 よろしくお願いします。
Recommends
こちらもおすすめ
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16