CodePipelineの実行結果をAWS ChatBotでSlackに通知するCloudformation

AWS ChatBotで簡単にSlackに通知が出来るようになったということで、やはりCodePipelineの実行結果をSlackに通知したいですよね。

ということで、CodePipelineの実行結果を通知するChatBotを出来る限りCloudFormationで構成していきたいと思います。

# ワークスペースの設定

出来る限りCloudFormationで。と書いたのは、最初に行うワークスペースのクライアント設定についてはCloudFormationに対応していないためです。
Slackへのアクセス権の許可ステップなどがあるのでここは仕方がないですね。
ChatBotのクライアント設定はコンソールから実施しておきます。

参考: [AWS Chatbot を利用して AWS 開発者用ツールの通知を Slack で受け取る方法](https://aws.amazon.com/jp/blogs/news/receive-aws-developer-tools-notifications-over-slack-using-aws-chatbot/)

上記ドキュメント内の手順2にあるSlackのパーミッション要求を許可してクライアントを設定する箇所だけ完了しておけば残りの作業はCloudFormationで記述可能です。

# ChatBotチャネルの設定

ChatBotのクライアントはSlackのワークスペースと1対1の関係にあります。
チャネルはその中で通知を投稿するSlackチャンネルと1対1に対応します。

SlackのチャンネルIDとChatBotのワークスペースIDを引数に取る以下のCFnでChatBotチャネルを構成します。

```chatbot-channel.yml
Parameters:
  NotifySlackChannel:
    Type: String
    Description: Slack Channel ID
  NotifyChatbotWorkspaceId:
    Type: String
    Description: Chatbot Workspace ID
Resources:
  PipelineNotificationChatbotRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub service-role-for-pipeline-notification-chatbot
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          -
            Effect: Allow
            Principal:
              Service:
                - chatbot.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess
  PipelineNotificationChatbot:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: pipeline-notification-chatbot
      IamRoleArn: !GetAtt PipelineNotificationChatbotRole.Arn
      LoggingLevel: ERROR
      SlackChannelId: !Ref NotifySlackChannel
      SlackWorkspaceId: !Ref NotifyChatbotWorkspaceId
```

### SlackのチャンネルID

チャンネルリストで該当のチャンネルを右クリックし、[その他のオプション]→[リンクをコピー]して、エディタなどに貼り付けたURLの末尾にある文字列です。

![slack-channel-id.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204890/a71563ec-f22a-1d8f-6340-11ca423c2f09.jpeg)

```text
https://example.slack.com/archives/${SlackChannelID} #<-ここ
```

### ワークスペースID

ChatBotのワークスペースは、コンソールからChatBotの設定済みクライアントを開いて該当のワークスペースを開くことで確認出来ます。

![workspace.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204890/f5e78727-4891-f9d2-7db9-b306f14e8cf6.jpeg)

# CodePipelineの通知を作成

DeveloperTools関係のサービスの通知を作成するには CodeStartNotificationsのNotificationRuleを用いて構築します。

参考:[CloudFormation - AWS::CodeStarNotifications::NotificationRule](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html)

構築するテンプレートは以下のようになります。

```pipeline-notification-rule.yml
Parameters:
  PipelineName:
    Type: String
    Description: Target Pipeline Name
  ChatBotArn:
    Type: String
    Description: AWS ChatBot ARN
Resources:
  PipelineNotificationRule:
    Type: AWS::CodeStarNotifications::NotificationRule
    Properties:
      Name: pipeline-notification-rule
      DetailType: FULL
      Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref PipelineName ] ]
      EventTypeIds:
        - codepipeline-pipeline-pipeline-execution-succeeded
        - codepipeline-pipeline-pipeline-execution-failed
        - codepipeline-pipeline-pipeline-execution-canceled
      Targets:
        -
          TargetType: AWSChatbotSlack
          TargetAddress: !Ref ChatBotArn
```

### EventTypeIds

通知するイベントタイプのIDをリストで指定します。
サポートしているIDのリストは、ドキュメントとしては見つけられませんでしたが、AWS CLIから取得できます。

```bash
aws codestar-notifications list-event-types --filters Name=SERVICE_NAME,Value=CodePipeline
```

上記のコマンドを実行すると、CodePipelineでサポートするイベントタイプのリストが取得できます。

```
{
    "EventTypes": [
        {
            "EventTypeId": "codepipeline-pipeline-action-execution-succeeded",
            "ServiceName": "CodePipeline",
            "EventTypeName": "Action execution: Succeeded",
            "ResourceType": "Pipeline"
        },
        {
            "EventTypeId": "codepipeline-pipeline-action-execution-failed",
            "ServiceName": "CodePipeline",
            "EventTypeName": "Action execution: Failed",
            "ResourceType": "Pipeline"
        },
        {
            "EventTypeId": "codepipeline-pipeline-stage-execution-started",
            "ServiceName": "CodePipeline",
            "EventTypeName": "Stage execution: Started",
            "ResourceType": "Pipeline"
        },
        ...
    ]
}
```

この中から、通知を受け取りたいイベントを選択してEventTypeIdsに指定します。

### TargetType

TargetTypeで指定可能な値は今のところ次の2つのようです。

| ターゲット | Value |
|:--:|:--:|
| Amazon SNS topic | SNS |
| AWS Chatbot client | AWSChatbotSlack |

指定可能な値のリストは見つけられませんでした。
現時点では以下のURLのサンプルでのみ確認しています。
参考: [AWS User Guide - View Notification Rule Targets](https://docs.aws.amazon.com/ja_jp/codestar-notifications/latest/userguide/notification-target-view.html)

# 実行

ここまでのCloudFormationをデプロイすると、CodePipelineの実行後に通知がSlackに届くようになります。

![chatbot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204890/4de79147-3a08-3d66-e81d-e74de8b504f6.jpeg)

通知のLambdaコード等を書かずにPipeline結果がSlackに通知されるのは捗りますね！