はじめに (対象読者・この記事でわかること)
この記事は、AWS Lambda を使ってインフラ自動化を図りたい Node.js 開発者や、サーバーレスアーキテクチャに興味があるエンジニアを対象としています。
本稿を読むことで、以下が実現できるようになります。
- Lambda 関数(JavaScript/Node.js)から CloudWatch Events(現在は EventBridge) のルールをプログラムで取得できる
- 取得した複数のルールを一括で有効化(
EnableRule)できる - IAM ポリシーやエラーハンドリングのベストプラクティスを理解できる
背景として、手動でルールを有効化する作業はミスが起きやすく、規模が大きくなると運用コストが増大します。コードで一元管理すれば、デプロイ時や障害復旧時に即座に状態を整えることが可能です。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- 基本的な JavaScript(ES6)と Node.js の開発経験
- AWS アカウントがあり、Lambda、CloudWatch Events(EventBridge)を利用したことがある
- AWS CLI または AWS SDK(JavaScript バージョン 3) のインストールと設定が完了している
背景と概要:なぜ Lambda でルールを有効化するのか
AWS のイベント駆動型アーキテクチャでは、CloudWatch Events(現在は EventBridge) が中心的な役割を果たします。スケジュール実行や外部サービスからのイベント受信は、個々の「ルール」に紐付くターゲット(Lambda、Step Functions、SQS 等)によって処理されます。環境構築やデプロイパイプラインの途中で、一時的にルールを無効化したり、障害復旧時にまとめて有効化したりするケースは珍しくありません。
手動操作は UI で行うと手間がかかりますし、CI/CD と組み合わせると自動化が難しくなります。そこで 「Lambda から複数ルールを一括有効化」 という手法が有効です。Lambda はサーバーレスなので、追加のサーバー管理コストが不要で、必要なときだけ実行でき、CloudWatch Logs に実行結果を残すことでトレーサビリティも確保できます。
この手法の核心は、AWS SDK for JavaScript v3 の EventBridgeClient と EnableRuleCommand、ListRulesCommand を組み合わせることです。以下のステップで実装します。
- 環境変数やタグで対象となるルールを絞り込む(例:プレフィックスやカスタムタグ)
ListRulesAPI で対象ルールの ARN・名前一覧を取得- 取得した各ルールに対して
EnableRuleを順次呼び出す - エラーが発生した場合は CloudWatch Logs に詳細を出力し、再試行ロジックを組む
具体的な実装手順
必要な IAM 権限
Lambda が操作できるように、以下のポリシーをアタッチします。(最小権限の例)
Json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "events:ListRules", "events:EnableRule", "events:TagResource", "events:UntagResource" ], "Resource": "*" } ] }
※リソースを絞りたい場合は ARN パターンで制限してください。
プロジェクト構成
lambda-enable-rules/
├─ src/
│ └─ index.js
├─ package.json
└─ .env ← optional, e.g. RULE_PREFIX=prod-
依存パッケージインストール
Bashnpm init -y npm install @aws-sdk/client-eventbridge dotenv
コード解説
以下が実装例です。ポイントは 非同期並列処理 と エラーハンドリング にあります。
Javascript// src/index.js import { EventBridgeClient, ListRulesCommand, EnableRuleCommand } from "@aws-sdk/client-eventbridge"; import dotenv from "dotenv"; dotenv.config(); const client = new EventBridgeClient({}); /** * 環境変数で絞り込み条件を取得 * 例: RULE_PREFIX=prod- → 名前が prod- で始まるルールだけ対象 */ const RULE_PREFIX = process.env.RULE_PREFIX || ""; /** * CloudWatch Events のルール一覧を取得(ページング対応) */ async function fetchTargetRules() { let nextToken; const rules = []; do { const cmd = new ListRulesCommand({ NextToken: nextToken }); const resp = await client.send(cmd); const filtered = resp.Rules.filter(r => r.Name.startsWith(RULE_PREFIX)); rules.push(...filtered); nextToken = resp.NextToken; } while (nextToken); return rules; } /** * 取得したルールを一括で有効化 */ async function enableRules(rules) { const enablePromises = rules.map(async (rule) => { try { const cmd = new EnableRuleCommand({ Name: rule.Name }); await client.send(cmd); console.log(`✅ Enabled: ${rule.Name}`); } catch (err) { console.error(`❌ Failed to enable ${rule.Name}:`, err); // 失敗した場合は CloudWatch Logs へ出すだけで、他のルールは継続 } }); // Promise.allSettled で全ての結果を待つ await Promise.allSettled(enablePromises); } /** * Lambda ハンドラ */ export const handler = async (event) => { console.log("🔎 Start enabling CloudWatch rules"); try { const rules = await fetchTargetRules(); if (rules.length === 0) { console.log("⚠️ No matching rules found."); return { statusCode: 200, body: "No rules to enable." }; } console.log(`Found ${rules.length} rule(s) to enable.`); await enableRules(rules); return { statusCode: 200, body: `Enabled ${rules.length} rule(s).` }; } catch (e) { console.error("🚨 Unexpected error:", e); return { statusCode: 500, body: "Internal error." }; } };
キーポイント解説
| 項目 | 内容 |
|---|---|
| ページング | ListRules は 100 件がデフォルト上限。NextToken を利用して全件取得します。 |
| 絞り込み | 環境変数 RULE_PREFIX でプレフィックスを指定。タグベースで絞り込みたい場合は ListTagsForResource と組み合わせます。 |
| 並列処理 | Promise.allSettled により全ルールを同時に有効化しつつ、個別失敗は他に影響しません。 |
| エラーログ | console.error が CloudWatch Logs に出力され、障害解析が容易です。 |
| 再試行 | 必要に応じて aws-sdk の retryStrategy をカスタマイズできます。 |
デプロイ手順(SAM・Serverless Framework 共通)
aws cloudformation packageでコードを S3 にアップロード- CloudFormation テンプレート(または
template.yaml)に Lambda リソースを定義し、上記 IAM ポリシーを付与 aws cloudformation deployでスタック作成- 任意で CloudWatch Events(EventBridge) の スケジュール か カスタムイベント からこの Lambda をトリガー
SAM テンプレート例
YamlResources: EnableRulesFunction: Type: AWS::Serverless::Function Properties: Runtime: nodejs20.x Handler: src/index.handler CodeUri: . Timeout: 60 Policies: - Statement: - Effect: Allow Action: - events:ListRules - events:EnableRule Resource: "*" Environment: Variables: RULE_PREFIX: prod-
ハマりやすい点と対策
| 現象 | 原因 | 解決策 |
|---|---|---|
AccessDeniedException が出る |
IAM ポリシーが不足 | 必要な events:* アクションを追加、リソース ARN を限定 |
NextToken が無限ループになる |
ListRulesCommand のレスポンスに NextToken が空文字列で返るケース |
while (nextToken) の代わりに do...while (nextToken) で空文字列を正しく判定 |
| 1,000 件以上のルールでタイムアウト | 並列実行数が多すぎる | Promise.allSettled を p-limit 等で同時実行数制限(例: 20 同時) |
| ルール名に特殊文字がある | EnableRuleCommand の Name に不正文字 |
AWS が許容する文字列(Unicode 正規化)に統一、または encodeURIComponent でエンコード |
まとめ
本記事では、Node.js(AWS SDK v3)を用いて Lambda から複数の CloudWatch Event ルールを自動的に有効化する方法 を解説しました。
- 対象ルールの取得:
ListRulesと環境変数で絞り込み、ページング対応。 - 一括有効化:
EnableRuleを並列実行し、Promise.allSettledで全体の完了を待つ。 - 実装上の注意点:最小権限の IAM ポリシー、エラーログ出力、再試行・同時実行数制御。
これにより、手動作業を排除し、CI/CD パイプラインや障害復旧プロセスに組み込めるサーバーレス自動化が実現できます。今後は、タグベースでの絞り込みや Step Functions と組み合わせたリトライポリシー など、さらに高度なパターンも検討する予定です。
参考資料
- Amazon EventBridge API Reference – ListRules
- Amazon EventBridge API Reference – EnableRule
- AWS SDK for JavaScript v3 – @aws-sdk/client-eventbridge
- AWS Lambda 関数のベストプラクティス
- Serverless Application Model (SAM) の公式ガイド