🛑
AWS CloudFormation で SSM Automation を利用したインスタンス停止処理
はじめに
以前、AWS CloudFormation で踏み台サーバー構築という記事を書きました。
このような踏み台サーバーなどを EC2 で作った場合は、夜間など未利用の時間は止めたくなることが多くあります。
今回は SSM Automation
を利用してインスタンスを自動で起動/停止する CloudFormation テンプレートを紹介します。
EC2 の夜間停止用テンプレート
EC2 の夜間停止用テンプレート
AWSTemplateFormatVersion: 2010-09-09
Description: Rules for starting and stopping EC2 using SSM Automation
# Rules for starting and stopping EC2 using SSM Automation
Parameters:
TargetEC2Id:
Description: Target EC2 ID
Type: String
Default: i-XXXXXXXXXXXXXXXXX
Resources:
# SSM Automation EC2 起動/停止用 IAM ロール
InstanceMaintenanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${TargetEC2Id}-maintenance
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ssm.amazonaws.com
Action: sts:AssumeRole
# ManagedPolicyArns:
Policies:
- PolicyName: AllowAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- ec2:StartInstances
- ec2:StopInstances
Resource: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/${TargetEC2Id}
- Effect: Allow
Action: ec2:DescribeInstanceStatus
Resource: '*'
# SSM Automation 実行 EventBridge 用 IAM ロール
InstanceMaintenanceEventRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${TargetEC2Id}-maintenance-event
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: AllowAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ssm:StartAutomationExecution
Resource:
- !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StartEC2Instance:*
- !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StopEC2Instance:*
- Effect: Allow
Action: iam:PassRole
Resource: !GetAtt InstanceMaintenanceRole.Arn
Condition:
StringLikeIfExists:
iam:PassedToService: ssm.amazonaws.com
# SSM Automation 実行 EventBridge ルール
InstanceStartEventsRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${TargetEC2Id}-start-instance
Description: !Sub Start EC2(${TargetEC2Id}) instance
ScheduleExpression: cron(55 23 ? * 1-5 *) # UTC Cron 式, JST 平日 8:55 起動, 1:Sun-7:Sat
State: ENABLED
Targets:
- Arn: !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StartEC2Instance:$DEFAULT
Id: start-instance
RoleArn: !GetAtt InstanceMaintenanceEventRole.Arn
Input: !Sub
- |
{
"InstanceId": [ "${TargetEC2Id}" ],
"AutomationAssumeRole": [ "${AutomationAssumeRole}" ]
}
- AutomationAssumeRole: !GetAtt InstanceMaintenanceRole.Arn
InstanceStopEventsRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${TargetEC2Id}-stop-instance
Description: !Sub Stop EC2(${TargetEC2Id}) instance
ScheduleExpression: cron(5 9 ? * * *) # UTC Cron 式, JST 毎日 18:05 停止
State: ENABLED
Targets:
- Arn: !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StopEC2Instance:$DEFAULT
Id: stop-instance
RoleArn: !GetAtt InstanceMaintenanceEventRole.Arn
Input: !Sub
- |
{
"InstanceId": [ "${TargetEC2Id}" ],
"AutomationAssumeRole": [ "${AutomationAssumeRole}" ]
}
- AutomationAssumeRole: !GetAtt InstanceMaintenanceRole.Arn
以降、テンプレート内容を補足します。
パラメーター
-
TargetEC2Id
: 夜間停止をする EC2 の IDi-XXXXXXXXXXXXXXXXX
を指定してください
EC2 起動/停止用ロール
EC2 の起動/停止を行うためのロールを作成します。
同一テンプレートを使いまわした際のロール名の重複を避けるため、ロール名にインスタンス ID を含むようにしています。
# SSM Automation EC2 起動/停止用 IAM ロール
InstanceMaintenanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${TargetEC2Id}-maintenance
指定した EC2 のみ起動/停止できるように対象リソースを絞り込んでいます。
- Effect: Allow
Action:
- ec2:StartInstances
- ec2:StopInstances
Resource: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/${TargetEC2Id}
SSM Automation 実行 EventBridge 用ロール
EventBridge
のルールを利用して、 SSM Automation
を実行するためのロールを作成します。
# SSM Automation 実行 EventBridge 用 IAM ロール
InstanceMaintenanceEventRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${TargetEC2Id}-maintenance-event
EC2 起動用 SSM Automation 実行 EventBridge ルール
SSM Automation
を EventBridge
から呼び出します。
平日の8:55に起動するように Cron 式で指定しています。
時間は業務に合わせて適宜修正ください。
# SSM Automation 実行 EventBridge ルール
InstanceStartEventsRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${TargetEC2Id}-start-instance
Description: !Sub Start EC2(${TargetEC2Id}) instance
ScheduleExpression: cron(55 23 ? * 1-5 *) # UTC Cron 式, JST 平日 8:55 起動, 1:Sun-7:Sat
EC2 停止用 SSM Automation 実行 EventBridge ルール
停止は毎日行うようにしています。
こちらも業務に合わせて適宜修正ください。
InstanceStopEventsRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${TargetEC2Id}-stop-instance
Description: !Sub Stop EC2(${TargetEC2Id}) instance
ScheduleExpression: cron(5 9 ? * * *) # UTC Cron 式, JST 毎日 18:05 停止
RDS インスタンスの夜間停止用テンプレート
RDS のインスタンス用です。
RDS クラスターを停止する場合は、RDS クラスター用の SSM Automation
に書き換える必要があるため注意ください。
RDS インスタンスの夜間停止用テンプレート
AWSTemplateFormatVersion: 2010-09-09
Description: Rules for starting and stopping RDS using SSM Automation
# Rules for starting and stopping RDS using SSM Automation
Parameters:
RoleName:
Description: DB maintenance event role name
Type: String
TargetDBInstanceID:
Description: Target DB Instance ID
Type: String
Resources:
# SSM Automation RDS 起動/停止用 IAM ロール
InstanceMaintenanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${RoleName}-maintenance
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ssm.amazonaws.com
Action: sts:AssumeRole
# ManagedPolicyArns:
Policies:
- PolicyName: AllowAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- rds:StopDBInstance
- rds:StartDBInstance
Resource: !Sub arn:aws:rds:${AWS::Region}:${AWS::AccountId}:db:${TargetDBInstanceID}
- Effect: Allow
Action: rds:DescribeDBInstances
Resource: '*'
# SSM Automation 実行 EventBridge 用 IAM ロール
InstanceMaintenanceEventRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${RoleName}-db-maintenance-event
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: AllowAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ssm:StartAutomationExecution
Resource:
- !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StartRdsInstance:*
- !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StopRdsInstance:*
- Effect: Allow
Action: iam:PassRole
Resource: !GetAtt InstanceMaintenanceRole.Arn
Condition:
StringLikeIfExists:
iam:PassedToService: ssm.amazonaws.com
# SSM Automation 実行 EventBridge ルール
InstanceStartEventsRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${RoleName}-start-rds-instance
Description: !Sub Start DB(${TargetDBInstanceID}) instance
ScheduleExpression: cron(35 23 ? * 1-5 *) # UTC Cron 式, JST 平日 8:35 起動, 1:Sun-7:Sat
State: ENABLED
Targets:
- Arn: !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StartRdsInstance:$DEFAULT
Id: start-rds-instance
RoleArn: !GetAtt InstanceMaintenanceEventRole.Arn
Input: !Sub
- |
{
"InstanceId": [ "${TargetDBInstanceID}" ],
"AutomationAssumeRole": [ "${AutomationAssumeRole}" ]
}
- AutomationAssumeRole: !GetAtt InstanceMaintenanceRole.Arn
InstanceStopEventsRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub ${RoleName}-stop-rds-instance
Description: !Sub Stop DB(${TargetDBInstanceID}) instance
ScheduleExpression: cron(35 9 ? * * *) # UTC Cron 式, JST 毎日 18:35 停止
State: ENABLED
Targets:
- Arn: !Sub arn:aws:ssm:${AWS::Region}::automation-definition/AWS-StopRdsInstance:$DEFAULT
Id: stop-rds-instance
RoleArn: !GetAtt InstanceMaintenanceEventRole.Arn
Input: !Sub
- |
{
"InstanceId": [ "${TargetDBInstanceID}" ],
"AutomationAssumeRole": [ "${AutomationAssumeRole}" ]
}
- AutomationAssumeRole: !GetAtt InstanceMaintenanceRole.Arn
以降、 EC2 と異なる点の補足をします。
パラメーター
-
RoleName
: RDS 起動/停止用のロール名を指定します- EC2 のようにロール名にインスタンス ID を利用すると64文字の制限に収まらないため明示的に指定します
-
TargetDBInstanceID
: 夜間停止をする RDS の DB インスタンス ID を指定してください
さいごに
EC2 や RDS のインスタンスを自動で起動/停止する CloudFormation テンプレートの紹介でした。
昔は Lambda で行うことが多かったのですが、今は SSM Automation
に準備されているタスクも多いため、オートメーションを活用して運用を簡素化したいと思います。
Discussion