AWS CloudFormation で Amazon EventBridge から Amazon CloudWatch Logs へのログ転送でハマった話。

こんにちは。ひるたんぬです。

本年もよろしくお願いいたします。今年は巳年ですね。
小さい頃に「十二支は神様の号令の下、競争して早い順に決まった」と言われた記憶があるのですが、実際に本当に早い順に十二支を並べるとどのようになるのか、ふと気になってしまいました。
調べたところ、すでにこの疑問に対して調査をしてくださっていた記事がありましたので一部を抜粋してご紹介します。

本やネットに速度が出ているものは、それを採用し、それ以外のものは、筆者の経験その他から強引に算出するなどした結果、13匹の動物たちの速度は以下のようになった。

子=鼠:時速10km
丑=牛:時速4km(注1)
寅=虎:時速64km
卯=兎:時速72km
辰=竜:時速360km以上(注2)
巳=蛇:時速16km(注3)
午=馬:時速68km(注4)
未=羊:時速13km(注5)
申=猿:時速30km(注6)
酉=鶏:時速18km(注7)
戌=犬:時速36km(注8)
亥=猪:時速45km
猫:時速48km(注9)

引用:Yahoo! ニュース「「十二支」の順番がナットクできない。実際の動物のスピードを考えると、どんな順番になるか?

上記から、令和版の十二支は「辰卯午寅猫亥戌申酉巳未子」となるようですね。竜が圧勝のようです。
戦略を練って二位に漕ぎ着けていた牛は、スタメンから外れてしまいました。
また、これを元に考えると、今年は亥年ということになりますね。

…さて、今回はIaCというものを少し使いこなせるようになって調子に乗っていた結果、大きな落とし穴にはまってしまったので、自戒の意味も込めてご紹介いたします。

やりたいこと

とあるログをEventBridgeを経由してCloudWatch Logsに送ろう!というよくあるものです。
せっかくなのでマネジメントコンソールからではなく、IaC(CloudFormation)を使用して構築しよう!ということになりました。

やったこと

マネジメントコンソールではEventBridgeのルール作成とCloudWatch Logsのロググループ作成のみで実施できたので、同じようにCloudFormationを書いてみました。今回は検証のため、EC2に関する任意のイベントをCloudWatch Logsのロググループへ転送することにします。

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  RuleEC2Activity:
    Type: AWS::Events::Rule
    Properties: 
      EventPattern: 
        {
          "source": ["aws.ec2"]
        }
      Targets: 
        - Arn: !GetAtt LogEC2Activity.Arn
          Id: LogGroup

  LogEC2Activity:
    Type: AWS::Logs::LogGroup
    Properties:
      RetentionInDays: 14
      LogGroupName: /aws/events/EC2Activity

上記のファイルのデプロイは問題なく完了しました。

起きたこと

ログへ転送がされるかを確認するために、EC2インスタンスを立ち上げました。しかし、待てど暮らせどログは出力されません。
おかしいな…と思い、EventBridgeの当該ルールのモニタリングをチェックすることにしました。すると…

EventBridgeのルール自体は動いていたのですが、そのすべての実行が失敗(FailedInvocationsに記録)していたのです。

原因調査

こんなときに役に立つのは、インターネットに広がる知識の海です。調査してみたところ、公式ドキュメントに気になる記載がありました。

CloudWatch Logs がルールのターゲットである場合、EventBridge がログストリームを作成し、CloudWatch Logs がログエントリとしてイベントからテキストを保存します。EventBridge がログストリームを作成してイベントを記録するためには、EventBridge が CloudWatch Logs に書き込むことを可能にするリソースベースポリシーを CloudWatch Logs に含める必要があります。

AWS Management Console を使用して、CloudWatch Logs をルールのターゲットとして追加する場合、リソースベースのポリシーは自動的に作成されます。AWS CLI を使用してターゲットを追加し、ポリシーがまだ存在しない場合は、作成する必要があります。
引用:AWS「Amazon EventBridge ユーザーガイド:Amazon EventBridge のリソースベースのポリシーを使用する

今までの私は前者(マネジメントコンソールでの操作)しか行ったことがなかったので気づかなかったのですが、実はリソースベースポリシーの設定が必要なようですね。言われてみれば、権限も設定していないのに書き込めるのは不思議ですもんね。。。

解決に向けて…

リソースベースポリシーをIaCにて設定

後述する参考記事によると、CloudFormationでリソースベースポリシーを設定できるようなので、まずはこちらを試してみます。
下記のテンプレートファイルを作成し、新規でスタックを作成してデプロイします。

PolicyDocument内のアカウントIDやロググループ名などは適宜修正してください。
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  EventBridgeToCWLPolicy:
    Type: AWS::Logs::ResourcePolicy
    Properties:
      PolicyDocument: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"TrustEventsToStoreLogEvent\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"delivery.logs.amazonaws.com\",\"events.amazonaws.com\"]},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Resource\":\"arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/events/*:*\"}]}"
      PolicyName: TrustEventsToStoreLogEvents

これにより、正常にログが転送されました!

また、このスタックを削除することによりポリシーがなくなり、ログ転送ができなくなる点も確認できました。

リソースベースポリシーをマネジメントコンソールにて設定

では、マネジメントコンソールでルールを作成した場合はどうなるのでしょうか。
リソースベースポリシーが裏で設定されているとのことだったので、その挙動を中心に確認してみます。

ルールを作成した後にCloudShellにてリソースベースポリシーの有無を確認してみると…

先ほどIaCにて設定したポリシーと同様のものが付与されていました。
知らないところで動かせるようにしてくれていたのですね。

…ここで気になった点がありました。
「このマネジメントコンソールで作ったルールを消したらリソースベースポリシーはどうなっちゃうの問題」です。
実際にやってみる他ありませんね!やってみました。

…残っていました。そのため、マネジメントコンソールからEventBridgeのルールを一度でも作成している場合、このブログのような症状には出会わない可能性もあるということですね。

おわりに

改めて、AWSの権限に対する考え方を痛感する良いきっかけとなりました。
何事にも許可がいる…現実でもクラウド上でもそんな認識でいるのが大事なのかなと思います。

また、今回の記事は以下を参考に作成いたしました。Web上の皆さまの記事にはいつも助けられてばかりです。。

上記サイトにも記載がありましたが、このリソースベースポリシーはマネジメントコンソール上から確認することができないようです。(CLIを用いて確認する)
あまり需要はないかもしれませんが、これも気軽に確認できるようになるとより良いのかな…と思った次第です。

余談ですが、十二支の昔話はYouTubeでも観れるのですね。

タイトルとURLをコピーしました