CloudWatchアラームを別アカウントのEventBusに転送・処理するCloudformationテンプレート

やりたいこと

CloudWatchアラートの発生元アカウントと、ハンドリングアカウントを分けたいと思い、以下の構成を作成します。

f:id:yomon8:20210915091402p:plain

Cloudformation

パラメータ

Cloudformationパラメータ event_source.cfn.yaml event_target.cfn.yaml 説明
TargetAwsAccountId - TargetアカウントID|
TargetAwsRegion - TargetのカスタムEventBusのリージョン
CustomEventBusName
(TargetEventBusName)
TargetのカスタムEventBusのリージョン
SourceAwsAccountId - SourceアカウントID
EventNotificationMailAddress - Targetアカウント側からメールを送信するアドレス

コード

event_source.cfn.yaml

Sourceアカウントで発生したCloudWatchアラートの状態変化( CloudWatch Alarm State Change ) をトリガーとして、Target側のEventBusにイベントを転送します。

転送にはIAMロールが必要なので、それも定義しています。

AWSTemplateFormatVersion: "2010-09-09"

Description: EventBus CloudWatch Alert Source 

Parameters:
  TargetAwsAccountId:
    Type: String
  TargetAwsRegion:
    Type: String
  TargetEventBusName:
    Type: String

Resources:
  EventForwardingRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: CloudWatchAlertForwarder
      Description: !Sub Forwarding CloudWatch Alert for EventBus ${TargetAwsAccountId}/${TargetEventBusName}
      AssumeRolePolicyDocument: 
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow" 
            Principal: 
              Service: events.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: CloudWatchEventBusPut
          PolicyDocument: 
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - events:PutEvents
                Resource:
                  - !Sub arn:aws:events:${TargetAwsRegion}:${TargetAwsAccountId}:event-bus/${TargetEventBusName}

  EventForwardingRule:
    Type: AWS::Events::Rule
    Properties:
      Name: CloudWatchAlertForwardingRule
      Description: CloudWatch Alert Forwarding Rule
      EventBusName: default
      State: ENABLED
      EventPattern:
        source:
          - aws.cloudwatch 
        detail-type:
          - CloudWatch Alarm State Change
      Targets:
        - Id: 1
          Arn: !Sub arn:aws:events:${TargetAwsRegion}:${TargetAwsAccountId}:event-bus/${TargetEventBusName}
          RoleArn: !GetAtt EventForwardingRole.Arn
event_target.cfn.yaml

defaultとは別にカスタムEventBusを作成してイベントを待ち受けます。CloudWatchイベントのアラート状態変化 (CloudWatch Alarm State Change )を受け取ったらSNS Topic(Email)に情報を転送します。

SNS Topicのポリシーとして events.amazonaws.com からの sns:Publish を許可してあげるところが、Management Consoleから操作すると自動で設定されるところなのでハマりがちなポイントです。

AWSTemplateFormatVersion: "2010-09-09"

Description: EventBus CloudWatch Alert Target

Parameters:
  SourceAwsAccountId:
    Type: String
  CustomEventBusName:
    Type: String
  EventNotificationMailAddress:
    Type: String

Resources:
  EventBus:
    Type: AWS::Events::EventBus
    Properties:
      Name: !Ref CustomEventBusName 

  EventBusPolicy:
    Type: AWS::Events::EventBusPolicy
    Properties:
      EventBusName: !Ref EventBus
      StatementId: EventFromCloudWatchAlertSource 
      Principal: !Ref SourceAwsAccountId
      Action: events:PutEvents

  EventNotificationSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: CloudWatchAlertSample
      TopicName: cw_alert_mail_sample
      Subscription:
        - Endpoint: !Ref EventNotificationMailAddress
          Protocol: email

  EventNotificationSNSTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref EventNotificationSNSTopic
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action: sns:Publish
            Principal:
              Service: events.amazonaws.com
            Resource: !Ref EventNotificationSNSTopic

  EventForwardingSNSRule:
    Type: AWS::Events::Rule
    Properties:
      Name: CloudWatchAlertNotificationRule
      Description: CloudWatch Alert Forwarding Rule
      State: ENABLED
      EventBusName: !Ref EventBus
      EventPattern:
        source:
          - aws.cloudwatch 
        detail-type:
          - CloudWatch Alarm State Change
      Targets:
        - Id: 1
          Arn: !Ref EventNotificationSNSTopic

使い方

2つアカウントを用意して、それぞれCloudformationでデプロイします。

Source側のアカウントでCloudWatchのアラームのステータスを変更させると、Target側からSNSでメール通知されます。