何がしたいのか
AutoScalingでEC2が増えたり減ったりしたとき、CloudWatch EventでSSM Automationを実行して自動的にAlarmを作成したり削除したりする。
ちなみにSSM AutomationではなくてLambdaを使ったほうが何かと便利1なので、この記事は何らかの事情でLambdaを使いたくない人向けかも。
使用するサービス
- Cloud Watch Alarm
- Cloud Watch Events
- SSM Automation(Systems Manager Automation)
- EC2 AutoScaling
- Cloudformation
全体の流れなど
- AutoScalingによりEC2 Instanceが作成または削除される
- CloudWatch Eventがそれらを検知し、Targetに設定しておいたSSM Automationを実行
- Automationに指定されたパラメータによって、Alarmを作成するか削除するか分岐
また、Cloudformation削除時にAlarmもきちんと削除されるようになっている
Cloudformation Template 一部解説
全体はnsk917/ec2-a3に置いておきました。
ただ、Alarmのステータスが変わったときにSNSへメッセージを飛ばすような設定は省いてます。
以下、Templateを抜粋して少々解説をコメントで記載。
CloudWatch Events
各イベントのサンプルは下記URLを参考
Auto Scaling グループスケーリング時の CloudWatch イベント の取得
template.yaml
PutDeleteAlarmEventRule:
Type: AWS::Events::Rule
DependsOn: SSMAutomationCPUAlarm
Properties:
Description: Put and Delete Alarm
State: ENABLED
EventPattern:
source:
- aws.autoscaling
# どのAutoScalingGroupからのEventなのかを指定する
# 本来なら !Ref を使いたいところではあるが、AutoScalingGroupと循環参照になってしまうため下記のようにしている
detail:
AutoScalingGroupName:
- EC2-A3-AutoScalingGroup
# AutoScalingからのeventのdetail-typeのうち、
# 以下を使ってEC2が起動/削除されたときにAutomationを実行させる
detail-type:
- 'EC2 Instance Launch Successful'
- 'EC2 Instance Terminate Successful'
Targets:
- Id: SSMAutomationCPUAlarm
Arn: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${SSMAutomationCPUAlarm}'
RoleArn: !GetAtt CWEventsExecuteAutomationRole.Arn
InputTransformer:
InputPathsMap:
DetailType: '$.detail-type'
EC2InstanceId: '$.detail.EC2InstanceId'
InputTemplate: '{ "DetailType":[<DetailType>], "EC2InstanceId":[<EC2InstanceId>] }'
SSM Automation
一応マネジメントコンソールから手動実行も可能。
この点はLambdaよりはやりやすいだろうけど、自動化されているのでメリットはあんまりない。
Systems Manager Automation アクションのリファレンス
template.yaml
SSMAutomationCPUAlarm:
Type: AWS::SSM::Document
Properties:
DocumentType: Automation
Content:
schemaVersion: '0.3'
description: Put or Delete Alarm. EC2 High CPU Utilization
parameters:
DetailType:
type: String
description: 'EC2 Instance Launch Successful|EC2 Instance Terminate Successful'
allowedPattern: 'EC2 Instance Launch Successful|EC2 Instance Terminate Successful'
EC2InstanceId:
type: String
description: EC2 Instance Id
AlarmNamePrefix:
type: String
description: High CPU Alarm Name Prefix
default: High CPU Utilization Alarm
mainSteps:
# DetailTypeで振る舞いを分岐させるAction
- name: BranchPutAlarmOrDeleteAlarm
action: aws:branch
inputs:
Choices:
- NextStep: PutAlarm
Variable: '{{ DetailType }}'
StringEquals: 'EC2 Instance Launch Successful'
- NextStep: DeleteAlarm
Variable: '{{ DetailType }}'
StringEquals: 'EC2 Instance Terminate Successful'
# 上記のChoicesに当てはまらない場合に実行されるAction
# これがないと次のActionが実行されてしまうので、強制的に終了させるActionを指定する
Default: DoNothing
(以下略)
- name: DoNothing
action: aws:sleep
isEnd: true
inputs:
Duration: PT1S
AutoScalingGroup
template.yaml
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
# このDependsOnを記述しておくことで、Cloudformationを雑に削除してもAlarmが残り続けたりしないようになっている。
DependsOn: PutDeleteAlarmEventRule
Properties:
AutoScalingGroupName: EC2-A3-AutoScalingGroup
DesiredCapacity: !Ref Min
HealthCheckGracePeriod: 60
HealthCheckType: EC2
LaunchConfigurationName: !Ref LaunchConfiguration
MinSize: !Ref Min
MaxSize: !Ref Max
VPCZoneIdentifier:
- !Ref SubnetId
UpdatePolicy:
AutoScalingRollingUpdate:
MinInstancesInService: 1
MaxBatchSize: 1
PauseTime: PT0S
参考URL
(小ネタ) AutoScaling で増減した EC2 インスタンスに動的に CloudWatch Alarm を設定
Auto Scaling に対応した EC2 監視アラーム設定ツール2