EventBridgeのルールが拾ったイベントをそのままSNSへ流すと、メールにはJSONが丸ごと届きます。入力トランスフォーマーは、イベントから必要な値だけを抜き出し、テンプレートに埋めてからターゲットへ渡す機能です。本記事ではInputPathsMapとInputTemplateの書き方、引用符と型の規則、CodePipelineの失敗をSNSメール・Amazon Q Developer・Slack Incoming Webhookへ届ける設定例、Lambdaへ切り替える判断までを公式ドキュメントに沿って整理しました。EventBridge全体の仕組みはAmazon EventBridgeとは?仕組み・料金とCLI・Pythonでの実装手順に譲ります。仕様と上限値は2026年10月時点の記載です。
まとめ:入力トランスフォーマーは引用符の規則を押さえ、通知先の形に合わせて組む
入力トランスフォーマーは、変数を定義するInputPathsMapと、変数を埋めるInputTemplateの2つで構成されます。詰まりやすいのは構文より引用符の扱いです。JSONテンプレートでは文字列の変数に引用符を付けなくてもよく、オブジェクトや配列を指す変数には付けてはいけません。存在しないパスの変数は黙って出力から消え、抜き出した値はエスケープされずに埋め込まれます。
通知先は3通りから選びます。メールで足りるならSNSに文字列テンプレートを渡す。Slackのチャンネルへ整った体裁で出したいなら、Amazon Q Developerのカスタム通知スキーマへ変換してSNS経由で送る。SNSを挟まずに直接投稿したいときはAPI送信先でIncoming WebhookへPOSTします。値に引用符や改行が混じる、日本時間への変換や条件分岐が要る、といった通知はテンプレートで粘らずLambdaで組むほうが安全です。
入力変換の仕組み|InputPathsMapとInputTemplateの役割と上限
最初に、設定項目の役割と上限値、ほかの入力指定との関係を押さえます。
InputPathsMapからInputTemplateへの変数展開と100個の上限
公式の入力変換ページによると、入力パスでJSONパスを使って元イベントの値を変数に入れ、入力テンプレートの中で山括弧に変数名を入れて参照します。変換後のイベントが元のイベントの代わりにターゲットへ送られる。変数は最大100個まで定義できます。
APIリファレンスのInputTransformerには細かい上限が並びます。InputTemplateは1〜8,192字、InputPathsMapは100組まで、キーと値はそれぞれ256字まで、キーはAWS.で始められません。JSONパスはルール作成時に検証されないため、綴りの誤りは保存できてしまう点も頭に入れておきます。
JSONパスの書き方は、2つの文書で表現が食い違っている点に気をつけてください。APIリファレンスは「ブラケット記法ではなくドット記法」と書く一方、ユーザーガイドは配列のインデックスを対応構文に挙げ、$.resources[0]を例に使っています。キーはドットでつなぎ、角括弧は配列のインデックスにだけ使う書き方にしておけば、どちらの記載にも沿います。
予約変数aws.events.rule-nameなど5種類の中身と使える位置の違い
パスを定義しなくても使える予約変数が5つあり、同じ名前の変数は作れません。
aws.events.rule-arn:ルールのARN(文字列内・JSONの値のどちらにも置ける)aws.events.rule-name:ルール名(同上)aws.events.event.ingestion-time:EventBridgeがイベントを受け取った時刻、ISO 8601形式(同上)aws.events.event:detailを除いた元イベント(JSONの値にだけ置ける)aws.events.event.json:detailを含む元イベント全体(JSONの値にだけ置ける)
最後の2つは中身がエスケープされないため、JSONフィールドの値としてしか置けません。通知文の末尾に「元イベント全文」を文字列で添える、という使い方はできない仕様です。ルール名を文面に入れておくと、どのルールが送った通知かを受信側で追えます。
Input・InputPathとの排他関係と別アカウントのバス宛てで使えない制約
put-targetsのリファレンスでは、Input(固定のJSON)・InputPath(イベントの一部をそのまま渡す)・InputTransformerはターゲットの排他パラメータです。detailだけを渡したいならInputPathの$.detailで済み、整形が要るときだけ入力トランスフォーマーを使います。
別のAWSアカウントのイベントバスをターゲットにした場合、この3つはどれも使えません。アカウントをまたいで集約する構成では、受け側のアカウントのルールで変換します。集約側バスのリソースポリシーや送信側ロールの権限設定は、EventBridge イベントバスの使い分け:クロスアカウント・リージョン送信のポリシー設定にまとめています。また、ターゲットのURLパスなどに値を差し込む動的パスパラメータは、変換後ではなく元のイベントを参照します。
InputTemplateの書き方|文字列とJSONで変わる引用符と型の扱い
テンプレートは文字列とJSONのどちらでも書けます。引用符の扱いが両者で違うため、ここが最初のつまずきどころになります。
文字列テンプレートとJSONテンプレートで変わる引用符の付け方と出力例
元イベントが"detail": {"instance-id": "i-0123456789", "state": "RUNNING"}で、変数instanceとstateを定義した場合の出力を、公式の例から抜き出しました。矢印の左がテンプレート、右が出力です。
# 文字列テンプレート
"instance <instance> is in <state>" => "instance i-0123456789 is in RUNNING"
# JSONテンプレート(文字列の変数は引用符なしでよい)
{"instance": <instance>} => {"instance": "i-0123456789"}
# JSONテンプレート(文字列の中に埋める)
{"msg": "state is <state>"} => {"msg": "state is RUNNING"}
文字列テンプレートは全体を二重引用符で囲みます。JSONテンプレートでは、文字列を指す変数は引用符なしで書けばEventBridgeが自動で引用符を補います。付けても許容されますが、どちらかに揃えておくと読み違いが減る。文字列の中で引用符を出したいときは\"と書きますが、公式によるとコンソールとAWS CLIで結果が変わり、CLIではバックスラッシュがさらにエスケープされます。
オブジェクトや配列を指す変数を文字列に埋めると引用符が消える落とし穴
変数が$.detailのようにオブジェクトや配列を指す場合、引用符を付けてはいけません。"Detail is <detail>"のように文字列の中へ埋めると、EventBridgeは有効な文字列にするため内側の引用符を取り除きます。結果はJSONとして読めない文字列です。
オブジェクトをそのまま渡したいときは{"detail": <detail>}のようにJSONの値として置きます。テンプレートがJSONの場合、プレースホルダーをオブジェクトのキーには使えません。{<name>: "x"}のようにキー名を動的に変える書き方は通らないので、キーは固定にします。
存在しないパスの変数は出力から消え、値はエスケープされない2つの注意
公式の「よくある問題」に、通知用途で効いてくる2点があります。1つ目は、イベントに存在しないパスを指す変数は作られず、出力にも現れないことです。エラーにはならず、該当箇所が空のまま届く。サービスによってはイベントの種類でフィールドの有無が変わるため、通知文に入れる項目は、拾うイベントすべてに存在するものから選びます。
2つ目は、入力パスで抜き出した値がエスケープされずにテンプレートへ入ることです。コミットメッセージのように利用者が書いた文字列は、二重引用符や改行を含むことがあります。JSONテンプレートにそのまま埋めると出力がJSONとして壊れうるため、自由記述の値を通知に載せるかどうかは判断章で扱う基準で決めます。
SNSのメール通知を読める文章に整形する手順|CodePipelineの失敗を例に
ここからはAWS CodePipelineのデプロイ失敗を例に、設定を組み立てます。
CodePipelineのアクション失敗イベントから項目を抜き出す変数定義
CodePipelineのイベント一覧では、パイプライン単位の失敗イベントのdetailにあるのはパイプライン名・実行ID・状態などで、どのステージで落ちたかは入っていません。failedStageなどの項目は、通知機能が処理した後のイベントにだけ付く項目です。ステージ名と失敗の要約を載せたいなら、アクション単位のCodePipeline Action Execution State Changeを拾います。ルールのパターンは公式例をそのまま使えます。
{
"source": ["aws.codepipeline"],
"detail-type": ["CodePipeline Action Execution State Change"],
"detail": {
"state": ["FAILED"],
"type": { "category": ["Deploy", "Build"] }
}
}
アクションの失敗イベントにはdetail.stage・detail.action・detail.execution-result.external-execution-summary・external-execution-urlが入ります。パターンの演算子の書き方はEventBridge イベントパターンの書き方で詳しく扱っています。
複数行の通知文を行ごとの二重引用符で組みput-targetsで登録する
メールで読む文章にする場合に使うのは、文字列テンプレートです。公式は、複数行の文字列を出すときは各行を二重引用符で囲むよう案内しています。JSONファイルに書く場合、行の区切りは\nで表します。
[
{
"Id": "notifyMail",
"Arn": "arn:aws:sns:ap-northeast-1:123456789012:deploy-alerts",
"InputTransformer": {
"InputPathsMap": {
"pipeline": "$.detail.pipeline",
"stage": "$.detail.stage",
"action": "$.detail.action",
"summary": "$.detail.execution-result.external-execution-summary",
"url": "$.detail.execution-result.external-execution-url",
"time": "$.time"
},
"InputTemplate": "\"[FAILED] <pipeline> / <stage> / <action>\"\n\"Summary: <summary>\"\n\"Detail: <url>\"\n\"Time (UTC): <time>\""
}
}
]
aws events put-rule --name deploy-failed-notify --event-pattern file://pattern.json
aws events put-targets --rule deploy-failed-notify --targets file://targets.json
put-targetsの応答でFailedEntryCountが0であることを確かめます。SNSはロールではなくトピックのリソースポリシーでEventBridgeからの発行を許可するターゲットなので、トピック側にも設定が必要です。トピックとサブスクリプションの考え方はAmazon SNSとは|Pub/Sub通知の仕組みにまとめています。$.timeはUTCのため、文面に「UTC」と明記しておくと読み違いを防げます。
Slackへ届ける2つの経路|Q Developerのカスタム通知とAPI送信先
Slackへ出す方法は、SNSを経由してAmazon Q Developerに投稿させる経路と、API送信先からIncoming Webhookを直接呼ぶ経路の2つです。
Amazon Q Developerのカスタム通知スキーマへ変換しSNS経由で投稿する
AWS Chatbotは現在Amazon Q Developer in chat applicationsに改称されています。カスタム通知のドキュメントでは、入力トランスフォーマーでイベントを所定のスキーマへ変換し、チャンネルに対応づけたSNSトピックへ送る方法が示されています。versionは1.0、sourceはcustomが必須で、本文のdescriptionは8,000字まで、titleは250字までです。カスタム通知の追加料金はかかりません。
{
"version": "1.0",
"source": "custom",
"content": {
"textType": "client-markdown",
"title": ":rotating_light: <pipeline> のデプロイが失敗",
"description": "*ステージ*: <stage>\n*アクション*: <action>\n*概要*: <summary>\n*詳細*: <url>",
"keywords": ["CodePipeline", "<stage>"]
},
"metadata": {
"threadId": "<pipeline>",
"summary": "<pipeline> の失敗通知"
}
}
threadIdにパイプライン名を入れると、同じパイプラインの通知がSlackとMicrosoft Teamsでスレッドにまとまります。注意したいのは、公式チュートリアルにある「<と>はエスケープできない」という制約です。Slackのリンク記法<URL|表示名>やメンション<@ユーザーID>は山括弧を使うため、テンプレートの固定文言として書くとプレースホルダーと衝突します。URLは素のまま置き、メンションが要る通知はLambda側で組み立てます。
API送信先でIncoming Webhookへ直接POSTする構成と接続の認証設定
API送信先は、ルールのターゲットとしてHTTPSエンドポイントを呼ぶ機能です。CreateConnectionでは認証方式が必須で、BASIC・OAUTH_CLIENT_CREDENTIALS・API_KEYから選びます。Incoming WebhookはURL自体が秘密情報なので、接続にはSlackが使わないヘッダーをAPIキーとして入れる形になります。Webhookの発行とBlock Kitの組み方はSlack Incoming Webhookの実装手順を参照してください。
aws events create-connection --name slack-webhook \
--authorization-type API_KEY \
--auth-parameters '{"ApiKeyAuthParameters":{"ApiKeyName":"X-Notify-Source","ApiKeyValue":"eventbridge"}}'
aws events create-api-destination --name slack-deploy-alerts \
--connection-arn arn:aws:events:ap-northeast-1:123456789012:connection/slack-webhook/EXAMPLE \
--invocation-endpoint https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXX \
--http-method POST --invocation-rate-limit-per-second 1
[
{
"Id": "notifySlack",
"Arn": "arn:aws:events:ap-northeast-1:123456789012:api-destination/slack-deploy-alerts/EXAMPLE",
"RoleArn": "arn:aws:iam::123456789012:role/eventbridge-invoke-api-destination",
"InputTransformer": {
"InputPathsMap": { "pipeline": "$.detail.pipeline", "stage": "$.detail.stage", "summary": "$.detail.execution-result.external-execution-summary" },
"InputTemplate": "{\"text\": \":x: <pipeline> / <stage> failed: <summary>\"}"
},
"RetryPolicy": { "MaximumRetryAttempts": 10, "MaximumEventAgeInSeconds": 3600 },
"DeadLetterConfig": { "Arn": "arn:aws:sqs:ap-northeast-1:123456789012:deploy-alerts-dlq" }
}
]
API送信先のターゲットはSNSと違い、IAMロールにevents:InvokeApiDestinationの許可が要ります。Slackはtextが無いとno_text、形式が壊れているとinvalid_payloadを返します。API送信先の仕様では401・407・409・429・5xxは再試行されますが、それ以外の4xxは再試行されず、DLQが無ければ破棄です。テンプレートの誤りで400が返る通知は黙って消えるため、ターゲットごとのDLQを必ず付けます。料金は100万回の呼び出しあたり0.20ドルです。
入力トランスフォーマーのテストと登録|サンドボックスとCloudFormationの書き方
イベントパターンにはtest-event-patternがありますが、入力変換を試すAPIはEventBridgeのアクション一覧にありません。確認はコンソールで行い、コードで管理します。
コンソールのサンドボックスでGenerate outputを押し出力を確かめる手順
サンドボックスの手順を使うと、ルールを作らずに変換結果を見られます。
- EventBridgeコンソールの「デベロッパーリソース」から「サンドボックス」を開き、「ターゲット入力トランスフォーマー」タブを選ぶ
- サンプルイベントでAWSのイベントを選ぶか、「自分のイベントを入力」に実際のイベントのJSONを貼る
- ターゲット入力トランスフォーマー欄に変数定義、テンプレート欄にテンプレートを入れる
- 「Generate output」を押し、出力欄に表示された内容を確かめる
サンプルには、実際に通知したいイベントをCloudTrailやDLQから取り出して貼るのが確実です。フィールドが欠けたイベントも1件試し、変数が消えたときの文面が読めるかまで見ておきます。本番の出力そのものを見たい場合は、同じ変換を設定したSQSキューを一時的に2つ目のターゲットに足す方法があります(1ルールのターゲットは5つまで)。
CloudFormationのYAMLで書くときのキー名の制約と引用符の扱い
コードで管理するなら、YAMLのブロック記法でテンプレートを書くとエスケープが減ります。AWS CloudFormationでの例です。
DeployFailedRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source: ["aws.codepipeline"]
detail-type: ["CodePipeline Action Execution State Change"]
detail:
state: ["FAILED"]
Targets:
- Id: notifyMail
Arn: !Ref DeployAlertsTopic
InputTransformer:
InputPathsMap:
pipeline: "$.detail.pipeline"
stage: "$.detail.stage"
summary: "$.detail.execution-result.external-execution-summary"
InputTemplate: |
"[FAILED] <pipeline> / <stage>"
"Summary: <summary>"
CloudFormationのリファレンスはInputPathsMapのキーのパターンを[a-zA-Z0-9]+と記載しており、APIリファレンスの[A-Za-z0-9_-]+より狭く書かれています。detail-typeのようなハイフン入りのキー名は避け、英数字のキャメルケースにしておけば両方の記載に収まります。
入力トランスフォーマーで済ませる場面とLambdaへ切り替える判断の基準
入力トランスフォーマーはコードを持たずに済む反面、できることは値の抜き出しと差し込みに限られます。
変換だけで済む条件はIDや状態値の抜き出しと固定文言の差し込みまで
入力トランスフォーマーで済ませてよいのは、AWSサービスが出すIDや状態値、リソース名を、決まった文面に差し込むだけの通知です。CodePipelineの失敗、EC2の状態変化、バックアップジョブの完了といった、値の形が仕様で決まっているイベントがこれに当たります。Lambdaの関数・ログ・ランタイム更新を持たずに済むため、運用で見る箇所が1つ減ります。
1つのルールでも、ターゲットごとに別の入力トランスフォーマーを設定できます。メールには文字列、SlackにはQ Developerのスキーマ、と宛先ごとに文面を分けるだけなら、Lambdaは要りません。
値に引用符や改行が混じる・条件分岐が要る通知はLambdaで組む
次のどれかに当たる通知は、テンプレートで粘らずLambdaで組みます。
- コミットメッセージや説明文など、利用者が書いた文字列を載せる(エスケープされず出力が壊れうる)
- 重要度に応じてメンションの有無を変えるなど、値で文面を分岐させる
- UTCの時刻を日本時間に直す、数値を丸めるといった加工が要る
- Slackのリンク記法やメンションなど、山括弧を含む書式を使いたい
テンプレートの誤りはエラーとして表に出にくく、変数が消えた文面や400で捨てられた通知として後から気づくことになります。上の条件に1つでも当たるなら、最初からLambdaで整形しテストコードを付けるほうが、障害時に通知が来ないという事故を防ぐ対策として有効です。通知基盤を含むAWS構成の設計や見直しはインフラ構築(AWS・Google Cloud・Azure)でご相談いただけます。
よくある質問
入力トランスフォーマーの設定でよく出る疑問に、公式ドキュメントの記載をもとに答えます。
入力トランスフォーマーで時刻を日本時間に変換できますか?
できません。入力トランスフォーマーは、JSONパスで抜き出した値をテンプレートに差し込む機能で、日付計算や書式変換の関数を持っていません。$.timeや予約変数aws.events.event.ingestion-timeはUTCのISO 8601形式のまま入ります。メールやSlackの読み手が日本時間を前提にしているなら、文面に「UTC」と添えて誤読を防ぐか、Lambdaで変換してから送ります。
入力トランスフォーマーの利用に料金はかかりますか?
EventBridgeの料金ページに入力変換の項目はなく、課金はイベントの取り込みと配信、API送信先の呼び出しといった既存の項目で決まります。API送信先は100万回あたり0.20ドルで、接続の認証情報を保存するSecrets Managerの費用も含めた料金です。SNSやLambdaを経由する場合は、それぞれのサービスの料金が別にかかります。EventBridge全体の課金の仕組みはAmazon EventBridgeの料金で整理しています。
EventBridge Pipesの入力変換とルールの入力トランスフォーマーは書き方が同じですか?
考え方は同じですが、書き方が違います。ルールではInputPathsMapで変数を定義してからInputTemplateで参照します。Pipesでは変数定義の欄がなく、テンプレートの中に$.dynamodb.NewImage.orderId.SのようなJSONパスを山括弧で直接書き、予約変数もaws.pipes.で始まる別の名前です。Pipes側の書き方はEventBridge Pipesの使い方で扱っています。
変換後の出力が想定と違うときはどこを確認しますか?
まずサンドボックスに実際のイベントを貼り、Generate outputで同じ出力になるかを見ます。項目が抜けているならJSONパスの綴りかイベント側のフィールドの有無を、JSONが壊れているなら引用符の付け方と、オブジェクトを文字列に埋めていないかが確認の対象です。届かない場合は、DLQに入ったメッセージの属性ERROR_CODEとERROR_MESSAGEに失敗の理由が残ります。put-targetsでDLQを指定したときはキューのリソースポリシーを手で付ける必要があるため、そこも併せて確かめます。ルールが動いたか、どこで失敗したかをバスのログとメトリクスで追う手順はEventBridge ログの調べ方:ルールが発火しない原因をメトリクス・バスログ・DLQで特定するで解説しています。
1つのルールで宛先ごとに違う文面を送れますか?
送れます。入力トランスフォーマーはルールではなくターゲットごとの設定で、1つのルールには最大5つのターゲットを付けられます。同じCodePipelineの失敗イベントを、運用チームのメールには複数行の文字列で、開発チームのSlackにはQ Developerのカスタム通知で届ける、といった分け方が可能です。ターゲットが5つを超えるなら、同じパターンのルールを分けて作ります。
関連記事
- Amazon EventBridgeとは?仕組み・料金とCLI・Pythonでの実装手順、新Custom Event Busとの違いを解説【2026年版】:バス・ルール・ターゲットの全体像と最小構成。
- EventBridge イベントパターンの書き方:演算子一覧とtest-event-patternでの検証:通知の対象を絞るルール側の条件の書き方。
- Amazon SNSとは|Pub/Sub通知の仕組み・配信先・FIFO/フィルタリングと採用判断を実装者目線で解説:変換後の通知を受けるトピックとサブスクリプションの設計。
- Slack Incoming Webhookの実装手順:URL発行・Block Kit整形・SDK送信と429対策:API送信先から呼ぶWebhookの発行と整形。
- EventBridgeとSQS・Lambdaの非同期構成|キューポリシー・部分バッチ応答・DLQの置き場所:Lambdaで整形する場合の受け方とDLQの置き場所。