クラウドインテグレーション事業部の林です。
今回はLCU(ロードバランサーキャパシティユニット) 予約を予定時刻に事前に設定できるよう以下サービスを利用し実装してみましたのでご紹介します。
・AWS Lambda
・Amazon EventBridge
・Amazon Q Developer in chat applications (旧称: AWS Chatbot)
・Amazon SNS
背景
以前はELBで急激なアクセス増加が見込まれる場合、事前にAWSサポートへサポートケースを作成の上、暖気申請を行う必要がありました。
しかしながら、現在は Load Balancer Capacity Unit Reservation (LCU 予約) 機能をご利用いただくことで、AWS サポートにご依頼いただかずとも、ユーザー自身でLCU 予約を実施することで事前にスケールさせることが可能となりました。
|
しかし、AWSサポートを利用した暖機申請(Pre-warming) と異なり期間指定でスケールさせることはできず、
期間を指定する必要がある場合、 EventBridge Scheduler & Lambda 等を利用した構成を検討しなければならない状況です。
事前準備
ロードバランサーキャパシティユニット (LCU) 予約機能を利用するにあたり、
アカウントのService Quotasにてクォータ “Reserved Application Load Balancer Capacity Units (LCU) per Region”の引き上げを事前に行なっておく必要があります。
Service Quotasのサービス画面から該当のクォータが今回の設定するLCU予約数を満たしているかどうか事前に確認してください。
クォータ申請を過去一度も行なってない場合はデフォルトの0になっているため、Service Quotasよりクォータの引き上げ申請を行なってください。
また、記事執筆時点ではLCU 予約の際は最低100LCUの設定が必要となります。
LCU予約設定自動化作業概要
今回の設定作業の目的としてはEventBridgeにてLCU予約設定を事前に設定しておき、予約時間になったらあらかじめ設定していたLCU数でLCU予約を自動的に設定されるように実装することです。
また、LCU予約設定が正常に設定されたかどうかもチームで確認を行いたかったため、Slackで正常に設定されたかどうかの結果を確認できるよう、Amazon SNS と Amazon Q Developer in chat applications (旧称: AWS Chatbot)を使用し、Amazon Q アプリ経由で通知するようにも設定しました。
それでは、作業手順について説明していこうと思います!
1.IAMにてLCU用ポリシー作成
まず、IAM→ポリシー→ポリシーの作成→JSONで作成にて以下のポリシーを作成します。
※SNSに結果を送信するためsns:Publishの権限も追加
※ポリシー名は任意になりますが、今回はLCUPolicyと命名しました。
{ “Version”: “2012-10-17”, “Statement”: [ { “Effect”: “Allow”, “Action”: [ “elasticloadbalancing:ModifyCapacityReservation”, “sns:Publish” ], “Resource”: “*” } ] } |
Lambda作成
以下内容でLambda関数作成しました。
関数の作成 | 一から作成 |
関数名 | Capacity_reservations_for_Application-Load-Balancer |
ランタイム | Python 3.13 |
実行ロール | 基本的な Lambda アクセス権限で新しいロールを作成 |
アーキテクチャ | x86_64 |
サンプルコードとしては以下を使用し、正常にLCU予約が実行されたか実行結果をSlackで通知するように設定しました。
また、チーム内でLCU予約が実行されたか通知を確認したいため、Slackのチームメンバー全員のメンション先であるグループIDを指定するようにしました。
import boto3
import json
import os# SNSトピックのARNを環境変数から取得
SNS_TOPIC_ARN = os.environ.get(‘SNS_TOPIC_ARN’)def lambda_handler(event, context):
sns_client = boto3.client(‘sns’)
elbv2_client = boto3.client(‘elbv2’)# 1. イベントから必須パラメータを取得
try:
load_balancer_arn = event[‘load_balancer_arn’]
capacity_units = int(event[‘capacity_units’])
except KeyError as e:
print(f”エラー: 必須パラメータ {str(e)} がイベントに含まれていません。”)
raise# 2. 予約・変更か、解除かを判定
is_cancel_action = capacity_units < 100
action_description = “解除” if is_cancel_action else “予約”# 3. メンション文字列を準備(グループIDを指定)
mention_text = “ ”try:
# 4. LCUの予約または解除を実行
if not is_cancel_action:
# LCUを予約・変更する場合 (100以上)
elbv2_client.modify_capacity_reservation(
LoadBalancerArn=load_balancer_arn,
MinimumLoadBalancerCapacity={
‘CapacityUnits’: capacity_units
}
)
else:
# LCUを解除する場合 (0など100未満)
elbv2_client.modify_capacity_reservation(
LoadBalancerArn=load_balancer_arn,
ResetCapacityReservation=True
)# — 5. 成功通知の準備 —
subject = f”OK: LCU {action_description} Success”
message_content = {
“version”: “1.0”,
“source”: “custom”,
“content”: {
“title”: f”✅ LCU {action_description} 成功”,
“description”: f”{mention_text}\n\n- **ARN:** `{load_balancer_arn}`\n- **設定LCU数:** `{capacity_units}`”,
“color”: “#28a745″
}
}# SNSにPublish
if SNS_TOPIC_ARN:
sns_client.publish(
TopicArn=SNS_TOPIC_ARN,
Subject=subject,
Message=json.dumps(message_content)
)return {
‘statusCode’: 200,
‘body’: json.dumps({‘message’: f'{action_description}に成功し、Slackに通知しました’})
}except Exception as e:
# — 6. 失敗通知の準備 —
subject = f”ERROR: LCU {action_description} Failed”
message_content = {
“version”: “1.0”,
“source”: “custom”,
“content”: {
“title”: f”🚨 LCU {action_description} 失敗”,
“description”: f”{mention_text}\n\n- **ARN:** `{load_balancer_arn}`\n- **設定LCU数:** `{capacity_units}`\n- **エラー:** `{str(e)}`”,
“color”: “#dc3545”
}
}# SNSにPublish
if SNS_TOPIC_ARN:
sns_client.publish(
TopicArn=SNS_TOPIC_ARN,
Subject=subject,
Message=json.dumps(message_content)
)raise e
もし、個人をメンションしたい場合以下のようなサンプルコードをご準備していただければ通知可能です。
import boto3
import json
import os# SNSトピックのARNを環境変数から取得
SNS_TOPIC_ARN = os.environ.get(‘SNS_TOPIC_ARN’)#【変更点】SlackのメンバーIDを直接指定
SLACK_MENTION_ID = “メンバーID”def lambda_handler(event, context):
sns_client = boto3.client(‘sns’)
elbv2_client = boto3.client(‘elbv2’)try:
load_balancer_arn = event[‘load_balancer_arn’]
capacity_units = int(event[‘capacity_units’])
except KeyError as e:
print(f”エラー: 必須パラメータ {str(e)} がイベントに含まれていません。”)
raiseis_cancel_action = capacity_units < 100
action_description = “解除” if is_cancel_action else “予約”# メンション文字列を準備
mention_text = f”<@{SLACK_MENTION_ID}> ” if SLACK_MENTION_ID else “”try:
if not is_cancel_action:
elbv2_client.modify_capacity_reservation(
LoadBalancerArn=load_balancer_arn,
MinimumLoadBalancerCapacity={‘CapacityUnits’: capacity_units}
)
else:
elbv2_client.modify_capacity_reservation(
LoadBalancerArn=load_balancer_arn,
ResetCapacityReservation=True
)# — 成功通知の準備 —
subject = f”OK: LCU {action_description} Success”
message_content = {
“version”: “1.0”,
“source”: “custom”,
“content”: {
“title”: f”✅ LCU {action_description} 成功”,
“description”: f”{mention_text}\n\n- **ARN:** `{load_balancer_arn}`\n- **設定LCU数:** `{capacity_units}`”,
“color”: “#28a745″
}
}if SNS_TOPIC_ARN:
sns_client.publish(
TopicArn=SNS_TOPIC_ARN,
Subject=subject,
Message=json.dumps(message_content)
)return {
‘statusCode’: 200,
‘body’: json.dumps({‘message’: f'{action_description}に成功し、Slackに通知しました’})
}except Exception as e:
# — 失敗通知の準備 —
subject = f”ERROR: LCU {action_description} Failed”
message_content = {
“version”: “1.0”,
“source”: “custom”,
“content”: {
“title”: f”🚨 LCU {action_description} 失敗”,
“description”: f”{mention_text}\n\n- **ARN:** `{load_balancer_arn}`\n- **設定LCU数:** `{capacity_units}`\n- **エラー:** `{str(e)}`”,
“color”: “#dc3545”
}
}if SNS_TOPIC_ARN:
sns_client.publish(
TopicArn=SNS_TOPIC_ARN,
Subject=subject,
Message=json.dumps(message_content)
)raise e
Lambdaコードのdeployを行いこちらは完了です。
SNSにてトピック作成
1.Amazon SNS→トピックを作成してください。
基本的にデフォルトの設定で問題ありません。
タイプ | スタンダード |
名前 | lcu-reservation-notifications |
表示名 | lcu-reservation-notifications |
暗号化 | オフ |
トピック作成後、Lambdaコードの環境変数項目にて、今回作成したSNSトピックのARNを環境変数として設定します。
Lambda->関数->Capacity_reservations_for_Application-Load-Balancer->設定->環境変数より設定できます。
Amazon Q Developer in chat applications (旧称: AWS Chatbot)
Amazon Qを使用し、Slackとの連携を設定します。
チャットクライアントを設定より、Slackの連携を行ってください。
Slack の認証ページにリダイレクトされ、連携を行うことができます。
連携後、新しいチャネルを設定より、以下内容でチャネルを設定します。(名称やログ設定等は任意で選択してください。)
設定名 | lcu-notification-channel | ||
Amazon CloudWatch Logs にログを発行 | ON (すべてのイベント) | ||
チャネル ID | 通知をしたいチャンネルのチャネル IDを入力 | ||
アクセス許可->ロール設定 | チャネルロール | ||
チャネルロール | テンプレートを使用して IAM ロールを作成する | ||
IAMロール名 | AWSChatbot-role | ||
ポリシーテンプレート |
|
||
チャネルガードレールポリシー | ReadOnlyAccess | ||
通知 – オプション | SNS トピック | ||
SNS トピック | lcu-reservation-notifications |
通知テスト
1.Amazon Q通知アプリの招待を行います。
対象Slackチャンネルにて@Amazon Q にてメンションしアプリを招待できます。
2.Amazon Q Developer in chat applications (旧称: AWS Chatbot)にて設定済みチャネルの設定名:lcu-notification-channelを選択し、テストメッセージを送信を押下します。
Slackに通知が来ていることを確認できれば、Amazon Q Developer in chat applications との連携は問題ないです。
3.SNSトピックへのメッセージの発行を選択し、トピック ARNが正しいことを確認し以下でメッセージの発行を行います。
Slackに通知が来ていることを確認します。
件名 – オプション:test
{ “version”: “1.0”, “source”: “custom”, “content”: { “title”: “✅ 手動テスト成功(メンション付き)”, “description”: “ \n\nSNSコンソールからのテストメッセージです。\nこの形式で通知が届けば、Lambdaからの通知も正しく表示されます。”, “color”: “#28a745” } } |
Amazon EventBridgeにてスケジュール作成する
1.Amazon EventBridge→スケジュールより、以下スケジュールを作成する
スケジュール名 | Start-LCU-Reservation |
説明 – オプション | Start-LCU-Reservation-hayashi-LCU-test-alb |
スケジュールグループ | default |
1 回限りのスケジュール | スケジュールのパターン |
日付と時刻 | 実行したい日時 |
フレックスタイムウィンドウ | オフ |
2.AWS Lambda Invokeを選択
Lambda 関数にて今回作成したLambda 関数を選択します。
Capacity_reservations_for_Application-Load-Balancer |
ペイロードは以下を選択します。
{ “load_balancer_arn”: “対象のロードバランサーのARNを記入”, “capacity_units”: 100 } |
3.設定 – オプション
スケジュールを有効化 | ON |
スケジュール完了後のアクション | NONE |
再試行ポリシー | OFF |
デッドレターキュー (DLQ) | なし |
暗号化 | なし |
このスケジュールの新しいロールを作成 | Amazon_EventBridge_Scheduler_LAMBDA |
4.スケジュールの確認と保存をします。
また、同じようにLCU予約の解除のスケジュールも作成します。
1.Amazon EventBridge→スケジュールより、以下スケジュールを作成する
スケジュール名 | Stop-LCU-Reservation |
説明 – オプション | Stop-LCU-Reservation-hayashi-LCU-test-alb |
スケジュールグループ | default |
スケジュールのパターン | 1 回限りのスケジュール |
日付と時刻 | 実行したい日時 |
フレックスタイムウィンドウ | オフ |
2.AWS Lambda Invokeを選択
Lambda 関数にて今回作成したLambda 関数を選択します。
Capacity_reservations_for_Application-Load-Balancer |
ペイロードは以下を選択します。
{ “load_balancer_arn”: “対象のロードバランサーのARNを記入”, “capacity_units”: 0 } |
3.設定 – オプション
スケジュールを有効化 | ON |
スケジュール完了後のアクション | NONE |
再試行ポリシー | OFF |
デッドレターキュー (DLQ) | なし |
暗号化 | なし |
既存のロールを使用 | Amazon_EventBridge_Scheduler_LAMBDA |
4.スケジュールの確認と保存をします。
実行確認
LCU予約
設定したスケジュールにて以下のようにLCU予約が実行された通知が行われました。
対象のロードバランサーにてLCU予約が問題なく実行されているか確認できました。
※一度キャンセルを実施していたため今日の残りの減少額が 1 に変わっています。(1日あたり2回までの回数制限が存在します)
|
LCU予約解除
設定したスケジュールにて以下のようにLCU予約の解除が実行された通知が行われました。
また、対象のロードバランサーにてLCUが解除されていることも確認できました。
最後に
弊社ではお客様の課題に合わせて、「監視運用保守サービス」等、当社が提供するサービスをご提案することも可能となっております。
ぜひお気軽にアイレットへご相談ください。