とりあえずできたので書き出し
そのうち図を書き足します
概要
平日の業務時間中だけサーバを使いたい。さらにNATゲートウェイも使わないので止めたい。
という貧乏な人コスト意識の高い方向けテンプレート
このテンプレートは
NATGWとSSM DocumentとEventBridgeを作るもの
NATGW: テンプレートの起動パラメータによって、作成・削除ができる
SSM Document: このテンプレートで作成したCFn Stackの更新(NATの作成削除を実行)できる
EventBridge: スケジュールでSSM Documentを実行する
起動パラメータ
- NATGW 作成フラグ
- メール通知送信先アドレス
- NATGWを配置するパブリックサブネット
- NATGWを経路にするプライベートサブネットのルートテーブル
作成するリソース
リソース | 内容 |
---|---|
NatGateway | フラグtrueの時のみ作成 |
EIP | フラグtrueの時のみ作成:NAT Gateway用EIP |
Route | フラグtrueの時のみ作成:NAT Gatewayのルート |
IAM::Role | SSM Document用のIAMロール |
SNS::Topic | SSM Automationで使用、終了通知用 |
SSM::Document | SSM Document |
IAM::Role | EventBridge用のIAMロール |
Events::Rule | 起動用スケジュール |
Events::Rule | 終了用スケジュール |
←(ここをクリックすると展開) CFnテンプレ全体はこちら
詳細
1,パラメータ
Parameters:
CreateNAT:
Type: String
AllowedValues: [true, false]
MailTo:
Type: String
PublicSubnetID:
Type: String
PrivateRouteTableID:
Type: String
Conditions:
isCreateNAT: !Equals [!Ref CreateNAT, "true"]
2,NAT Gateway
NAT:
Type: AWS::EC2::NatGateway
Condition: isCreateNAT
Properties:
AllocationId: !GetAtt
- NatGatewayEIP
- AllocationId
SubnetId: !Ref PublicSubnetID
NatGatewayEIP:
Type: AWS::EC2::EIP
Condition: isCreateNAT
Properties:
Domain: vpc
PrivateRouteNAT:
Type: AWS::EC2::Route
Condition: isCreateNAT
Properties:
RouteTableId: !Ref PrivateRouteTableID
NatGatewayId: !Ref NAT
DestinationCidrBlock: "0.0.0.0/0"
3,SSM Document
3-1, Role
AutomationAssumeRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub 'Role-automation-${AWS::StackName}'
Path: "/"
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ssm.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole
Policies:
- PolicyName: inline
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- cloudformation:UpdateStack
- sns:Publish
- ec2:*
- tag:GetResources
Resource:
- "*"
- 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: iam:PassRole
Resource:
- !Sub "arn:aws:iam::${AWS::AccountId}:role/Role-automation-${AWS::StackName}"
Condition:
StringLikeIfExists:
iam:PassedToService: ssm.amazonaws.com
3-2, SNS Topic
SNSTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub "SampleTopic-${AWS::StackName}"
Subscription:
- Endpoint: !Ref MailTo
Protocol: email
3-3, SSM Document
SSMDocumentStartStopResorces:
Type: AWS::SSM::Document
Properties:
DocumentFormat: YAML
DocumentType: Automation
Content:
schemaVersion: "0.3"
description: CovProject Remove NATGateway and Start/Stop EC2 Instances(byTag)
assumeRole: !GetAtt AutomationAssumeRole.Arn
parameters:
createFlg:
type: String
default: "ture"
description: true is Create NAT and Start EC2Instance / false is Remove NAT and Stop EC2Instance
allowedValues:
- "true"
- "false"
mainSteps:
- name: UpdateCFnStack
action: aws:executeAwsApi
inputs:
Service: cloudformation
Api: update_stack
StackName: !Ref AWS::StackName
UsePreviousTemplate: true
Parameters:
- ParameterKey: CreateNAT
ParameterValue: "{{ createFlg }}"
- ParameterKey: MailTo
UsePreviousValue: True
- ParameterKey: PublicSubnetID
UsePreviousValue: True
- ParameterKey: PrivateRouteTableID
UsePreviousValue: True
Capabilities:
- CAPABILITY_NAMED_IAM
outputs:
- Name: stackId
Selector: $.StackId
Type: String
- name: WaitCFnStack
action: aws:waitForAwsResourceProperty
timeoutSeconds: 300
inputs:
Service: cloudformation
Api: DescribeStacks
StackName: "{{ UpdateCFnStack.stackId }}"
PropertySelector: Stacks[0].StackStatus
DesiredValues:
- UPDATE_COMPLETE
- name: CheckIsStart
action: aws:branch
inputs:
Choices:
- NextStep: StopEC2
Variable: "{{ createFlg }}"
StringEquals: "false"
- name: StartEC2
action: aws:executeAwsApi
inputs:
Service: ssm
Api: StartAutomationExecution
DocumentName: AWS-StartEC2Instance
TargetParameterName: "InstanceId"
Targets:
-
Key: tag:AutoStop
Values:
- 'true'
- name: StartCompletionNotice
action: aws:executeAwsApi
inputs:
Service: sns
Api: Publish
TopicArn: !Ref SNSTopic
Message: 'Message'
Subject: 'subject Start'
isEnd: true
- name: StopEC2
action: aws:executeAwsApi
inputs:
Service: ssm
Api: StartAutomationExecution
DocumentName: AWS-StopEC2Instance
TargetParameterName: "InstanceId"
Targets:
-
Key: tag:AutoStop
Values:
- 'true'
- name: StopCompletionNotice
action: aws:executeAwsApi
inputs:
Service: sns
Api: Publish
TopicArn: !Ref SNSTopic
Message: 'Message'
Subject: 'subject Stop'
isEnd: true
4,EventBridge
4-1, Role
EventBridgeRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub 'Role-events-${AWS::StackName}'
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "events.amazonaws.com"
Action: sts:AssumeRole
Path: /
Policies:
- PolicyName: StopEc2Role_policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: ssm:StartAutomationExecution
Resource: !Sub "arn:aws:ssm:ap-northeast-1:${AWS::AccountId}:automation-definition/${SSMDocumentStartStopResorces}:$DEFAULT"
4-2, EventBridge
EventRuleEc2Start:
Type: AWS::Events::Rule
Properties:
Name: !Sub "${AWS::StackName}StartRule"
Description: !Sub "${AWS::StackName} Start."
ScheduleExpression: "cron(00 23 ? * SUN-THU *)"
State: ENABLED
Targets:
- Arn: !Sub "arn:aws:ssm:ap-northeast-1:${AWS::AccountId}:automation-definition/${SSMDocumentStartStopResorces}:$DEFAULT"
Id: TargetStartCov
RoleArn: !GetAtt EventBridgeRole.Arn
Input: "{\"createFlg\":[\"true\"]}"
EventRuleEc2Stop:
Type: AWS::Events::Rule
Properties:
Name: !Sub "${AWS::StackName}StopRule"
Description: !Sub "${AWS::StackName} Stop."
ScheduleExpression: "cron(00 11 ? * MON-FRI *)"
State: ENABLED
Targets:
- Arn: !Sub "arn:aws:ssm:ap-northeast-1:${AWS::AccountId}:automation-definition/${SSMDocumentStartStopResorces}:$DEFAULT"
Id: TargetStopCov
RoleArn: !GetAtt EventBridgeRole.Arn
Input: "{\"createFlg\":[\"false\"]}"