Lambda 関数を利用して EC2 Auto Scaling グループの、最小の希望する容量が 0 になったことをトリガーに SNS 通知するように実装してみた
はじめに
テクニカルサポートの 片方 です。
今回は Lambda 関数を利用して EC2 Auto Scaling グループの、最小の希望する容量が 0 になったことをトリガーに SNS から通知する仕組みを実装してみました。
実装してみた
以下の順番で実装します。
- SNS 作成
- 実行ロール作成
- Lambda 関数作成
EC2 Auto Scaling の作成については省かせていただきます。弊社ブログを参考に作成してください。
SNS
通知機能として SNS を利用します。SNS トピックおよびサブスクリプションを作成します。
Protocol (プロトコル) として Email (E メール) を選択して作成しました。後に arn が必要なので控えます。
実行ロール
信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
アタッチするポリシー例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:${AWS_REGION}:${ACCOUNT_ID}:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:${AWS_REGION}:${ACCOUNT_ID}:log-group:/aws/lambda/${FUNCTION_NAME}:*"
]
},
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingGroups"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": "arn:aws:sns:${AWS_REGION}:${ACCOUNT_ID}:*"
}
]
}
※ 適宜修正してください。
Lambda 関数
Python 3.13 で作成しました。
実行ロールでは、既存のロールを使用するを選択し、先ほど作成したロールを指定します。
Lambda 関数例
import os
import boto3
import json
from datetime import datetime
def lambda_handler(event, context):
# 環境変数から設定を取得
asg_name = os.environ['ASG_NAME']
sns_topic_arn = os.environ['SNS_TOPIC_ARN']
try:
# Auto Scalingクライアントの初期化
autoscaling = boto3.client('autoscaling')
# Auto Scalingグループの情報を取得
response = autoscaling.describe_auto_scaling_groups(
AutoScalingGroupNames=[asg_name]
)
# Auto Scalingグループが存在しない場合のエラーハンドリング
if not response['AutoScalingGroups']:
raise Exception(f"Auto Scaling Group '{asg_name}' not found")
asg = response['AutoScalingGroups'][0]
min_size = asg['MinSize']
# MinSizeが0の場合、SNS通知を送信
if min_size == 0:
sns = boto3.client('sns')
# 通知メッセージの作成
message = {
'timestamp': datetime.now().isoformat(),
'asg_name': asg_name,
'alert': 'Auto Scaling Group MinSize is set to 0',
'current_min_size': min_size,
'current_desired_capacity': asg['DesiredCapacity'],
'current_max_size': asg['MaxSize']
}
# SNS通知の送信
sns.publish(
TopicArn=sns_topic_arn,
Subject=f"Alert: {asg_name} MinSize is 0",
Message=json.dumps(message, indent=2)
)
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Alert sent successfully',
'asg_name': asg_name,
'min_size': min_size
})
}
# MinSizeが0でない場合
return {
'statusCode': 200,
'body': json.dumps({
'message': 'ASG MinSize is not 0',
'asg_name': asg_name,
'min_size': min_size
})
}
except Exception as e:
# エラーハンドリング
error_message = str(e)
print(f"Error: {error_message}")
return {
'statusCode': 500,
'body': json.dumps({
'error': error_message
})
}
環境変数を利用しているため、作成している EC2 Auto Scaling グループ名と、SNS トピック arn を記載ください。
- ASG_NAME: Auto Scaling グループの名前
- SNS_TOPIC_ARN: 通知先 SNS トピック ARN
※ 適宜修正してください。
検証してみた
最小の希望する容量が 2 の状況です。
作成した、Lambda 関数をテストします!成功です。
しかしながら、最小の希望する容量が 0 ではないので、SNS からの通知は発生しません。
では、最小の希望する容量が 0 の状態でテストします。
こちらも、問題なく成功しました!
では、通知内容を確認します。
成功です!
まとめ
EventBridge のスケジュール機能を利用して、当該 Lambda 関数を定期実行させるなど合わせてご検討ください。
また、本ブログでは最小の希望する容量を監視対象にしていますが、"希望するキャパシティ" や "最大の希望する容量" などご自身の環境に合わせて使用することも良いと思います。本ブログが誰かの参考になれば幸いです。
ルールは、イベントに応じて実行したり、一定の時間間隔で実行したりすることができます。例えば、AWS Lambda 関数を定期的に実行するには、スケジュールに従って実行するルールを作成します。
参考資料
- [初心者向け]EC2 Auto Scaling グループを作成する | DevelopersIO
- Amazon SNS トピックの作成とメッセージの発行 - Amazon Simple Notification Service
- AutoScaling - Boto3 1.36.14 documentation
- Amazon EventBridge でスケジュールに従って実行するルールの作成 - Amazon EventBridge
アノテーション株式会社について
アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、様々な背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。