EventBridgeでec2の開始と停止をcfnで実現する

EventBridgeでec2の開始と停止をcfnで実現する

2024/01/14 00:00:00
Program
Ubuntu, Aws

前提 #

EventBridgeでec2の開始と停止をcfnファイル(yaml)を作成する #

ec2 の開始と停止を制御する event bridge の cfn を作成する。
作成する内容は以下の通り。

  • 開始時間 am8:00
  • 停止時間 am0:00
  • 時間はJST
  • 開始/停止に必要なIAM追加

$ emacs ec2-start-stop-schedule.yml

 1AWSTemplateFormatVersion: 2010-09-09
 2Description: EventBridge Scheduler for start/stop of ec2 instance
 3
 4Parameters:
 5  EC2InstanceId:
 6    Type: String
 7    Default: i-0a310f474534f0f89  # 開始/停止するec2インスタンスID
 8    Default: i-XXXXXXXXXXXXXXXXX  # 開始/停止するec2インスタンスID
 9  ScheduleStartTime:
10    Type: String
11    Default: "cron(0 8 * * ? *)"  # am8時に起動
12  ScheduleStopTime:
13    Type: String
14    Default: "cron(0 0 * * ? *)"  # am0時に停止
15  ScheduleTimezone:
16    Type: String
17    Default: Japan  # 日本時間(JST)指定
18
19Resources:
20  MyScheduleEC2Sart:
21    Type: AWS::Scheduler::Schedule
22    # 現在は AWS::Events::Rule ではなく AWS::Scheduler::Schedule を使うべき
23    # - EventBridge Schedulerを使ってEC2を定期起動・停止するCloudFormationテンプレート
24    #   https://dev.classmethod.jp/articles/cloudformation-template-eventbridge-scheduler-ec2-start-stop/
25    Properties:
26      Name: !Sub 'EC2-Start-${EC2InstanceId}'
27      Description: Start EC2 Instance
28      ScheduleExpression: !Ref ScheduleStartTime 
29      ScheduleExpressionTimezone: !Ref ScheduleTimezone
30      FlexibleTimeWindow:
31        Mode: "OFF"
32      State: ENABLED
33      Target:
34        Arn: arn:aws:scheduler:::aws-sdk:ec2:startInstances
35        Input: !Sub '{"InstanceIds":["${EC2InstanceId}"]}'
36        # Input: !Sub |-
37        #   {
38        #     "InstanceIds": ["${EC2InstanceId}"]
39        #   }
40        RoleArn:
41          Fn::GetAtt:
42            - MyEC2StopStartRole
43            - Arn
44
45  MyScheduleEC2Stop:
46    Type: AWS::Scheduler::Schedule
47    Properties:
48      Name: !Sub 'EC2-Stop-${EC2InstanceId}'
49      Description: Stop EC2 Instance
50      ScheduleExpression: !Ref ScheduleStopTime 
51      ScheduleExpressionTimezone: !Ref ScheduleTimezone
52      FlexibleTimeWindow:
53        Mode: "OFF"
54      State: ENABLED
55      Target:
56        Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances
57        Input: !Sub '{"InstanceIds":["${EC2InstanceId}"]}'
58        # Input: !Sub |-
59        #   {
60        #     "InstanceIds": ["${EC2InstanceId}"]
61        #   }
62        RoleArn:
63          Fn::GetAtt:
64            - MyEC2StopStartRole
65            - Arn
66
67  MyEC2StopStartRole:
68    Type: AWS::IAM::Role
69    Properties:
70      AssumeRolePolicyDocument:
71        Version: '2012-10-17'
72        Statement:
73          - Effect: Allow
74            Principal:
75              Service:
76                - scheduler.amazonaws.com
77            Action:
78              - sts:AssumeRole
79      Path: "/"
80      Policies:
81        - PolicyName: EC2StopStart
82          PolicyDocument:
83            Version: "2012-10-17"
84            Statement:
85              - Effect: Allow
86                Action:
87                  - ec2:StartInstances  # カスタムのIAMリソースではない
88                  - ec2:StopInstances  # カスタムのIAMリソースではない
89                Resource:
90                  - "*"

aws cli コマンド実行 #

新規、更新、削除を実行するコマンドを以下に示す。
※ aws profile を指定する場合、–profile [プロファイル名] オプションを付加すること

新規 #

$ aws cloudformation create-stack --stack-name myEC2StartStopSchedule --template-body file://ec2-start-stop-schedule.yml --capabilities CAPABILITY_IAM
  • スタックのリソース(ec2-start-stop-schedule.yml)の中にIAM リソースがあるので、–capabilities オプション指定は必須
    また、–capabilities オプションに指定する内容は、カスタム名の IAM リソースの指定がないので、CAPABILITY_IAM を指定
    カスタム名の IAM リソースがある場合、CAPABILITY_NAMED_IAM を指定する必要がある

    # IAM リソースがあるにもかかわらず --capabilities オプション指定なしだと以下のエラーが発生する
    $ aws cloudformation create-stack --stack-name myEC2StartStopSchedule --template-body file://ec2-start-stop-schedule.yml
    An error occurred (InsufficientCapabilitiesException) when calling the CreateStack operation: Requires capabilities : [CAPABILITY_IAM]
    

更新 #

$ aws cloudformation update-stack --stack-name myEC2StartStopSchedule --template-body file://ec2-start-stop-schedule.yml --capabilities CAPABILITY_IAM

削除 #

$ aws cloudformation delete-stack --stack-name myEC2StartStopSchedule

参考UR #