AWS アカウントの新規作成や組織間の移動、解約等を EventBridge と SNS で Slack へ通知する

記事タイトルとURLをコピーする

マネージドサービス部 佐竹です。
AWS Organizations で AWS アカウントを新規に払い出したタイミングや、組織間の移動、解約等のタイミングで Slack へと通知を行うための Amazon EventBridge の設定について記載します。

はじめに

2020年12月に以下のブログを記載しました。今回はこのブログを最新化するという試みになります。

blog.serverworks.co.jp

と言いますのも、上記ブログの記載時からサービス名等も変更されています。加えて、最近改めて本仕組みを実装する機会を得ましたので、その作業をもって最新化を行いたいと感じたところがあります。

改めて背景

AWS Organizations 等でマルチアカウント管理をしている場合、AWS アカウント(組織におけるメンバーアカウント)を新規に払い出した後、すぐにそれに気づきたいという要望があります。

というのも、作成された AWS アカウントに対してすぐに後続処理をしたいためで、それは具体的には OU の移動やセキュリティに関する初期セットアップとなります*1

Root 直下にアカウントが配置される

また後続処理が発生するのは、何も新規アカウントの払い出し時だけではなく、組織間のアカウント移動や、アカウントの閉鎖(解約)も含まれます。

というわけで管理アカウントの Amazon EventBridge をトリガーに、これらの作業が実施された時に Slack へ通知する実装方法について記載します。

AWS 環境構成図による全体像

AWS 環境構成図

こちらの構成図に従って実装していきます。なお、実装に関する詳細は一部割愛しており、注意点だけに留めます。

リージョンは US East (N. Virginia) を利用する

大前提として、管理アカウントにおける AWS Organizations の操作履歴は US East (N. Virginia) に記録されます。

US East (N. Virginia)

このため、まずは実装するためにリージョンを US East (N. Virginia) へと変更してください。

これを忘れると、最初から実装をやり直しする羽目にもなりますので、大前提として記載しています(実際、私自身が最初からやり直ししたことがあります)。

SNS Topic を作成する (暗号化も行う)

では、まずは SNS Topic の作成からです。

暗号化された SNS Topic を作成する

今回は、Security Hub のコントロールの1つである [SNS.1] SNS topics should be encrypted at-rest using AWS KMS をクリアする目的で合わせて暗号化を行うこととします*2

Amazon SNS に関するコントロールについては以下を合わせて参考としてください。

docs.aws.amazon.com

では早速、AWS マネジメントコンソールの SNS の画面から作成していきます。

Create topic

トピックは FIFO である必要もないため「Standard」で作成します。また今回「Amazon-EventBridge-Topic」という名称としました。

暗号化時の注意事項

次に暗号化の設定ですが、大事な注意点があります。

Encryption - optional

まず KMS の鍵に (Default) alias/aws/sns利用しないでください

理由ですが、AWS Managed Key(デフォルト)は、キーポリシーが修正できません。このため、Amazon EventBridge が AWS Managed Key を利用するというアクセス許可を設定できず、SNS の Publish (構成図の ③Publish ) に失敗します。

よって今回の利用シーンでは、SNS Topic の暗号化において「Customer managed key」が必須となります。

Customer managed keys

ということで今回は SNS-Topic-Key-for-Organizations-Management-Account という名前の「Customer managed key」を作成し、それを利用していきます。

KMS キーポリシーの修正

また、作成した KMS キーに対してキーポリシーの修正が必要です。

Amazon EventBridge が Customer managed key を利用可能となるよう、アクセス許可を設定します。修正例は以下の re:Post (日本語版は「Amazon SNSトピックがEventBridge通知を受信しないのはなぜですか?」) からの引用を参考にします。

repost.aws

この最下部にある Example IAM policy statement that allows EventBridge to publish messages to an encrypted Amazon SNS topic を参考に、以下の通りの JSON をキーポリシーに追加します*3

{
  "Sid": "Allow CWE to use the key",
  "Effect": "Allow",
  "Principal": {
    "Service": "events.amazonaws.com"
  },
  "Action": [
    "kms:Decrypt",
    "kms:GenerateDataKey*"
  ],
  "Resource": "*"
}

これで Amazon EventBridge が「SNS Topic の暗号化に利用されている KMS キー」にアクセスが可能となり、問題なく SNS Topic へと Publish が可能となります。

EventBridge から KMS へアクセスが可能

KMS キーポリシーの修正に関して

なお、管理アカウントにおける KMS キーポリシーの修正ですが、この暗号化された SNS Topic を他サービスでも利用する場合、以下のサービスからの利用も許可を併記しておくと便利です。

  • "events.amazonaws.com":Amazon EventBridge(再掲)
  • "budgets.amazonaws.com":AWS Budgets
  • "costalerts.amazonaws.com":AWS Cost Anomaly Detection

こちらも合わせて参考にしてみてください。

では作業を継続します。

作成した Customer managed key を指定する

SNS Topic における暗号化の KMS キーに、作成した Customer managed key を指定します。または Topic を作成した後から修正も可能です。

SNS-Topic-Key-for-Organizations-Management-Account

後続作業で「Name タグ」等を付与した後「Create topic」を押下して SNS Topic の作成作業は完了です。

AWS Chatbot で Slack 連携を設定する

AWS Chatbot

AWS Chatbot から Slack への連携設定は以下のブログに詳しく記載しておりますため、参考に設定頂ければ幸いです。

blog.serverworks.co.jp

部分的な補足ですが「Configure Slack channel」においては「Notifications - optional」の設定で「US East - N. Virginia」と先ほど作成した「Amazon-EventBridge-Topic」を選択し、紐付けを行います。

Configure Slack channel

Amazon EventBridge で Rule を作成する

Amazon EventBridge で Rules を作成する

順序としては最後の設定です。Amazon EventBridge で Rule を複数作成します。

Create rule

「Amazon EventBridge > Rules」から「Create rule」を押下して設定を勧めます。

CreateOrganizationalUnit のイベントを通知する

今回最初に動作確認も兼ねて「AWS-Create-Organizational-Unit」を作っていきます。

Define rule detail

上画像の通り、「Rule detail」では「Name」と「Description - optional」のみ入力し、次に進みます。

Build event pattern

次の「Build event pattern」の画面では、下部の「Creation method」で「Custom pattern (JSON editor)」のラジオボタンを選択し「Event pattern」に以下の JSON を入力してください*4

{
  "source": ["aws.organizations"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["organizations.amazonaws.com"],
    "eventName": ["CreateOrganizationalUnit"]
  }
}

次に、EventBridge が上記のイベントをフックしたタイミングで通知する先を「Target」として選択します。

Select target(s)

ここで、先ほど作成した SNS Topic 「Amazon-EventBridge-Topic」を選択します。

次の「タグ設定」は任意のため割愛させて頂きます。

Review and create

最後にレビューを行い、問題がなければ「Create rule」を押下し作成を完了します。

AWS-Create-Organizational-Unit

念のため、ルールが作成された後は「Rule details」から詳細を確認しておくと良いでしょう。

SNS Topic の Access policy

補足ですが、マネジメントコンソールからこれらの設定を行うと、SNS Topic のアクセスポリシーが自動的に追記&修正され、上図の通り Amazon EventBridge から SNS Topic がキックできる権限が付与されます。

CreateOrganizationalUnit で動作確認を行う

AWS Chatbot で正しく Slack に通知が行われるのか、実際に「Create organizational unit」を行い動作確認します。

Create organizational unit

上図の画面から「Create organizational unit」を押下すると、数秒後には Slack へ以下のような通知が行われるはずです。

AWS API Call via CloudTrail

この通知が行われることで動作確認としてください。

もし CreateOrganizationalUnit の通知が来ない場合は、どこかで設定を誤っていることになります。これから先の設定も同様に通知されないことになりますので、必ず動作確認を行いましょう。

InviteAccountToOrganization のイベントを通知する

その他に有用な、AWS アカウントの操作に関連するイベント通知設定を続けて行います。

InviteAccountToOrganization は、組織間の移動時にキックされるイベントで、例えば自社組織に「他社組織の AWS アカウント」を移動させたい場合に利用します。なおこの API は「招待」で利用するものです。「離脱」の場合は LeaveOrganization がキックされます*5

これをフックすることで、AWS アカウントが新たに組織内に参加することを検出できます。この後の作業は新規 AWS アカウント発行時と同様、「OU の移動」などが必要となるでしょう。

docs.aws.amazon.com

この イベントを EventBridge の Event pattern として記載する場合は、以下の通りです。

{
  "source": ["aws.organizations"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["organizations.amazonaws.com"],
    "eventName": ["InviteAccountToOrganization"]
  }
}

先程の設定から「eventName」を変更するだけとなりますが、念のため JSON 全体を記載します。

CloseAccount のイベントを通知する

CloseAccount は組織のメンバーアカウントを閉鎖する場合に利用する API です。

これに伴い、対象のアカウントを「Suspended OU に移動させる」などの対応を行うために検出したいという背景があります。

docs.aws.amazon.com

この イベントを EventBridge の Event pattern として記載する場合は、以下の通りです。

{
  "source": ["aws.organizations"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["organizations.amazonaws.com"],
    "eventName": ["CloseAccount"]
  }
}

CreateAccountResult のイベントを通知する

CreateAccountResult は組織で新しいメンバーアカウントを発行した場合に発生するイベント CreateAccount の後にキックされるイベントです。

docs.aws.amazon.com

このイベントは、CreateAccount が成功した場合に結果として実行されるもののため、CreateAccountResult をフックする方がより運用に則ったものとなります。

なお、CreateAccount と異なり、CreateAccountResult は AWS Chatbot で正常に連携されません。このため、Input transformer で整形し可読性を高める必要があります。

本件については以下にまとめました。

blog.serverworks.co.jp

CreateAccountResult の イベントを EventBridge の Event pattern として記載する場合は、以下の通りで設定自体には変わりません。

{
  "source": ["aws.organizations"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["organizations.amazonaws.com"],
    "eventName": ["CreateAccountResult"]
  }
}

Input transformer の設定

Target input transformer

先にご紹介しましたブログにも記載がありますが、本ブログにも合わせて記載致します。

Input transformer の設定は以下の通りです。

Input path
{
    "account": "$.account",
    "eventID": "$.detail.eventID",
    "eventName": "$.detail.eventName",
    "id": "$.id",
    "region": "$.region",
    "source": "$.source",
    "state": "$.detail.serviceEventDetails.createAccountStatus.state",
    "time": "$.time",
    "userAgent": "$.detail.userAgent"
}
Template
{
    "version": "0",
    "id": "<id>",
    "detail-type": "AWS API Call via CloudTrail",
    "source": "<source>",
    "account": "<account>",
    "time": "<time>",
    "region": "<region>",
    "resources": [],
    "detail": {
        "eventVersion": "1.08",
        "userIdentity": {
            "arn": "No ARN"
        },
        "userAgent": "<userAgent>",
        "eventTime": "<time>",
        "eventName": "<eventName>(<state>)",
        "awsRegion": "<region>",
        "eventID": "<eventID>",
        "eventType": "AwsServiceEvent"
    }
}

こちらでお勧めするイベントの紹介を終わります。

まとめ

本ブログでは AWS Organizations で AWS アカウントを新規に払い出したタイミングや、組織間の移動、解約等のタイミングで Slack へと通知を行うための Amazon EventBridge の設定について記載しました。

再掲となりますが、全体の構成は上図の通りです。

最後に通知設定に関して整理します。

  • 設定は US East (N. Virginia) リージョンで行う
  • SNS Topic で暗号化を行う場合には、KMS でカスタマーマネージドキーを必ず利用し、キーポリシーを修正する
  • Amazon EventBridge のルールでは以下の AWS API Call via CloudTrail を通知すると良い
    • CreateOrganizationalUnit:OU の作成。特に動作確認用としても有用
    • InviteAccountToOrganization:組織間の AWS アカウントの移動(招待)
    • CloseAccount:組織におけるメンバーアカウントの閉鎖
    • CreateAccountResult:組織におけるメンバーアカウント発行が成功した結果
  • CreateAccountResult は Input transformer 設定し可読性を向上させる

これらを Slack に通知することで、ほぼ即時の AWS アカウントに関連する業務のトリガーとできますので、エンドユーザ様を待たせることなく対応が開始できます。

ですので、この通知によって微力ながら顧客満足度により貢献できるのではと考えております。

以上になります。

では、またお会いしましょう。

*1:AWS アカウントの払い出し機会が多いエンドユーザ様では、Lambda 等で OU 移動を自動化している場合もありますが、今回は手動で対応する場合を想定しています

*2:2024年4月にこのコントロールは AWS Foundational Security Best Practices v1.0.0 standard から除外されてしまいましたが、ここでは暗号化したほうが良い文脈で話を進めます

*3:例の Sid に記載のある「CWE」というのは、EventBridge の旧称である「CloudWatch Events」を指しているようなので、Sid が気になるかたはこれも修正したほうがいいでしょう

*4:GUI で生成する方法は以前のブログに記載しておりますので、今回はシンプルに完成形の JSON をご紹介します

*5:補足すると、似た API で RemoveAccountFromOrganization はスタンドアロンの AWS アカウントとして独立する API です

佐竹 陽一 (Yoichi Satake) エンジニアブログの記事一覧はコチラ

マネージドサービス部所属。AWS資格全冠。2010年1月からAWSを利用してきています。2021-2022 AWS Ambassadors/2023-2024 Japan AWS Top Engineers/2020-2024 All Certifications Engineers。AWSのコスト削減、最適化を得意としています。