はじめに (対象読者・この記事でわかること)

この記事は、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 v3EventBridgeClientEnableRuleCommandListRulesCommand を組み合わせることです。以下のステップで実装します。

  1. 環境変数やタグで対象となるルールを絞り込む(例:プレフィックスやカスタムタグ)
  2. ListRules API で対象ルールの ARN・名前一覧を取得
  3. 取得した各ルールに対して EnableRule を順次呼び出す
  4. エラーが発生した場合は 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-

依存パッケージインストール

Bash
npm 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-sdkretryStrategy をカスタマイズできます。

デプロイ手順(SAM・Serverless Framework 共通)

  1. aws cloudformation package でコードを S3 にアップロード
  2. CloudFormation テンプレート(または template.yaml)に Lambda リソースを定義し、上記 IAM ポリシーを付与
  3. aws cloudformation deploy でスタック作成
  4. 任意で CloudWatch Events(EventBridge) の スケジュールカスタムイベント からこの Lambda をトリガー

SAM テンプレート例

Yaml
Resources: 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.allSettledp-limit 等で同時実行数制限(例: 20 同時)
ルール名に特殊文字がある EnableRuleCommandName に不正文字 AWS が許容する文字列(Unicode 正規化)に統一、または encodeURIComponent でエンコード

まとめ

本記事では、Node.js(AWS SDK v3)を用いて Lambda から複数の CloudWatch Event ルールを自動的に有効化する方法 を解説しました。

  • 対象ルールの取得ListRules と環境変数で絞り込み、ページング対応。
  • 一括有効化EnableRule を並列実行し、Promise.allSettled で全体の完了を待つ。
  • 実装上の注意点:最小権限の IAM ポリシー、エラーログ出力、再試行・同時実行数制御。

これにより、手動作業を排除し、CI/CD パイプラインや障害復旧プロセスに組み込めるサーバーレス自動化が実現できます。今後は、タグベースでの絞り込みStep Functions と組み合わせたリトライポリシー など、さらに高度なパターンも検討する予定です。

参考資料