EC2とRDSを自動起動停止する設定をCloudformationで設定してみた

## 設定内容
まずは設定した内容をザっと張り付けておきます。
下に主要な設定部分を説明します。
```yaml:EC2-RDS_AutoStop-Start.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Schedule EC2 instances start and stop using EventBridge Scheduler

Parameters:
  InstanceIds:
    Type: CommaDelimitedList
    Description: List of EC2 Instance IDs to be started and stopped.

Resources:
  SchedulerAutoStopStartRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: <ロール名>
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: 
                - scheduler.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: <ポリシー名>
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action: 
                  - ec2:StopInstances
                  - ec2:StartInstances
                  - rds:StopDBInstances
                  - rds:StartDBInstances
                  - rds:CreateDBSnapshot
                  - rds:AddTagsToResource
                Resource: "*"

  StopInstanceScheduler:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: <スケジュール名１>
      FlexibleTimeWindow:
        Mode: "OFF"
      ScheduleExpression: "cron(0 22 ? * MON-FRI *)"
      ScheduleExpressionTimezone: Japan
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances
        RoleArn: !GetAtt SchedulerAutoStopStartRole.Arn
        Input: !Sub '{"InstanceIds": ["<インスタンスID>", "<インスタンスID>"]}'

  StartInstanceScheduler:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: <スケジュール名２>
      FlexibleTimeWindow:
        Mode: "OFF"
      ScheduleExpression: "cron(0 9 ? * MON-FRI *)"
      ScheduleExpressionTimezone: Japan
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:ec2:startInstances
        RoleArn: !GetAtt SchedulerAutoStopStartRole.Arn
        Input: !Sub '{"InstanceIds": ["<インスタンスID>", "<インスタンスID>"]}'

  StopRDSScheduler:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: <スケジュール名３>
      FlexibleTimeWindow:
        Mode: "OFF"
      ScheduleExpression: "cron(0 22 ? * MON-FRI *)"
      ScheduleExpressionTimezone: Japan
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:rds:stopDBInstance
        RoleArn: !GetAtt SchedulerAutoStopStartRole.Arn
        Input: !Sub '{"DbInstanceIdentifier": "<RDS名>"}'

  StartRDSScheduler:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: <スケジュール名４>
      FlexibleTimeWindow:
        Mode: "OFF"
      ScheduleExpression: "cron(0 9 ? * MON-FRI *)"
      ScheduleExpressionTimezone: Japan
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:rds:startDBInstance
        RoleArn: !GetAtt SchedulerAutoStopStartRole.Arn
        Input: !Sub '{"DbInstanceIdentifier": "<RDS名>"}'
```
まずは、EventBridgeで使用するための権限を作成してます。
```yaml:
Resources:
  SchedulerAutoStopStartRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: <ロール名>
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: 
                - scheduler.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: <ポリシー名>
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action: 
                  - ec2:StopInstances
                  - ec2:StartInstances
                  - rds:StopDBInstances
                  - rds:StartDBInstances
                  - rds:CreateDBSnapshot
                  - rds:AddTagsToResource
                Resource: "*"
```
「**RoleName、PolicyName**」は自由です。
今回はEC2とRDSの両方を停止起動するスケジュールを作成しますが、同じロールを使用するためEC2とRDSの両方のポリシーを設定しています。
続いて、EC2の停止起動のスケジュールを設定してます。
```yaml:
StopInstanceScheduler:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: <スケジュール名１>
      FlexibleTimeWindow:
        Mode: "OFF"
      ScheduleExpression: "cron(0 22 ? * MON-FRI *)"
      ScheduleExpressionTimezone: Japan
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances
        RoleArn: !GetAtt SchedulerAutoStopStartRole.Arn
        Input: !Sub '{"InstanceIds": ["<インスタンスID>", "<インスタンスID>"]}'

  StartInstanceScheduler:
    Type: AWS::Scheduler::Schedule
    Properties:
      Name: <スケジュール名２>
      FlexibleTimeWindow:
        Mode: "OFF"
      ScheduleExpression: "cron(0 9 ? * MON-FRI *)"
      ScheduleExpressionTimezone: Japan
      State: ENABLED
      Target:
        Arn: arn:aws:scheduler:::aws-sdk:ec2:startInstances
        RoleArn: !GetAtt SchedulerAutoStopStartRole.Arn
        Input: !Sub '{"InstanceIds": ["<インスタンスID>", "<インスタンスID>"]}'
```
「**Name**」は自由です
「**ScheduleExpression**」で動かす時間を定義しています。
今回は「**cron(0 22 ? * MON-FRI *)**」としており、月曜～金曜までの22時に停止としています。
停止の定義は「**Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances**」という箇所で、
EventBridgeが使うAPIとして「**stopInstances**」を指定することでEC2が停止してくれます。
次に「**RoleArn**」で「**SchedulerAutoStopStartRole.Arn**」を定義しています。
コード内でIAMロールのリソース名として**SchedulerAutoStopStartRole**と定義していて、IAMロールのARNを使うため、語尾に「.Arn」と付けています。
最後に「**Input**」にどのEC2を停止したいかをインスタンス名で指定しています。今回は複数指定してますが、単体でも複数でも可能です。
「**StartInstanceScheduler**」も要領は同じです。
起動したい時間帯を「**ScheduleExpression**」に定義し、「**Arn**」で指定するAPIを「**tartInstances**」にして下さい。

RDSもほとんど一緒のため割愛します。
「**Input**」で指定する値が、DBインスタンスIDであるということだけ注意してください。

以上！！