Amazon EventBridge の新しいカスタムイベントバスを CLI で試してみた
はじめに
2026年09月24日、新しいカスタムイベントバスがリリースされました。
新方式では、24時間の組み込みリテンションが付き、最大1年まで延長できるようになりました。課金体系は従来のイベント数ベースではなく転送データ量ベースで、提供リージョンは東京を含む14リージョンです。
新方式の追加に伴い、従来のカスタムイベントバスは Custom event bus - classic に改称されました。
今回、シングルアカウント・SQS 宛ての構成で、新しいカスタムイベントバスを作成し、イベントを publish して、配信先で本文を受け取るまでを CLI で確かめました。
コンソールのバス作成画面
コンソールのバス作成画面では、Bus type が Custom event bus (recommended) と Custom event bus - classic の2択になっており、前者に New バッジが付いています。

左メニューでも Event buses に New バッジが付き、Classic のルーティングは Classic event routing という別グループに分かれています。

既存バスの改称について、コンソールのモーダルは「This is a name change only. All other functionality works exactly as before, and you can continue to create and manage Classic event buses.」と案内しています。
検証環境
東京リージョン(ap-northeast-1)で、次の AWS CLI を使いました。
$ aws --version
aws-cli/2.37.2 Python/3.14.6 Linux/7.1.13-402.asahi.fc44.aarch64+16k
リテンション付きでバスを作る
新方式のバスは、Classic の aws events とは別のサービス名 aws eventbridgev2 で操作します。
リテンションは作成時の --storage-configuration で指定します。ここでは7日を指定しました。
$ aws eventbridgev2 create-event-bus \
--name eb-v2-verify \
--description "Verification bus for the new custom event bus" \
--storage-configuration RetentionPeriodInDays=7
{
"EventBusArn": "arn:aws:events:ap-northeast-1:123456789012:event-busv2/eb-v2-verify/0flgsossjby9l8ls5jd55eb7z",
"Name": "eb-v2-verify",
"Description": "Verification bus for the new custom event bus",
"StorageConfiguration": {
"RetentionPeriodInDays": 7,
"RetentionWindowStartTime": "2026-09-25T09:59:28.956000+09:00"
},
"State": "CREATING",
"CreationTime": "2026-09-25T09:59:29.014000+09:00"
}
ARN の形は Classic の event-bus/<name> から event-busv2/<name>/<生成ID> に変わり、末尾の ID は EventBridge が付与します。バス名から ARN を組み立てることはできず、describe-event-bus や Subscriber の作成でもバスは ARN で指定します。
そのため、作成応答の EventBusArn を控えておきます。以降のコマンドではこれを BUS_ARN として使います。
$ BUS_ARN=arn:aws:events:ap-northeast-1:123456789012:event-busv2/eb-v2-verify/0flgsossjby9l8ls5jd55eb7z
作成直後は State が CREATING で返り、少し待つと ACTIVE になります。
Subscriber で SQS へ配信する
新方式では、ルールとターゲットの代わりに Subscriber を作って配信先を指定します。必須パラメータは --name、--event-bus-arn、--invoke-configuration の3つで、フィルタや Transformer は任意です。今回は Subscriber を3本作りました。put-events 用、put-raw-events 用、順序確認用の FIFO です。SQS は配信先の3キューと DLQ の計4本を用意しました。
$ aws eventbridgev2 create-subscriber \
--name sub-raw \
--event-bus-arn "$BUS_ARN" \
--type UNORDERED \
--filter-configuration '{"Filters":[{"Scope":"DATA","Pattern":"{\"data\":{\"amount\":[{\"numeric\":[\">\",500]}]}}"}]}' \
--transformer '{"Type":"WITH_METADATA"}' \
--invoke-configuration '{"TargetArn":"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-raw-q","RoleArn":"arn:aws:iam::123456789012:role/eb-v2-delivery-role"}' \
--on-failure-configuration '{"Arn":"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-dlq"}'
{
"SubscriberArn": "arn:aws:events:ap-northeast-1:123456789012:subscriber/sub-raw/dm1qvl9dd5p8iyr8946yanvc2",
"Name": "sub-raw",
"Type": "UNORDERED",
"StartingPosition": "LATEST",
"State": "RUNNING",
"CreationTime": "2026-09-25T10:01:38.135000+09:00"
}
StartingPosition の既定値は LATEST なので、Subscriber 作成より前に publish したイベントは届きません。動作確認では Subscriber を先に作ります。
配信の権限は、キューのリソースポリシーではなく Subscriber に渡す IAM ロールで与えます。ロールには配信先のキューと、OnFailureConfiguration に指定した DLQ への sqs:SendMessage を含めます。KMS とクロスアカウント共有は今回扱いません。
配信ロールの信頼ポリシーと権限ポリシー
信頼ポリシーは検証で使った最小の形で、aws:SourceAccount や aws:SourceArn による呼び出し元の絞り込みは入れていません。共用アカウントで使うなら、これらの条件キーで信頼する呼び出し元を限定します。
信頼ポリシー(trust.json として保存し aws iam create-role --role-name eb-v2-delivery-role --assume-role-policy-document file://trust.json に渡しました):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "events.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
権限ポリシー(perm.json として保存し aws iam put-role-policy --role-name eb-v2-delivery-role --policy-name send-to-queues --policy-document file://perm.json に渡しました):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sqs:SendMessage",
"Resource": [
"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-events-q",
"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-raw-q",
"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-ordered-q.fifo",
"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-dlq"
]
}
]
}
リトライとバッチは指定しなくても既定値が入ります。
`describe-subscriber` で見える既定値
$ aws eventbridgev2 describe-subscriber --subscriber-arn "$SUB_ARN"
{
"InvokeConfiguration": {
"RoleArn": "arn:aws:iam::123456789012:role/eb-v2-delivery-role",
"TargetArn": "arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-raw-q"
},
"FilterConfiguration": {
"Language": "EVENT_BRIDGE_PATTERN",
"Filters": [
{ "Pattern": "{\"data\":{\"amount\":[{\"numeric\":[\">\",500]}]}}", "Scope": "DATA" }
]
},
"Type": "UNORDERED",
"StartingPosition": "LATEST",
"BatchConfiguration": { "MaxBatchSize": 10, "MaxBatchWindowInSeconds": 0 },
"Transformer": { "Type": "WITH_METADATA" },
"RetryPolicy": { "MaxRetryAttempts": 5, "MaxEventAgeInSeconds": 300, "RetryStrategy": "ALL" },
"OnFailureConfiguration": { "Arn": "arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-dlq" },
"State": "RUNNING"
}
put-events と put-raw-events で届く形が変わる
publish の API は2つあります。put-events は Source・DetailType・Detail を取る Classic に近い形、put-raw-events は Data にペイロードそのものを渡す形です。
put-raw-events の Data は base64 blob です。AWS CLI の既定の binary format では、渡した JSON を base64 として解釈しようとして失敗します。
$ aws eventbridgev2 put-raw-events --event-bus-arn "$BUS_ARN" \
--entries '[{"Data":"{\"specversion\":\"1.0\", ...}", ...}]'
aws: [ERROR]: Invalid base64: "{\"specversion\":\"1.0\", ...}"
CLI から生の JSON を渡すには --cli-binary-format raw-in-base64-out を付けます。次は、両 API で同じ注文データを publish した結果です。put-raw-events 側は CloudEvents の形にしました。
$ aws eventbridgev2 put-events --event-bus-arn "$BUS_ARN" \
--entries '[{"Source":"com.example.myapp","DetailType":"OrderCreated",
"Detail":"{\"orderId\":\"ORD-101\",\"amount\":1980}",
"SystemMetadata":{"EventGroupId":"customer-1"}}]'
{
"FailedEntryCount": 0,
"Entries": [
{ "EventId": "9d46baf1-640c-4663-9417-9d0e5dc65200", "SequenceNumber": "10000000000000003000", "SuccessCode": "PUBLISHED" }
]
}
$ aws eventbridgev2 put-raw-events --cli-binary-format raw-in-base64-out --event-bus-arn "$BUS_ARN" \
--entries '[{"Data":"{\"specversion\":\"1.0\",\"type\":\"com.example.order.created\",\"source\":\"com.example.myapp\",\"id\":\"ce-101\",\"time\":\"2026-09-25T01:00:00Z\",\"datacontenttype\":\"application/json\",\"data\":{\"orderId\":\"ORD-101\",\"amount\":1980}}",
"Metadata":{"producer":"checkout-service"},
"SystemMetadata":{"ContentType":"application/json","EventGroupId":"customer-1"}}]'
{
"FailedEntryCount": 0,
"Entries": [
{ "EventId": "9944a059-17d2-4665-a323-d0bd3cb6530a", "SequenceNumber": "10000000000000004000", "SuccessCode": "PUBLISHED" }
]
}
SystemMetadata.ContentType に指定できるのは application/json / application/avro / application/protobuf / application/octet-stream です。CloudEvents は application/json として送ります。
配信先で受け取る形は、publish API と Subscriber の Transformer の組み合わせで決まります。まず、Transformer を指定しない Subscriber で put-events のイベントを受けると、届くのはユーザーガイドで envelope と呼ばれている構造だけです。ペイロードを detail に包む構造は Classic と同じで、Metadata と SystemMetadata は本文に含まれません。
`Transformer` 指定なしの Subscriber で `put-events` を受けた本文
{
"version": "0",
"id": "df3e557b-6282-4df1-84c5-1e8956a533e0",
"detail-type": "OrderCreated",
"source": "com.example.myapp",
"account": "123456789012",
"time": "2026-09-25T01:02:36Z",
"region": "ap-northeast-1",
"resources": [],
"detail": { "orderId": "ORD-101", "amount": 1980 }
}
Transformer: WITH_METADATA の Subscriber で put-raw-events のイベントを受け取ると、本文は次のようになります。
{
"Data": {
"specversion": "1.0",
"type": "com.example.order.created",
"source": "com.example.myapp",
"id": "ce-101",
"time": "2026-09-25T01:00:00Z",
"datacontenttype": "application/json",
"data": { "orderId": "ORD-101", "amount": 1980 }
},
"Metadata": { "producer": "checkout-service" },
"SystemMetadata": {
"EventGroupId": "customer-1",
"DeduplicationId": "47befe33-072e-4afd-86d1-0d89ef4216d4",
"ContentType": "application/json",
"aws:IngestionTime": "2026-09-25T01:02:58.740Z",
"aws:EventId": "9944a059-17d2-4665-a323-d0bd3cb6530a",
"aws:SequenceNumber": "10000000000000004000",
"aws:DeliveryType": "LIVE"
}
}
送った CloudEvents の JSON が Data にそのまま入っており、EventBridge のエンベロープで包み直されて二重になることはありません。受信側ではそのまま CloudEvents として扱えます。Metadata には publish 時に付けたキーが入り、EventBridge が付与する値は SystemMetadata に分かれます。
フィルタは publish API に合わせて書く
フィルタは、配信されるデータ構造に合わせて書きます。同じ「amount が500を超える」という条件でも、起点のキーが publish API によって変わります。
| publish API | フィルタのパターン | amount: 1980 |
amount: 100 |
|---|---|---|---|
put-events |
{"detail":{"amount":[{"numeric":[">",500]}]}} |
届く | 届かない |
put-raw-events |
{"data":{"amount":[{"numeric":[">",500]}]}} |
届く | 届かない |
| 両 API(フィルタなしの Subscriber) | — | 届く | 届く |
起点を取り違えたフィルタはエラーにならず、どのイベントにもマッチしないまま動作します。
順序保証と重複排除
順序が必要なら Subscriber を --type FIFO で作ります。SQS の FIFO キューへ配信するには MessageGroupId が必要で、JSONata 式で publish 時の EventGroupId を渡せます。配信先の FIFO キューは FifoQueue=true,ContentBasedDeduplication=true で作りました。
$ aws eventbridgev2 create-subscriber \
--name sub-fifo \
--event-bus-arn "$BUS_ARN" \
--type FIFO \
--invoke-configuration '{"TargetArn":"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-ordered-q.fifo","RoleArn":"arn:aws:iam::123456789012:role/eb-v2-delivery-role","SqsParameters":{"MessageGroupId":"{% $events.SystemMetadata.EventGroupId %}"}}' \
--on-failure-configuration '{"Arn":"arn:aws:sqs:ap-northeast-1:123456789012:eb-v2-dlq"}'
{
"SubscriberArn": "arn:aws:events:ap-northeast-1:123456789012:subscriber/sub-fifo/dl7sjpulnlearuy29hne8lr75",
"Name": "sub-fifo",
"Type": "FIFO",
"StartingPosition": "LATEST",
"State": "RUNNING",
"CreationTime": "2026-09-25T10:01:49.110000+09:00"
}
EventGroupId を customer-1 に揃えて、ORD-201 から ORD-205 までを1件ずつ publish しました。FIFO キューには publish した順に届き、SQS 側の SequenceNumber も昇順でした。
// eb-v2-ordered-q.fifo(FIFO Subscriber)での到着順
[
{ "orderId": "ORD-201", "MessageGroupId": "customer-1", "SqsSequenceNumber": "18905060493981423616" },
{ "orderId": "ORD-202", "MessageGroupId": "customer-1", "SqsSequenceNumber": "18905060494079727616" },
{ "orderId": "ORD-203", "MessageGroupId": "customer-1", "SqsSequenceNumber": "18905060494186223616" },
{ "orderId": "ORD-204", "MessageGroupId": "customer-1", "SqsSequenceNumber": "18905060494296303616" },
{ "orderId": "ORD-205", "MessageGroupId": "customer-1", "SqsSequenceNumber": "18905060494416111872" }
]
同じイベントを --type UNORDERED の Subscriber でも受けたところ、ORD-202 → 205 → 201 → 203 → 204 の順で届きました。
重複排除は publish 側の設定です。put-events に --deduplication-configuration DeduplicationType=CONTENT_BASED を付けて、同一内容を2回続けて publish しました。
// 1回目
{ "EventId": "f6fda443-afe5-4daa-a971-d254be085d74", "SequenceNumber": "10000000000000012000", "SuccessCode": "PUBLISHED" }
// 2回目(同じコマンド)
{ "EventId": "f6fda443-afe5-4daa-a971-d254be085d74", "SequenceNumber": "10000000000000012000", "SuccessCode": "DEDUPLICATED" }
2回目は SuccessCode が DEDUPLICATED になり、EventId と SequenceNumber は1回目と同じでした。配信先に届いたのも1件です。
Classic から移すときに変わる3点
同一アカウント内で SQS に配信する構成を Classic と新方式の両方で組みました。
Classic(aws events) |
新方式(aws eventbridgev2) |
|
|---|---|---|
| バス ARN | event-bus/<name> |
event-busv2/<name>/<生成ID>。名前から組み立てられない |
| SQS への配信権限 | キューのリソースポリシー | Subscriber に渡す IAM ロール |
publish 応答の EventId |
配信された本文の id と一致 |
一致しない。SystemMetadata.aws:EventId が一致する |
ユーザーガイドでは、JSON のイベントで Classic と同じエンベロープが欲しい場合は put-events を選ぶよう案内しています。
エンベロープの構造は実測でも Classic と同じでした。次は、この確認のために別途作成したバスに Transformer: WITH_METADATA の Subscriber を1本用意し、put-events のイベントを受けた結果です。
// publish 応答
{ "EventId": "0d8fd5c4-524b-4d4f-9149-b11cd66aecfd", "SuccessCode": "PUBLISHED" }
// SQS で受け取った本文
{
"Data": {
// version / source / account / time / region / resources は省略
"id": "3027f30e-bfb2-4ab5-a5e5-d6b67c5790a4",
"detail-type": "OrderCreated",
"detail": { "orderId": "ORD-401", "amount": 1980 }
},
"Metadata": {},
"SystemMetadata": {
// EventGroupId / DeduplicationId / aws:IngestionTime は省略
"ContentType": "application/eventbridge+json",
"aws:Source": "com.example.myapp",
"aws:DetailType": "OrderCreated",
"aws:EventId": "0d8fd5c4-524b-4d4f-9149-b11cd66aecfd",
"aws:SequenceNumber": "10000000000000003000",
"aws:DeliveryType": "LIVE"
}
}
put-events では、ペイロードは Data の下の detail に入り、SystemMetadata.ContentType には EventBridge が application/eventbridge+json を設定します(put-raw-events では publish 時に指定した値、今回は application/json)。受信側はこの値で put-events 経由かを判別できます。
publish 応答の EventId は、配信された本文の id ではなく SystemMetadata.aws:EventId と一致します。EventId で publish と配信を突き合わせているなら、Subscriber の Transformer を WITH_METADATA にして SystemMetadata.aws:EventId を参照してください。
まとめ
新方式のカスタムイベントバスで最初に決めるのは、put-events と put-raw-events のどちらで publish するかです。ここで配信先に届く形が決まります。
新規に組むなら put-raw-events をおすすめします。ユーザーガイドは put-events を「Classic と同じエンベロープが欲しい場合」、put-raw-events を「ペイロードをそのまま届けたい、独自のメタデータを付けたい、JSON 以外を扱う場合」と使い分けており、Classic 互換が要らないなら後者に当てはまります。送った JSON がエンベロープに包まれずそのまま届くので、CloudEvents のようにスキーマが決まっている形式を、受信側で EventBridge 独自のエンベロープから取り出す処理を挟まずにそのまま扱えます。Step Functions のように JSONata で入力を参照するターゲットでも、detail を1段掘らずにペイロードを扱えるようになると期待できます。
Classic との互換性を保つなら put-events です。Classic と同じ構造のエンベロープを作るので、既存の受信処理とフィルタパターンをそのまま使えます。
今回取り上げなかった AWS RAM による他アカウントや Organizations へのバス共有については、追って検証して紹介する予定です。







