LoginSignup
0
1

More than 3 years have passed since last update.

Config → EventBridge → SNS → Chatbot → Slack

Last updated at Posted at 2021-05-28

構成

Configで設定変更を検知 >> Event Bridge をトリガーに SNSトピックに通知 >> SNSトピックに設定されているChatbotに情報送信 >> ChatbotがSlackに通知

というのを CloudFormation でデプロイしていこうと思います。

パターン1

1アカウント1つのリージョンにのみ、Configで設定変更を検知した場合に、Slackへ通知するようにしてみたいと思います。

Chatbot

ワークスペースID

チャットクライアントで、Slackを選択し、「クライアントを設定」をする。
スクリーンショット 2021-05-08 13.39.23.png

AWS Chatbot が XXX Slack ワークスペースにアクセスする権限をリクエストするので、「許可する」。
スクリーンショット 2021-05-08 13.42.44.png

ワークスペースIDを控えておく。(後で、CloudFormation へ埋め込むのに必要)
スクリーンショット 2021-05-08 14.57.18.png

チャネルID

Slack のチャネルで右クリックして、「リンクをコピー」。
スクリーンショット 2021-05-09 14.36.48.png

https://XXX.slack.com/archives/12345678901234567890 の部分をチャネルID
として控えておく。(後で、CloudFormation へ埋め込むのに必要)

Config

CloudFormation から
AWSConfigDeliveryChannel
AWSConfigRecorder
を作成しようとした際に、次のように 1 つまでですと怒られることがある。

Failed to put configuration recorder 'AWSConfigRecorder'
because the maximum number of configuration recorders: 1 is reached.

この場合、次のページに書かれている内容で、CLIから削除する必要がある。(コンソールからは削除できない。)

とはいえ、Config は既に有効化されていることが多いので、Config をまだ有効化していないパターンと既に有効化済の2パターンをCloudFormation でデプロイしてみたいと思う。

Config をまだ有効化していない場合

コメントの<>の箇所は適宜自分のものに修正する。

AWS-config-sns-slack1.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: aws config sns slack

Resources:

#S3#

    ConfigS3Bucket:
        Type: AWS::S3::Bucket
        Properties:
            BucketName: <<BucketName>> ##

    S3BucketPolicy:
        Type: AWS::S3::BucketPolicy
        DependsOn: ConfigS3Bucket
        Properties:
            Bucket: !Ref ConfigS3Bucket
            PolicyDocument: 
                Version: 2012-10-17
                Statement: 
                  - 
                    Sid: AWSConfigBucketPermissionsCheck
                    Effect: Allow
                    Principal: 
                        Service: config.amazonaws.com
                    Action: s3:GetBucketAcl
                    Resource: arn:aws:s3:::<<BucketName>> ##
                  - 
                    Sid: AWSConfigBucketExistenceCheck
                    Effect: Allow
                    Principal: 
                        Service: config.amazonaws.com
                    Action: s3:ListBucket
                    Resource: arn:aws:s3:::<<BucketName>> ##
                  - 
                    Sid: AWSConfigBucketDelivery
                    Effect: Allow
                    Principal: 
                        Service: config.amazonaws.com
                    Action: s3:PutObject
                    Resource: !Sub arn:aws:s3:::<<BucketName>>/AWSLogs/${AWS::AccountId}/Config/* ##
                    Condition: 
                        StringEquals: 
                            s3:x-amz-acl: bucket-owner-full-control

#IAM#

    ConfigIAMManagedPolicy:
        Type: AWS::IAM::ManagedPolicy
        Properties:
            ManagedPolicyName: naata-AWS-Chatbot-NotificationsOnly-Policy
            Path: /service-role/
            PolicyDocument: |
                {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Action": [
                                "cloudwatch:Describe*",
                                "cloudwatch:Get*",
                                "cloudwatch:List*"
                            ],
                            "Effect": "Allow",
                            "Resource": "*"
                        }
                    ]
                }

    ConfigIAMRole:
        Type: AWS::IAM::Role
        DependsOn: ConfigIAMManagedPolicy
        Properties:
            Path: /service-role/
            RoleName: naata-Chatbot-role
            AssumeRolePolicyDocument: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"chatbot.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}"
            MaxSessionDuration: 3600
            ManagedPolicyArns:
              - !Ref ConfigIAMManagedPolicy
            Description: naata AWS Chatbot Execution Role

#Chatbot#

    ConfigChatbotSlackChannelConfiguration:
        Type: AWS::Chatbot::SlackChannelConfiguration
        DependsOn: ConfigSNSTopic
        Properties:
            ConfigurationName: naata-ConfigChatbot
            IamRoleArn: !GetAtt ConfigIAMRole.Arn
            LoggingLevel: ERROR
            SlackChannelId: <<>SlackChannelId> ##
            SlackWorkspaceId: <<SlackWorkspaceId>> ##
            SnsTopicArns: 
                - !Ref ConfigSNSTopic

#SNS#

    ConfigSNSTopic:
        Type: AWS::SNS::Topic
        Properties:
            TopicName: naata-ConfigSNSTopic

    ConfigSNSTopicPolicy:
        Type: AWS::SNS::TopicPolicy
        DependsOn: ConfigSNSTopic
        Properties:
            PolicyDocument: !Sub "{\"Version\":\"2008-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:GetTopicAttributes\",\"SNS:SetTopicAttributes\",\"SNS:AddPermission\",\"SNS:RemovePermission\",\"SNS:DeleteTopic\",\"SNS:Subscribe\",\"SNS:ListSubscriptionsByTopic\",\"SNS:Publish\",\"SNS:Receive\"],\"Resource\":\"${ConfigSNSTopic}\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"${AWS::AccountId}\"}}}]}"
            Topics:
              - !Ref ConfigSNSTopic

    ConfigSNSSubscription:
        Type: AWS::SNS::Subscription
        DependsOn: ConfigSNSTopic
        Properties:
            TopicArn: !Ref ConfigSNSTopic
            Endpoint: https://global.sns-api.chatbot.amazonaws.com
            Protocol: https
            RawMessageDelivery: "false"
            Region: !Ref AWS::Region

#config#

    ConfigConfigurationRecorder:
        Type: AWS::Config::ConfigurationRecorder
        Properties:
            Name: default
            RecordingGroup:
                AllSupported: true
                IncludeGlobalResourceTypes: true
            RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig


    ConfigDeliveryChannel:
        Type: AWS::Config::DeliveryChannel
        DependsOn: 
        - ConfigS3Bucket
        - ConfigSNSTopic
        Properties:
            Name: default
            S3BucketName: !Ref ConfigS3Bucket
            SnsTopicARN: !Ref ConfigSNSTopic
            ConfigSnapshotDeliveryProperties:
                DeliveryFrequency: Six_Hours

#Events#

    ConfigEventsRule:
        Type: AWS::Events::Rule
        Properties:
            Name: naata-ConfigEventsRule
            EventPattern: "{\"source\":[\"aws.config\"],\"detail-type\":[\"Config Configuration Item Change\"],\"detail\":{\"messageType\":[\"ConfigurationItemChangeNotification\"]}}"
            State: "ENABLED"
            Targets: 
              - 
                Arn: !Sub "arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${ConfigSNSTopic.TopicName}"
                Id: naata-ConfigSNSTopic
            EventBusName: default

Configを既に有効化済の場合

AWS-config-sns-slack2.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: aws config sns slack

Resources:

#IAM#

    ConfigIAMManagedPolicy:
        Type: AWS::IAM::ManagedPolicy
        Properties:
            ManagedPolicyName: naata-AWS-Chatbot-NotificationsOnly-Policy
            Path: /service-role/
            PolicyDocument: |
                {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Action": [
                                "cloudwatch:Describe*",
                                "cloudwatch:Get*",
                                "cloudwatch:List*"
                            ],
                            "Effect": "Allow",
                            "Resource": "*"
                        }
                    ]
                }

    ConfigIAMRole:
        Type: AWS::IAM::Role
        DependsOn: ConfigIAMManagedPolicy
        Properties:
            Path: /service-role/
            RoleName: naata-Chatbot-role
            AssumeRolePolicyDocument: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"chatbot.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}"
            MaxSessionDuration: 3600
            ManagedPolicyArns:
              - !Ref ConfigIAMManagedPolicy
            Description: naata AWS Chatbot Execution Role

#Chatbot#

    ConfigChatbotSlackChannelConfiguration:
        Type: AWS::Chatbot::SlackChannelConfiguration
        DependsOn: ConfigSNSTopic
        Properties:
            ConfigurationName: naata-ConfigChatbot
            IamRoleArn: !GetAtt ConfigIAMRole.Arn
            LoggingLevel: ERROR
            SlackChannelId: <<>SlackChannelId> ##
            SlackWorkspaceId: <<SlackWorkspaceId>> ##
            SnsTopicArns: 
                - !Ref ConfigSNSTopic

#SNS#

    ConfigSNSTopic:
        Type: AWS::SNS::Topic
        Properties:
            TopicName: naata-ConfigSNSTopic

    ConfigSNSTopicPolicy:
        Type: AWS::SNS::TopicPolicy
        DependsOn: ConfigSNSTopic
        Properties:
            PolicyDocument: !Sub "{\"Version\":\"2008-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:GetTopicAttributes\",\"SNS:SetTopicAttributes\",\"SNS:AddPermission\",\"SNS:RemovePermission\",\"SNS:DeleteTopic\",\"SNS:Subscribe\",\"SNS:ListSubscriptionsByTopic\",\"SNS:Publish\",\"SNS:Receive\"],\"Resource\":\"${ConfigSNSTopic}\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"${AWS::AccountId}\"}}}]}"
            Topics:
              - !Ref ConfigSNSTopic

    ConfigSNSSubscription:
        Type: AWS::SNS::Subscription
        DependsOn: ConfigSNSTopic
        Properties:
            TopicArn: !Ref ConfigSNSTopic
            Endpoint: https://global.sns-api.chatbot.amazonaws.com
            Protocol: https
            RawMessageDelivery: "false"
            Region: !Ref AWS::Region

#Events#

    ConfigEventsRule:
        Type: AWS::Events::Rule
        Properties:
            Name: naata-ConfigEventsRule
            EventPattern: "{\"source\":[\"aws.config\"],\"detail-type\":[\"Config Configuration Item Change\"],\"detail\":{\"messageType\":[\"ConfigurationItemChangeNotification\"]}}"
            State: "ENABLED"
            Targets: 
              - 
                Arn: !Sub "arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${ConfigSNSTopic.TopicName}"
                Id: naata-ConfigSNSTopic
            EventBusName: default

動作確認1

まず、Chatbot >> Slack に通知されるか確認してみたいと思います。

Chatbot の作成されたチャネルを開くと、画面右上に「テストメッセージを送信」があるのでクリックする。
スクリーンショット 2021-05-09 14.52.16.png

Slack に通知されたことを確認する。
スクリーンショット 2021-05-09 14.55.04.png

次に適当な変更を加えて、Slack に通知されるか確認してみたいと思います。
今回は、S3の暗号化を有効にしてみました。

無事、Slack に通知されたことを確認。
スクリーンショット 2021-05-09 17.40.46.png

パターン2

1アカウント全リージョンに対して、Configで設定変更を検知した場合に、Slackへ通知するようにしてみたいと思います。

Config

AWS CloudFormation StackSets サンプルテンプレートを使って、全リージョンにConfigを有効化することも可能である。

ただし、今回は既に有効化されているリージョンもあるためコンソールから個別に有効化していく。設定項目は次の通り。基本的に余計な設定は行わない。SNSはEventBridgeから飛ばすので設定しない。
スクリーンショット 2021-05-16 15.41.17.png
スクリーンショット 2021-05-16 15.41.33.png
スクリーンショット 2021-05-16 15.41.48.png

IAMロール

セルフマネージド型のアクセス許可を付与する にある 2 つのIAMロールをCloudFormationスタックを使って作成する。

AWS-CloudFormationStackSet-Role
AWSTemplateFormatVersion: 2010-09-09
Description: Creating AWSCloudFormationStackSetAdministrationRole and AWSCloudFormationStackSetExecutionRole


Parameters:

  MasterAccountId:
    Type: String
    Description: AWS Account Id of the master account (the account in which StackSets will be created).
    MaxLength: 12
    MinLength: 12

Resources:

#AdministrationRole
  AdministrationRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetAdministrationRole
      AssumeRolePolicyDocument: 
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal: 
              Service: cloudformation.amazonaws.com
            Action: 
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: AssumeExecutionRole
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - sts:AssumeRole
                Resource: 
                  - "arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole"

#ExecutionRole
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetExecutionRole
      AssumeRolePolicyDocument: 
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal: 
              AWS:
                - !Ref MasterAccountId
            Action: 
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess

EventBridge、SNSTopic

Cloudformation StackSets で、EventBridge、SNSTopic を全リージョンにデプロイする。

AWS-config
AWSTemplateFormatVersion: 2010-09-09
Description: Config Slack notification, EventBridge adn SNSTopic creation

Resources:

#Events#

    ConfigEventsRule:
        Type: AWS::Events::Rule
        Properties:
            Name: ConfigEventsRule
            EventPattern: "{\"source\":[\"aws.config\"],\"detail-type\":[\"Config Configuration Item Change\"],\"detail\":{\"messageType\":[\"ConfigurationItemChangeNotification\"]}}"
            State: "ENABLED"
            Targets: 
              - 
                Arn: !Sub "arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${ConfigSNSTopic.TopicName}"
                Id: ConfigSNSTopic
            EventBusName: default

#SNS#

    ConfigSNSTopic:
        Type: AWS::SNS::Topic
        Properties:
            TopicName: ConfigSNSTopic

    ConfigSNSTopicPolicy:
        Type: AWS::SNS::TopicPolicy
        Properties:
            PolicyDocument: !Sub "{\"Version\":\"2008-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:GetTopicAttributes\",\"SNS:SetTopicAttributes\",\"SNS:AddPermission\",\"SNS:RemovePermission\",\"SNS:DeleteTopic\",\"SNS:Subscribe\",\"SNS:ListSubscriptionsByTopic\",\"SNS:Publish\",\"SNS:Receive\"],\"Resource\":\"${ConfigSNSTopic}\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"${AWS::AccountId}\"}}},{\"Sid\":\"AWSEvents_config_Iddbe4eadd-2e0e-433e-acae-40e14a8cf397\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"events.amazonaws.com\"},\"Action\":\"sns:Publish\",\"Resource\":\"${ConfigSNSTopic}\"}]}"
            Topics:
              - !Ref ConfigSNSTopic

「StackSets」 をクリック。
スクリーンショット 2021-05-15 1.55.58.png

「StackSetsの作成」 をクリック。
スクリーンショット 2021-05-15 1.59.37.png

ステップ 1 テンプレートの選択

ここは、スタックの作成と同じように、Amazon S3 URLまたは、テンプレートファイルのアップロードを行う。
スクリーンショット 2021-05-15 15.08.20.png

ステップ 2 StackSet の詳細を指定

「StackSet 名」を入力。
スクリーンショット 2021-05-15 15.29.52.png

ステップ 3 StackSet オプションの設定

「セルフサービスのアクセス許可」を選択。
IAM 管理ロール ARN は先程CloudFormationスタックで作成されたIAMロールを選択。
スクリーンショット 2021-05-15 15.33.25.png

ステップ 4 StackSet にスタックを追加
「スタックをアカウントにデプロイ」を選択し、「アカウント番号」を入力。
スクリーンショット 2021-05-15 15.37.51.png

デプロイするリージョンを選択する。
スクリーンショット 2021-05-15 15.39.20.png

ステップ 5 レビュー
「AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。」にチェックを入れる。
スクリーンショット 2021-05-15 15.43.27.png

Chatbot

ChatbotワークスペースとChatbotチャンネルを作成していく。

  • Chatbotワークスペース:この記事の最初の部分で紹介済なので作成方法は割愛する。
  • Chatbotチャンネル:CloudFormationスタックで作成していく。
AWS-Chatbot
AWSTemplateFormatVersion: '2010-09-09'
Description: Creating a slack channel

Parameters:
  SnsTopicName:
    Type: String
    Default: ConfigSNSTopic
  SlackWorkspaceId:
    Type: String
    Default: XXXXXXXXX
  SlackChannelId:
    Type: String
    Default: YYYYYYYYY

Resources:

#Chatbot用 IAMロール
  ChatbotIamRole: 
    Type: AWS::IAM::Role
    Properties: 
      RoleName: ChatbotIamRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action: "sts:AssumeRole"
            Principal:
              Service: "chatbot.amazonaws.com"
      Policies: 
        - PolicyName: AWS-Chatbot-NotificationsOnly-Policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Action:
                  - "cloudwatch:Describe*"
                  - "cloudwatch:Get*"
                  - "cloudwatch:List*"
                Effect: "Allow"
                Resource: "*"

#Chatbot
  ChatbotConfiguration:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties: 
      ConfigurationName: Config-Chatbot-SlackChanel
      IamRoleArn: !GetAtt ChatbotIamRole.Arn
      LoggingLevel: ERROR
      SlackChannelId: !Ref SlackChannelId
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SnsTopicArns: 
        - !Sub 'arn:aws:sns:ap-northeast-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:ap-northeast-2:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:ap-northeast-3:${AWS::AccountId}:${SnsTopicName}'
        - !Sub 'arn:aws:sns:ap-south-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:ap-southeast-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:ap-southeast-2:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:ca-central-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:eu-central-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:eu-north-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:eu-west-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:eu-west-2:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:eu-west-3:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:sa-east-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:us-east-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:us-east-2:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:us-west-1:${AWS::AccountId}:${SnsTopicName}' 
        - !Sub 'arn:aws:sns:us-west-2:${AWS::AccountId}:${SnsTopicName}'

動作確認2

適当なリソースを作成や変更をして、Slack に通知されたことを確認する。
スクリーンショット 2021-05-16 16.00.49.png

0
1
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
1