0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS リージョン横断のIAMイベント通知を行う方法

0
Posted at

概要

IAMを変更できる管理者ロールを使用した際に、通知が行く仕組みを作成したい
リージョン横断の具体的な実装の参考があまりなかったのでまとめておく

要約

  • CloudTrail のコンソールサインイン系イベント(AWS Console Sign In via CloudTrail)はリージョンごとに発火する。1 リージョンだけ監視しても、別リージョンでの操作は素通りする
  • 解決策は 集約先リージョンにカスタム EventBus を 1 つ立て、各リージョンの EventBridge ルールから PutEvents で寄せる こと
  • 寄せたイベントは中央側のルールで SNS → AWS Chatbot → Slack に流し、SwitchRole のうち管理者相当のロール名にマッチしたものだけを通知する
  • 全リージョン展開は CloudFormation StackSets で 1 アクションで済む

なぜ「リージョン横断」が必要か

AWS マネジメントコンソールにサインインしたり SwitchRole したりすると、CloudTrail に以下のようなイベントが残る。

{
  "source": "aws.signin",
  "detail-type": "AWS Console Sign In via CloudTrail",
  "detail": {
    "eventSource": "signin.amazonaws.com",
    "eventName": "SwitchRole",
    "additionalEventData": {
      "SwitchTo": "arn:aws:iam::123456789012:role/ExampleAdminRole"
    }
  }
}

これは 発生したリージョンの EventBridge 既定バス に届く。たとえばユーザーが ap-northeast-1 のコンソールで SwitchRole したら、そのイベントは ap-northeast-1 の EventBridge にしか出ない。us-east-1 で待ち構えていても気づけない

「全リージョン分のルールと SNS と Chatbot 連携を 30 リージョン分作るのか…?」となるところを、集約用カスタム EventBus を 1 つ立てて寄せる ことで、通知ロジックは 1 箇所に集約できる

実装ポイント

1. カスタム EventBus とバスポリシー(中央側)

カスタム EventBus を作成し、同一アカウントの全リージョンから PutEvents を許可 するバスポリシーを付ける。Principal をアカウント root にすることで、別リージョンからの API コールに対しても効く。

CentralSignInBus:
  Type: AWS::Events::EventBus
  Properties:
    Name: cloudtrail-central

CentralSignInBusPolicy:
  Type: AWS::Events::EventBusPolicy
  Properties:
    EventBusName: !Ref CentralSignInBus
    StatementId: AllowSameAccountCrossRegionPutEvents
    Statement:
      Effect: Allow
      Principal:
        AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
      Action: events:PutEvents
      Resource: !GetAtt CentralSignInBus.Arn

2. 転送用 IAM ロール(中央側で 1 つだけ作る)

IAM ロールはグローバルリソースなので、中央スタックで 1 つ作って、その ARN を各リージョンのルールに渡し回すのが楽。各リージョンで重複作成しなくて良い。

ForwarderRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName: EventBridgeSignInForwardToCentralRole
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Principal:
            Service: events.amazonaws.com
          Action: sts:AssumeRole
    Policies:
      - PolicyName: PutEventsToCentralSignInBus
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action: events:PutEvents
              Resource: !GetAtt CentralSignInBus.Arn

3. 各リージョンの転送ルール(StackSet 側)

各リージョンの default バス に対してルールを置き、ターゲットを 中央リージョンの カスタム EventBus ARNRoleArn を ForwarderRole にする。

SwitchRoleForwardRule:
  Type: AWS::Events::Rule
  Properties:
    Name: !Sub 'CloudTrailSignInSwitchRoleForward-${AWS::Region}'
    EventPattern:
      source: [aws.signin]
      detail-type: ['AWS Console Sign In via CloudTrail']
      detail:
        eventSource: [signin.amazonaws.com]
        eventName: [SwitchRole]
        additionalEventData:
          SwitchTo:
            - wildcard: !Sub 'arn:aws:iam::*:role/*${RoleNameSubstring}*'
    Targets:
      - Id: CentralCustomEventBus
        Arn: !Sub 'arn:aws:events:${CentralRegion}:${AWS::AccountId}:event-bus/${CentralEventBusName}'
        RoleArn: !Ref ForwarderRoleArn

4. 中央側の通知ルール(SNS → Chatbot → Slack)

中央 EventBus に届いたイベントを SNS に流す。InputTransformer で Slack に読みやすい形式に整形しておくと、流れた瞬間に内容が把握できる。

Targets:
  - Id: SignInAlertTopic
    Arn: !Ref SignInAlertTopic
    InputTransformer:
      InputPathsMap:
        AccountID: $.detail.userIdentity.accountId
        AwsRegion: $.detail.awsRegion
        EventTime: $.detail.eventTime
        SwitchTo: $.detail.additionalEventData.SwitchTo
        UserArn:  $.detail.userIdentity.arn
      InputTemplate: |
        {
          "version": "1.0",
          "source": "custom",
          "content": {
            "textType": "client-markdown",
            "title": ":bell: 管理者ロールへのスイッチを検知",
            "description": "---------------------",
            "nextSteps": [
              "アカウントID: <AccountID>",
              "リージョン: <AwsRegion>",
              "発生時刻: <EventTime>",
              "ユーザーArn: <UserArn>",
              "スイッチ先: <SwitchTo>"
            ]
          },
          "UserArn": "<UserArn>"
        }

Slack 側ではこのように届く(イメージ):

🔔 管理者ロールへのスイッチを検知
---------------------
• アカウントID: 123456789012
• リージョン: ap-northeast-1
• 発生時刻: 2026-05-20T12:34:56Z
• ユーザーArn: arn:aws:iam::123456789012:user/example-user
• スイッチ先: arn:aws:iam::123456789012:role/ExampleAdminRole

さいごに

StackSetでの実行を知らないと「全リージョン分リソース作るのか。。。?」となりそうだったのでまとめました
誰かの助けになれば幸いです

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?