EC2自動起動自動停止を全てcloudFormationで!

· ☕ 2
🏷️
  • #aws
  • #AMI
  • EC2を自動起動停止するのをcloud watch eventにお願いしようとしています。

    その仕組みをcloudFormationで頑張る話。

    いやぁ、久々にだいぶ頑張りました//

    作っているもの

    力尽きちゃったので、図解はまた改めて…

    • 起動イベント

    • 停止イベント

    • 起動停止ができるロール

    template

    時間はUTCタイムで!

    日本時間-9時間です。

    デフォルトは0時から12時⇒日本時間の9時~21時にしてあります。

    実行コマンドは最後におまけでつけてあります。

     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
    
    AWSTemplateFormatVersion: "2010-09-09"
    Description: 
      ec2-start-stop Create
    Parameters:
      InstanceName:
        Type: String
      StartHour:
        Type: String
        Default: 0
      StopHour:
        Type: String
        Default: 12
      Env:
        Type: String
        Default: dev
        
    Resources:
      Ec2StartRule:
        Type: AWS::Events::Rule
        Properties:
          Name: !Sub ec2-start-${Env}
          Description: ScheduledRule
          ScheduleExpression: !Sub "cron(0 ${StartHour} * * ? *)"
          State: ENABLED
          RoleArn: !GetAtt Ec2StartStopRole.Arn
          Targets:
          - Arn: "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StartEC2Instance:$DEFAULT"
            Id: StartEc2
            RoleArn: !GetAtt Ec2StartStopRole.Arn
            Input: !Sub '{"InstanceId":${InstanceName}}'
      Ec2StopRule:
        Type: AWS::Events::Rule
        Properties:
          Name: !Sub ec2-stop-${Env}
          Description: ScheduledRule
          ScheduleExpression: !Sub "cron(0 ${StopHour} * * ? *)"
          State: ENABLED
          RoleArn: !GetAtt Ec2StartStopRole.Arn
          Targets:
          - Arn: "arn:aws:ssm:ap-northeast-1::automation-definition/AWS-StopEC2Instance:$DEFAULT"
            Id: StopEc2
            RoleArn: !GetAtt Ec2StartStopRole.Arn
            Input: !Sub '{"InstanceId":${InstanceName}}'
      Ec2StartStopRole:
        Type: AWS::IAM::Role
        Properties: 
          RoleName: !Sub ec2-start-stop-${Env}
          AssumeRolePolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Principal:
                  Service:
                    - "events.amazonaws.com"
                    - "ec2.amazonaws.com"
                Action: "sts:AssumeRole"
          Description:
            Describe what you want
          Policies: 
            - PolicyName: Ec2StartStopPolicy
              PolicyDocument:
                Version: '2012-10-17'
                Statement:
                  - Effect: Allow
                    Action: "lambda:InvokeFunction"
                    Resource: "arn:aws:lambda:*:*:function:Automation*"
                  - Effect: Allow
                    Action:
                      - "ec2:StartInstances"
                      - "ec2:RebootInstances"
                      - "ec2:StopInstances"
                      - "ec2:TerminateInstancesInstances"
                    Resource: "*"
                  - Effect: Allow
                    Action: "ssm:*"
                    Resource: "*"
    

    実行コマンド

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    template_name="ec2-start-stop"
    packaged_name="./packaged.yaml"
    stack_name="ec2-start-stop"
    bucket_name=バケット名
    #例param='InstanceName=["i-xxxxxxxxxxx","i-xxxxxxxxxxx"] StartHour=0 StopHour=12'
    param='InstanceName=[インスタンスIDのリスト] StartHour=起動時間 StopHour=停止時間'
    
    aws cloudformation package --template-file ./template-$template_name.yaml --s3-bucket $bucket_name --output-template-file $packaged_name
    aws cloudformation deploy --template-file $packaged_name --stack-name $stack_name --capabilities CAPABILITY_NAMED_IAM --parameter-overrides $param
    

    独り言

    色々とこだわりました。

    cloud watch eventにEC2のストップというがあるのですが、それだと1targetで1インスタンスまでしか同時に処理できないので、複数イベント設定したりしなきゃいけない

    (5targetまでは1イベントに設定できるので、まとめたりはできなくはないのですが、5target書くのも微妙で…)

    なので、起動と合わせて、ssmのイベントにしてみたり、そもそもlambdaを使わずに頑張ってみたりと。

    なかなか大変でしたが、とても学びのあるトライでしたw

    またこういうのちゃんとやってみたいです//


    るな
    るな
    エンジニア