概要
以下のような構成をセットアップして、カレンダー形式で EC2 インスタンスの起動停止スケジュールを管理してみます。Change Calendar とは
AWS Systems Manager (SSM) の一機能である Change Calendar は、同じく SSM の Automation などのアクションを実行できる日時をカレンダー形式で管理するものです。上記画像のカレンダーは DEFAULT_CLOSED という設定になっています。
この場合、カレンダーに予定(イベント)を作成すると、そのイベント中は OPEN というステータスになります。
カレンダーのステータスが変更される時、EventBridge イベントが発生します。
本記事ではこれを利用して EC2 インスタンスの起動停止スケジュールを管理します。
AWS Systems ManagerChange Calendar Events
準備・設定
以下のうち、カレンダーと EC2 インスタンスを作成しておきます。 カレンダーは DEFAULT_CLOSED で作成します。カレンダーとインスタンスを作成したら、以下の CloudFormation テンプレートをデプロイします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
AWSTemplateFormatVersion: 2010-09-09 Parameters: Prefix: Type: String InstanceId: Type: AWS::EC2::Instance::Id CalendarName: Type: String Resources: StartEventsRule: Type: AWS::Events::Rule Properties: Name: !Sub ${Prefix}-start-rule EventPattern: source: - aws.ssm detail-type: - Calendar State Change resources: - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:document/${CalendarName} detail: state: - OPEN State: ENABLED Targets: - Id: AWS-StartEC2Instance Arn: !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StartEC2Instance:$DEFAULT RoleArn: !GetAtt EventsRole.Arn Input: !Sub "{\"InstanceId\":[\"${InstanceId}\"]}" DeadLetterConfig: Arn: !GetAtt DLQueue.Arn StopEventsRule: Type: AWS::Events::Rule Properties: Name: !Sub ${Prefix}-stop-rule EventPattern: source: - aws.ssm detail-type: - Calendar State Change resources: - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:document/${CalendarName} detail: state: - CLOSED State: ENABLED Targets: - Id: AWS-StopEC2Instance Arn: !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StopEC2Instance:$DEFAULT RoleArn: !GetAtt EventsRole.Arn Input: !Sub "{\"InstanceId\":[\"${InstanceId}\"]}" DeadLetterConfig: Arn: !GetAtt DLQueue.Arn EventsRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${Prefix}-events-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: ssm:StartAutomationExecution Resource: - !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StartEC2Instance:$DEFAULT - !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StopEC2Instance:$DEFAULT - Effect: Allow Action: - ec2:StartInstances - ec2:StopInstances Resource: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId} - Effect: Allow Action: ec2:DescribeInstanceStatus Resource: "*" DLQueue: Type: AWS::SQS::Queue Properties: QueueName: !Sub ${Prefix}-dlqueue QueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: SQS:SendMessage Resource: !GetAtt DLQueue.Arn Queues: - !Ref DLQueue |
イベント開始時(カレンダーが OPEN になった時)、インスタンスが起動されます。
逆にイベント終了時(カレンダーが CLOSED になった時)は、インスタンスが停止されます。
つまり、インスタンスを稼働させておきたい時間帯を予定(イベント)として登録しておく、という使い方になっています。
※Change Calendar の仕様で開始~終了まで5分以上空ける必要があります。
動作確認
カレンダーに登録したイベント通りにインスタンスが起動・停止されているか確認してみましょう。また、SSM Automation コンソールから起動・停止の実行履歴を確認することが出来ます。
補足
EventBridge で指定するリソースARN
CloudFormation テンプレートの AWS::Events::Rule の EventPattern を見ると、resources に SSM ドキュメントの ARN が指定されてます。Change Calendar のイベントなので、最初は "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:calendar/${CalendarName}" のようになると思っていたのですが違いました。
1 2 3 4 5 6 7 8 9 |
source: - aws.ssm detail-type: - Calendar State Change resources: - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:document/${CalendarName} detail: state: - OPEN |
AWS Systems Manager Change Calendar
Change Calendar エントリを作成すると、ChangeCalendar
タイプの Systems Manager ドキュメントが作成されます。
このSSMドキュメントはマネジメントコンソール上では確認できませんでしたが、CLI から参照することは出来ました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ aws ssm describe-document --name StartStopScheduler { "Document": { "Hash": "xxxxxxxxxx", "HashType": "Sha256", "Name": "StartStopScheduler", "Owner": "111122223333", "CreatedDate": "2022-05-31T03:29:05.315000+00:00", "Status": "Active", "DocumentVersion": "17", "Description": "", "PlatformTypes": [], "DocumentType": "ChangeCalendar", "LatestVersion": "17", "DefaultVersion": "17", "DocumentFormat": "TEXT", "Tags": [], "Category": [], "CategoryEnum": [] } } |
SQS について
今回の CloudFormation テンプレートには、EventBridge + SSM Automation の実行が失敗した場合のデッドレターキュー(SQS)を設定していました。 EventBridge + SSM Automation を設定した場合の困りごとの1つが、Automation の実行できなかった場合のトラブルシューティングです。イベントパターンに該当するイベントが発生したのに Automation が実行されないような場合、その失敗原因を示すログが見当たりません。
ですが Automation が失敗した場合のデッドレターキューを設定しておくと、そのあたりのトラブルシューティングが容易になります。
Automation が実行できなかった際、そのイベントが設定したキュー(SQS)にメッセージングされますが、そのメッセージの属性に有用な ERROR_MESSAGE が記載されています。
投稿者プロフィール
- 2015年8月入社。弊社はインフラ屋ですが、アプリも作ってみたいです。