AWS帳號代充值 AWS EventBridge 規則匹配但無法觸發 SNS 通知?Topic Policy 權限診斷
先釐清:規則命中,不代表 SNS 已收到訊息
很多人看到 EventBridge 規則的 MatchedEvents 上升,就以為 SNS 一定已經收到通知。其實不是。EventBridge 先做的是事件比對,只有當事件內容符合規則條件時,才會嘗試把資料送到目標;而 SNS 是否真的發出通知,還要再經過一次授權檢查、服務呼叫與主題策略驗證。也就是說,匹配成功只是第一關,真正投遞成功才是你要追的結果。
所以當你遇到「規則看起來正常、事件也命中、但手機或郵件完全沒收到通知」這種情況,第一個念頭不要停在 EventBridge 的事件模式,而要往後看:SNS Topic Policy 有沒有放行、目標 ARN 對不對、Region 是否一致、主題是否有加密、EventBridge 是否真的完成了目標呼叫。這些地方只要有一個卡住,畫面上看起來就像是「規則有命中,但通知消失了」。
一、把整條投遞鏈路拆成四段
排錯最怕把所有元件混在一起看。先把整條路拆開,問題就清楚很多。
1. 事件進到 EventBridge
來源可以是自建應用、AWS 服務事件,或其他系統送進來的自訂事件。這一段你要先確認事件本身有沒有真的進到 EventBridge,例如 PutEvents 有沒有成功、事件格式是不是完整、欄位名稱有沒有拼錯。
2. 規則判斷是否命中
AWS帳號代充值 規則命中代表事件內容符合你設定的 pattern。這一步只說明「有機會送出」,不代表後面一定成功。很多人只看這裡就停止排查,結果把真正的錯誤留在後面。
3. EventBridge 嘗試呼叫 SNS Publish
只要規則的 target 設為 SNS,EventBridge 就會去做一次 sns:Publish。如果這個呼叫被拒絕、找不到目標、或因為策略限制失敗,規則仍然會顯示命中,但目標不會收到訊息。
4. SNS 根據 Topic Policy 接不接受
這一段最常出問題。SNS 主題不是只要有 ARN 就能直接被別人推送,必須在 Topic Policy 裡明確允許 events.amazonaws.com 發佈訊息,還常常要加上來源規則的 ARN 限制,避免太寬鬆。少了這一步,EventBridge 再努力也送不進去。
二、最常見的原因:Topic Policy 沒有放行 events.amazonaws.com
如果你只是在 IAM 使用者或某個角色上加了權限,通常沒有用。因為真正發出 SNS 訊息的不是你登入控制台的那個人,而是 EventBridge 這個服務。SNS 看的不是人的權限,而是 Topic Policy 是否允許服務主體 events.amazonaws.com 執行 sns:Publish。
很多錯誤配置都長得很像:有些人把 principal 寫成 sns.amazonaws.com,有些人放行了 sns:Subscribe 卻忘了 sns:Publish,還有人把 Resource 寫成錯的主題 ARN,或是條件中的 aws:SourceArn 寫成事件匯流排 ARN,而不是規則 ARN。這些錯誤不一定會在控制台直接報得很明顯,但結果都一樣:規則命中,通知沒有出去。
下面是一個最小可用、也比較安全的 Topic Policy 範本。你可以先拿它確認流程,再依實際需求增加限制。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEventBridgePublish",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:ap-northeast-1:123456789012:order-alert",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:events:ap-northeast-1:123456789012:rule/order-rule"
},
"StringEquals": {
"aws:SourceAccount": "123456789012"
}
}
}
]
}
這份 policy 的重點是什麼
第一,principal 要寫 events.amazonaws.com,因為是 EventBridge 在送。第二,action 要是 sns:Publish,不是 Subscribe,也不是別的動作。第三,Resource 要精準指向那個 SNS topic。第四,條件中的 aws:SourceArn 要對準規則 ARN,不要寫錯成 event bus ARN 或其他資源 ARN。第五,aws:SourceAccount 可以幫你縮小授權範圍,避免被別的帳號誤用。
如果你現在還在排查階段,建議先用這種最小可用 policy 讓流程跑通,再慢慢加上更細的限制。先把「能送」確認清楚,再談「怎麼送得更安全」。
三、看懂一份可用的 Topic Policy
Principal 要對
很多人會直覺想把 SNS 本身放進 principal,或是把自己的 IAM 使用者、角色名字加進去。這些都不是 EventBridge 發送 SNS 訊息時真正使用的身分。真正要放行的是服務主體 events.amazonaws.com。只要 principal 不對,後面的條件再漂亮也沒用。
Action 要對
EventBridge 要做的是發佈訊息,所以必須有 sns:Publish。如果你只允許 sns:Subscribe、sns:SetTopicAttributes 或其他管理動作,對通知投遞沒有幫助。這是很典型的「看起來有權限,實際上沒有」的狀況。
Resource 要對
許可要落在正確的 Topic ARN 上,不能只寫到某個泛用資源,或抄錯 Region 與帳號。尤其是複製環境時,最容易把 dev、staging、prod 的 ARN 搞混。Topic Policy 一旦綁錯,你在控制台看到的可能還是那個主題,但實際放行的卻是另一個資源。
Condition 不要過度限制
條件寫太嚴格,常常會讓自己卡死。最常見的是 aws:SourceArn 填錯,或以為規則名稱換過之後 ARN 不用更新。也有人把條件寫成某個固定的事件內容,結果每次事件欄位稍微變動就失敗。原則很簡單:先確認最小可行,再逐步收緊。
四、當訊息還是發不出去,依序查這 5 件事
- 看 EventBridge 指標:先確認
MatchedEvents有增加,再看Invocations和FailedInvocations。如果命中很多、失敗也很多,通常不是 pattern 問題,而是目標投遞失敗。 - 檢查 target ARN:目標是不是正確的 SNS topic,名稱有沒有打錯,Region 有沒有對上。不要只看畫面上「好像很像」,要把完整 ARN 拿出來比對。
- 確認 Topic Policy:有沒有放行
events.amazonaws.com,sns:Publish是否存在,aws:SourceArn是否精準指向那條規則。 - 查看 CloudTrail 或事件記錄:如果有權限,找
sns:Publish的嘗試紀錄,常常可以直接看到被拒絕的原因。這比只看控制台提示有效得多。 - 檢查是否有 KMS 加密:如果 SNS Topic 使用客戶管理的 KMS 金鑰,除了 Topic Policy,KMS Key Policy 也要允許 SNS 服務使用金鑰,否則訊息在加密階段就會卡住。
五、幾個很容易忽略的邊界情況
1. 規則和 Topic 不在同一個 Region
先確認事件匯流排、規則和 SNS Topic 的 Region 是否一致。很多人以為只要 ARN 看起來合法就能互通,實際上跨區域配置常常不是那麼直覺。排錯時不要猜,直接對照完整 ARN。
2. 以為訂閱端有問題,其實是主題根本沒收到
有些人看到手機或 Email 沒通知,就一直檢查訂閱狀態、過濾政策、垃圾信件夾,卻忘了先確認主題是否收到訊息。若 Topic Policy 就擋住了,訂閱端當然什麼都看不到。
3. 誤把事件匹配當成投遞成功
這是最常見的認知落差。EventBridge 的「命中」只是規則判斷結果,不是目標執行結果。你要養成習慣,把規則命中、目標呼叫、SNS 收到這三件事分開看。
4. 跨帳號時過度相信預設授權
跨帳號架構裡,Topic Policy 幾乎一定要明確設計,不能靠預設行為。若來源帳號、目標帳號、規則 ARN 或 SourceAccount 任一項不一致,就很容易出現授權拒絕。這種情境下,更要先用最小策略跑通,再逐步加固。
5. 主題使用了 KMS,但金鑰政策沒跟上
AWS帳號代充值 如果 Topic 啟用了 SSE-KMS,除了 SNS 主題本身的資源政策,KMS Key Policy 也要允許對應服務使用金鑰。很多團隊只改 SNS,忘了改 KMS,結果訊息發送過程卡在加密步驟,排查時還以為是 EventBridge 出問題。
六、實戰排錯順序:先縮小範圍,再動手改
真正有效的排錯,不是東改一點西改一點,而是按順序縮小問題範圍。你可以照這個順序來:
第一步,確認事件真的有進到 EventBridge。第二步,確認規則確實命中。第三步,看目標投遞有沒有失敗。第四步,核對 SNS Topic Policy。第五步,如果有 KMS,再查 Key Policy。第六步,確認 Region 與 ARN 完全一致。第七步,再檢查訂閱端是否正常。
如果你一開始就大改 policy、重建規則、刪除重建 topic,通常只會讓問題更難追。好的排錯方式是先證明「哪一段沒有成功」,再針對那一段做最小修改。這樣你不但能快速找出原因,也比較不會把原本正常的部分一起弄壞。
七、最常見的幾個錯誤組合
實務上,最常見的錯誤組合通常長這樣:規則命中正常,Topic Policy 少了 sns:Publish,CloudWatch 顯示 FailedInvocations 增加,但使用者還在檢查 Email 訂閱;或者主題名稱是新的,但 policy 還留著舊 ARN;或者 topic 已經啟用 KMS,但金鑰政策沒有更新。只要你遇過一次,就會知道這類問題為什麼總是反覆出現,因為它們都很像「設定完成了」,實際上卻只完成了一半。
AWS帳號代充值 要避免這種情況,最好的方法不是背更多名詞,而是建立一個固定習慣:每次做 EventBridge 到 SNS 的整合,都先檢查三件事——事件是否命中、目標是否被允許、投遞是否真的成功。這三件事分開看,很多原本很玄的問題就會變得很明確。
結語:先信任數據,再信任感覺
「規則匹配但沒有 SNS 通知」這個問題,表面上像是 EventBridge 出錯,實際上大多是 SNS Topic Policy 或金鑰政策沒有對齊。只要你記住一件事:匹配成功不等於投遞成功,排錯方向就不會偏。
下次再遇到這種狀況,先看 MatchedEvents,再看 FailedInvocations,然後直接去查 Topic Policy、SourceArn、SourceAccount 和 KMS Key Policy。把整條鏈路拆開來看,問題通常會比你想像得更快浮出來。

