Lambdaで複数のEventBridgeのステータスを一括変更する
はじめに
こんにちは!株式会社Gemcookのバックエンドエンジニアのshunです。
早速ですが今回は複数のEventBridgeのステータスを一括で変更してみます!
どのようなケースで活用できるのか?
例えばEventBridgeとAWS Batchでバッチ処理を作成[1][2]している場合など、DBのメンテナンス作業中などは一時的にデータ更新用のバッチ処理を停止させたい場面があるかと思います。今回紹介するのはそのような場面で、複数のEventBridgeのステータス(無効化/有効化)を一括で変更する方法です。
バッチ処理の本数自体が少なければAWSコンソール上で手動で変更しても問題ないと思いますが、バッチ処理の本数が10本~20本と増えるほど工数の削減、ヒューマンエラーの防止、手順書へ落とせるなど、自動化するメリットは大きいと思いますので是非参考になればと思います👍
対象読者
- 複数のEventBridgeに対して、一括で設定変更する処理を検討している人
構成図
グレーで囲った範囲がこの記事のメインとなります。
EventBridgeの設定を一括で変更する機会は多くないため、Lambda関数を実行するだけのシンプルでわかりやすい構成にします。
前置き
【1】EventBridgeを作成する
まずはステータスを一括変更する対象のEventBridgeのルールを作成していきます。
ターゲットを用意
先にEventBridge用の簡単なターゲットを作成しておきます。今回はメールを送信するSNSトピックをtest_topic
という名前で作成します。
aws sns create-topic --name test_topic
{
"TopicArn": "arn:aws:sns:ap-northeast-1:[AWSアカウントID]:test_topic"
}
SNSトピックのARNに対してメールアドレスをサブスクライブします。
aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:[AWSアカウントID]:test_topic \
--protocol email \
--notification-endpoint [送信先のメールアドレス]
{
"SubscriptionArn": "pending confirmation"
}
メールが届くので承認します。
念のためSNSトピックを発行して実際にメールが届くか確認してみます。
aws sns publish \
--topic-arn arn:aws:sns:ap-northeast-1:[AWSアカウントID]:test_topic \
--subject "test_topic mail" \
--message "Hello World!"
{
"MessageId": "21c748d4-e394-54e0-aa48-28d1af9a0060"
}
メールが届いていればOKです。
EventBridgeを作成
今回ステータスを一括変更する対象のEventBridge本体を作成します。test_event_publish_email__{A...C}
という名前で複数個作成します。
1. ルールを作成
検証用なのでcronの値は何でもOKです。
aws events put-rule \
--name "test_event_publish_email__A" \
--schedule-expression "cron(0 9 * * ? *)"
{
"RuleArn": "arn:aws:events:ap-northeast-1:[AWSアカウントID]:rule/test_event_publish_email__A"
}
2. ターゲットを指定
- 今回作成する3つのEventBridgeのルールにはそれぞれ、1つのターゲットしか設定しないので
"Id"
の値は全て1
でOKです。 -
"Arn"
には「ターゲットを用意する」セクションで出力されたSNSトピックのARNの値を指定します。
aws events put-targets \
--rule "test_event_publish_email__A" \
--targets "Id"="1","Arn"="arn:aws:sns:ap-northeast-1:[AWSアカウントID]:test_topic"
{
"FailedEntryCount": 0,
"FailedEntries": []
}
AWSコンソール上でも、ステータスが有効
状態の3つのEventBridgeのルールが出来上がります。
【2】Lambda関数を作成する
最終的にこのLambda関数を実行することで、対象のEventBridgeのステータスを有効化もしくは無効化に変更することができます。
実行ロールを作成
Lambda関数の実行ロールを作成し、必要なポリシーをアタッチします。
ロール名 |
---|
LambdaToSwitchEventBridgeActionRole とします |
aws iam create-role \
--role-name LambdaToSwitchEventBridgeActionRole \
--assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'
出力はこちら
{
"Role": {
"Path": "/",
"RoleName": "LambdaToSwitchEventBridgeActionRole",
"RoleId": "AROAZKDICZDC5L44XUVKF",
"Arn": "arn:aws:iam::[AWSアカウントID]:role/LambdaToSwitchEventBridgeActionRole",
"CreateDate": "2025-01-18T08:55:28+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
ポリシーを2つアタッチします。
ポリシー名 | 説明 |
---|---|
AWSLambdaBasicExecutionRole |
主にCloudWatch Logsへの書き込み権限を提供[3] |
AmazonEventBridgeFullAccess |
Amazon EventBridge へのフルアクセス権を提供[4] (今回は検証用なのでフルアクセス) |
aws iam attach-role-policy \
--role-name LambdaToSwitchEventBridgeActionRole \
--policy-arn "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
aws iam attach-role-policy \
--role-name LambdaToSwitchEventBridgeActionRole \
--policy-arn "arn:aws:iam::aws:policy/AmazonEventBridgeFullAccess"
AWSコンソール上で、LambdaToSwitchEventBridgeActionRole
が出来上がります。
デプロイコードを作成
ローカルでLambda関数のファイルを作成します。
今回はLambda関数の作成やコードのデプロイをAWS CLIで行うため、作成したLambda関数のファイルはzip化しておきます。
ローカルでデプロイコードを作成し、zip化
以下2ファイルを作成します。
target_eventbridge_rules.txt
lambda_main.py
Lambda関数の概要説明はこちら
lambda_handler
が実行され、以下の流れで処理が進みます。
-
load_rules
関数が実行され引数のtxtファイル
からEventBridgeのルール名をリストで返す - Lambda関数実行時のペイロード(引数)の
action
の値(enable
かdisable
)に応じてEventBridgeのステータスを有効化もしくは無効化に変更する - EventBridgeのルール名ごとに「成功」「存在しないルール」「失敗」の3パターンのメッセージをjson形式でレスポンス
test_event_publish_email__A
test_event_publish_email__B
test_event_publish_email__C
# 【目的】
# EventBridgeのルールのステータスを一括変更する。(有効化/無効化)
#
# 【使い方】
# 1. 更新対象のEventBridgeのルールをtarget_eventbridge_rules.txtファイルに記載する。
# 2. Lambda関数を実行する。
#
# target_eventbridge_rules.txtの例
# test_event_publish_email__A
# test_event_publish_email__B
# test_event_publish_email__C
import boto3
import logging
# ログの設定
def setup_logger():
logger = logging.getLogger()
logger.setLevel(logging.INFO)
return logger
# EventBridgeクライアントの設定
def create_eventbridge_client():
return boto3.client('events')
# 更新対象のEventBridgeのルール名リストを取得
def load_rules(file_path):
try:
with open(file_path, 'r') as f:
rule_names = [line.strip() for line in f if line.strip()]
return rule_names
except Exception as e:
logger.error(f"Failed to load rules from {file_path}: {e}")
return []
def lambda_handler(event, context):
logger = setup_logger()
eventbridge_client = create_eventbridge_client()
logger.info("Lambda function started.")
action = event.get("action")
if not action:
return {
"statusCode": 400,
"body": "Missing 'action' parameter. Use 'enable' or 'disable'."
}
if action not in ["enable", "disable"]:
return {
"statusCode": 400,
"body": f"Invalid action: {action}. Use 'enable' or 'disable'."
}
rule_list = load_rules('target_eventbridge_rules.txt')
update_rule_method = eventbridge_client.enable_rule if action == "enable" else eventbridge_client.disable_rule
results = {}
for rule in rule_list:
try:
update_rule_method(Name=rule)
results[rule] = f"Successfully {action}d."
except eventbridge_client.exceptions.ResourceNotFoundException:
logger.warning(f"Rule not found: {rule}")
results[rule] = "Rule not found."
except Exception as e:
logger.error(f"Failed to {action} {rule}: {e}")
results[rule] = f"Failed to {action}: {e}"
response = {
"statusCode": 200,
"body": results
}
logger.info(f"Response: {response}")
logger.info("Lambda function completed.")
return response
zip化します。
zip -r lambda_function.zip lambda_main.py target_eventbridge_rules.txt
ls | grep lambda_function
lambda_function.zip
デプロイ
先に、先程作成したLambda関数の実行ロールのARNを確認します。
aws iam get-role --role-name LambdaToSwitchEventBridgeActionRole --query "Role.Arn"
"arn:aws:iam::[AWSアカウントID]:role/LambdaToSwitchEventBridgeActionRole"
Lambda関数をデプロイします。
aws lambda create-function \
--function-name switch-eventbridge-action-function \
--runtime python3.13 \
--role "arn:aws:iam::[AWSアカウントID]:role/LambdaToSwitchEventBridgeActionRole" \
--handler lambda_main.lambda_handler \
--zip-file fileb://lambda_function.zip
出力はこちら
{
"FunctionName": "switch-eventbridge-action-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:[AWSアカウントID]:function:switch-eventbridge-action-function",
"Runtime": "python3.13",
"Role": "arn:aws:iam::[AWSアカウントID]:role/LambdaToSwitchEventBridgeActionRole",
"Handler": "lambda_main.lambda_handler",
"CodeSize": 1652,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2025-01-18T10:10:47.277+0000",
"CodeSha256": "xuwaW9yk0oFauVJDl7nFOtI+sH0OSH6rlAODBjGGUmE=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "98a7eec5-9a76-4812-8dcd-19015f3406a0",
"State": "Pending",
"StateReason": "The function is being created.",
"StateReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:b881cbc9a10a8bcb3def9d9e9fe38f922bb36510a1d92d4ce85cf2a899eeabd8"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/switch-eventbridge-action-function"
}
}
AWSコンソール上に、Lambda関数が出来上がります。
【3】Lambda関数を実行しEventBridgeのステータスを変更する
Lambda関数を実行
aws lambda invoke
コマンドでLambda関数を実行し、EventBridgeのステータスを切り替えます。今回は{ "action": "disable" }
を指定し、EventBridgeのステータスを無効化してみます。
aws lambda invoke \
--function-name switch-eventbridge-action-function \
--cli-binary-format raw-in-base64-out \
--payload '{ "action": "disable" }' \
response.json
オプション | 説明 |
---|---|
--cli-binary-format |
ペイロード(引数)をエンコード (AWS CLI v2 の場合は必須[5]) |
--payload |
enable かdisable を指定する |
response.json |
レスポンス結果のファイル名 |
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
レスポンス結果を確認
response.json
の中身を確認します。
cat response.json
{"statusCode": 200, "body": {"test_event_publish_email__A": "Successfully disabled.", "test_event_publish_email__B": "Successfully disabled.", "test_event_publish_email__C": "Successfully disabled."}}%
無事target_eventbridge_rules.txt
で指定したEventBridgeのステータスが無効化されました!成功です!!
レスポンス結果を見やすくする
response.json
見やすくフォーマットするため、ローカルPCや踏み台サーバなどで実行する場合はjqコマンド
[6]をインストールしておくことをお勧めします。
jqコマンド
をインストールした上で、先ほどのaws lambda invoke
コマンドに&&
で続けてresponse.json
を出力してみます。
OS | installコマンド |
---|---|
macOS | brew install jq |
Linux(Ubuntu) | sudo apt-get install jq |
aws lambda invoke \
--function-name switch-eventbridge-action-function \
--cli-binary-format raw-in-base64-out \
--payload '{ "action": "disable" }' \
response.json && cat response.json | jq
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
{
"statusCode": 200,
"body": {
"test_event_publish_email__A": "Successfully disabled.",
"test_event_publish_email__B": "Successfully disabled.",
"test_event_publish_email__C": "Successfully disabled."
}
}
非常に見やすくなりました🎉!
指定のEventBridgeのルールが存在しない場合は..?
仮にtest_event_publish_email__D
という存在しないEventBridgeのルールが指定された場合は以下のような出力になります。
{
"statusCode": 200,
"body": {
"test_event_publish_email__A": "Successfully disabled.",
"test_event_publish_email__B": "Successfully disabled.",
"test_event_publish_email__C": "Successfully disabled.",
"test_event_publish_email__D": "Rule not found."
}
処理が中断されることなく、メッセージでわかるようになっています。
運用例
ささっとEventBridgeのステータスを変更したい
仮に実行回数も年に数回だけかつ対象のEventBridgeの数も膨大でない場合はAWSコンソールのLambdaのコードエディタ上で「target_eventbridge_rules.txt
の中身を変更」 & 「Lambda関数を実行」すると非常にシンプルでコンパクトですね。
(lambda関数の処理内ではtarget_eventbridge_rules.txt
は引数のようなファイルなため、状況に応じて対象のEventBridgeを変更できるように空ファイルでデプロイしといも良いかもですね。)
Lanbdaのコードエディタ上で実行する手順
-
target_eventbridge_rules.txt
の中身を変更し、Deploy
ボタンを押下
-
Test
ボタンからテストを作成し、invoke
ボタンを押下して実行
実行結果もコードエディタのプロンプトで確認できます。
まとめ
今回は自動化に関するテーマでした。プロジェクトコード上での自動化といえば「Makeコマンドやシェルスクリプトを手動で実行する」という工程で対応することも多いと思いますが、AWSリソースの設定変更に関してもそれと近い感じで「Lambda関数を手動で実行する」というちょうど良い手軽さで構成できたのは保守面でもコストが低いためメリットに感じました!
Discussion