SlackからCodeBuildを走らせるシンプルな方法

# はじめに
AWSビギナーによる自由研究です。SlackからAWS CodeBuildを走らせる方法を試してみました。
（最終的な活用イメージは[こちら](#活用イメージ)）

# 概要
構成の全体像と、今回活用したAWSの各サービスの概要を紹介します。

## 全体構成
Slackから、ChatbotとLambdaを経由してCodeBuildを起動します。

1. Slack workflowからデプロイをkick
1. Chatbot、Lambda経由でCodeBuildをstart
1. CodeBuildの実行ステータスをChatbot経由でSlackにpost

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/d9367022-ac53-7358-a698-96a7a7ea6f04.png)

## 各サービスの役割
今回は、Chatbot・Lambda・CodeBuildの3つのAWSのサービスを使用します。
### Chatbot
AWS内⇔AWS外のインターフェース機能です。
今回はSlackとAWSの接続に活用し、下記を実行します。

- SlackからLambdaを起動
- CodeBuildの実行ステータスをSlackに通知

### Lambda
サーバーレスでプログラムを実行できるサービスです。
今回は、CodeBuildによるビルドを開始するプログラムとして活用します。

### CodeBuild
AWS上で動作するビルドサービスです。
今回は下記を実行するよう設定済みです。（本題から外れるため、詳細は割愛します。）

- ビルド（GitHub上のソースコードを、実際に動作するプログラムに変換）
- デプロイ（ビルド成果物をS3に配置）
- リリース（CloudFrontのキャッシュクリア）

# 手順
具体的な設定手順です。
## 1. Chatbotの作成
AWSと連携したいSlackチャネルを登録したChatbotを作成します。
ロールには下記ポリシーをアタッチしておきます。

- 通知のアクセス許可
- Lambda呼び出しコマンドのアクセス許可

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/932bf055-9bf2-51cc-53de-8a7e0ca50b4b.png)

## 2. Lambda関数の作成
CodeBuildの開始に必要なロールを作成した上で、このロールを持たせたLambda関数を作成します。

**ロールを作成**
下記ポリシーを持つロールを作成します。

- AWSLambdaBasicExecutionRole（AWS管理ポリシー）
- CodeBuildのポリシー（下記JSONで作成）

```json:json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "codebuild:StartBuild",
            "Resource": "{CodeBuildのリソース名}"
        }
    ]
}
```

**Lambda関数を作成**
Lambda関数のメタデータを作成します。

- 上記で作成したロールを適用
- 今回はランタイムにpython 3.8を選択

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/6e9d0ac3-3908-7c4c-a859-b6e3222142f2.png)

**関数のコードを記述**
Lambda関数のコード部分を書いていきます。

- `event[xxx]`は、SlackからChatbot経由で送信可能な変数
- projectName、sourceVersionはCodeBuildの設定や命名に合わせて記載

```py:Lambda
import os
import boto3
from logging import getLogger, INFO

logger = getLogger()

codebuild_client = boto3.client('codebuild')

def lambda_handler(event, context):
    codebuild_client.start_build(
        projectName=event["target_env"] + '{リポジトリ名等}', //CodeBuildのプロジェクト名
        sourceVersion=event["target_branch_name"]
    )
```

## 3. CodeBuildの通知ルールを作成
CodeBuildの対象プロジェクトから、通知ルールを作成します。
これにより、CodeBuildの実行ステータスをChatbot経由でSlackに通知できます。

**"通知"メニューから通知ルール作成画面に遷移**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/e39a5927-eff8-03fc-3ea9-557441ffd89f.png)

**お好みのイベントを選択**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/b3f70774-213e-7378-873c-44161f176ebe.png)

**ターゲットはターゲットタイプ：`AWS Chatbot　(Slack)`から今回作成したChatbotを選択**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/2555545b-b040-2d31-144f-733115679fba.png)

## 4. SlackチャネルにChatbotを招待
下記コマンドでChatbotをチャネルに招待することで、該当のSlackチャネルからChatbotを操作できるようになります。

```text:Slack
/invite @aws
```

あとは、Slackチャネルで下記コマンドを打てばCodeBuildが走りだすはずです。

``` text:Slack
@aws invoke {Lambda関数名} --payload {“target_env”: “xxx”, “target_branch_name”: “xxx”}
```

## 5. 起動コマンドのworkflow化
上記コマンドを毎回打つのは面倒ですよね。起動コマンドをworkflow化しておきましょう。
下記は参考記事です。

 - [Slack でワークフローを設定する](https://slack.com/intl/ja-jp/help/articles/360053571454-Slack-%E3%81%A7%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)
 - [AWS ChatbotからのLambda起動をCloudFormationとSlackワークフローで使いやすくする - Slackワークフローの作成](https://dev.classmethod.jp/articles/chatbot-lambda-cfn/#toc-6)

# 活用イメージ
**1. Slack Workflowでデプロイ条件を指定しSubmit**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/538fffe5-2064-dea4-bd5e-980547591533.png" width="500px">

**2. 内容に問題なければ"Run"ボタンをクリック**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/ef09931d-1223-97f0-96ba-9d2cbdb4813b.png" width="750px">

**3. CodeBuildが走りだし、実行ステータスの通知を受領**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2322844/47aeaf3c-3b3f-45e4-cf3e-bcdbef217482.png" width="500px">

# 最後に
シンプルな構成なので手順も簡単だったと思います。
目に見える効果がありつつAWSの複数のサービスが触れて、AWSビギナーとしては良い題材でした。
CodePipelineやStep Functionsを使うと、より高度な仕組みを構築できそうなので、今後チャレンジしてみたいと思います。
（参考）[AWS Step Functions を利用したCI フローについて](https://qiita.com/saba_can00/items/071aef60542b3ff19d46)

# 参考
[Slack と AWS Chatbot で ChatOps をやってみよう](https://aws.amazon.com/jp/builders-flash/202006/slack-chatbot/?awsf.filter-name=*all)
[SlackでAWS Lambdaを実行してみた](https://dev.classmethod.jp/articles/execute-lambda-function-with-slack/)