GitHub WebhooksとAWS Lambdaを連携してデプロイとSlack通知を同時に行う

#はじめに
プルリクがdevelopブランチにマージされたとき、ステージング環境へのデプロイとSlack通知を同時に行う機能を以下の構成(GitHub Webhooks, Slack Incomming Webhooks, API Gateway, Lambda, OpsWorks)で実装しました。

各設定についてまとめましたので、参考にしていただければ幸いです(OpsWorksの設定については記載しません)。

*Webhookとは、Webサービスがサービス内で起こったイベントをトリガーに、所定のURLにパラメータを渡してコールしてくれる機能です。
![スクリーンショット 2021-02-02 11.02.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/9bd59524-8b13-473b-6f91-1887258e4f19.png)

#実施事項
**1. SlackのIncoming Webhooksで通知先のチャンネルを登録し、Webhook URLを発行する。
2. Lambdaの関数コードにOpsWorksの自動デプロイとSlack通知の内容を記述する。
3. API Gatewayでエンドポイントの発行とLambdaの登録を行う。
4. GitHubのWebhooksでGitプッシュイベントが起こったときのエンドポイントにAPI Gatewayを指定する。**

## Slack Incomming Webhooksの設定
SlackのアプリケーションからIncomming Webhooksを選択します。
投稿したいチャンネルを選択してIncomming Webhookインテグレーションの追加を押します。
![スクリーンショット 2021-02-02 10.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/ca8020d3-9dd1-7a52-eb0f-546cf7f5ea4e.png)

Webhook URLを控えます。Lambdaの関数コードで通知先を指定するときに使用します。
![スクリーンショット 2021-02-02 10.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/5e4227d8-8d44-b550-aa54-52fc1b0d48b4.png)

名前やアイコンのカスタマイズを行なって設定を保存します。
![スクリーンショット 2021-02-02 10.38.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/7de5e6ae-ecc2-af54-40a7-089ba718bb46.png)

## Lambda関数の作成
AWS Lambdaで関数の作成をクリックします。
関数名を入力して、既存のロール(lambda_basic_execution)をアタッチし、関数を作成します。
![スクリーンショット 2021-02-02 17.57.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/c62a7b7c-336b-6c33-cd6d-8edaf9e25a15.png)

以下の画面になるので、関数コードに実行したい内容を記述します。
![スクリーンショット 2021-02-02 18.06.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/63f48c55-d2b4-0636-3b19-9d381f08c607.png)

Slackへの送信内容についての記述は<a href="https://www.te-nu.com/entry/2018/08/05/164117">こちらのサイト</a>を参考にしました。
ここでSlack Incomming Webhooksの設定で取得したWebhook URLを記述します。

```javascript
 let options = {
    host: "hooks.slack.com",
    path: "[Webhook URLのパス]",
    port: 443,
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
  };
```
また、postDataについてもカスタマイズしました。

```javascript
        fields: [
          {
            title: "Webhook Repository",
            value: repo,
            short: true,
          },
          {
            title: "Repository Branch",
            value: branch,
            short: true,
          },
          {
            title: "OpsWorks Stack",
            value: stack,
            short: true,
          },
        ],
        footer: "Pushed by " + uname,
```
デプロイするソースコードのリポジトリとブランチをStackId、StackName、AppIdと紐付けます。

```javascript
var deployMap = {
  '[リポジトリ名]': {
    "refs/heads/[ブランチ名]": {
      StackId: '[StackId]',
      StackName: '[StackName]',
      AppId: '[AppId]',
    }
  },
};

```
以下でデプロイとSlack通知を実行します。
eventはGitプッシュ時にGitHub Webhooksから取得されるデータとなります。

```javascript
var opsworks = new aws.OpsWorks();

exports.handler = async (event, context, callback) => {
                      .
                      .
                      .
    const data = await opsworks.createDeployment(params).promise();

    let message = "デプロイするよ〜〜〜！！！";
    let repo    = event.repository.name;
    let branch  = event.ref;
    let stack   = deployMap[event.repository.name].StackName;
    let uname   = event.pusher.name;
    let log_url = '[log出力先URL]' + params.StackId + '/deployments/' + data.DeploymentId;
    
    await postToSlack( message, repo, branch, stack, uname, log_url );
```

## API Gatewayの設定
API GatewayでGitHubでのプッシュイベントのPOST先のエンドポイント(WEB APIを利用するときのURI)を作成します。

リソースの作成を行います。
![スクリーンショット 2021-02-02 18.37.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/8778a7ca-f8dd-e4ca-7dc0-15b1727be583.png)

POSTメソッドを作成しLambda関数の名前を入力して保存します。
![スクリーンショット 2021-02-02 18.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/abfa208e-b153-aeb7-3c2b-60b2ea140365.png)

最後にリソースのアクションでAPIのデプロイを実行してエンドポイントを作成します。
ステージでURLが作成されたことを確認することができます。
![スクリーンショット 2021-02-02 18.40.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/7abcb2ef-a9a4-0e1a-de68-7c2d85f04216.png)


## GitHub Webhooksの設定
リポジトリのSettings→WebhooksからAdd webhookを押します。
![スクリーンショット 2021-02-02 9.55.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/dc74b875-bdb4-9d8b-688a-7100b59a22e3.png)

Webhooksの設定をします。
Payload URLには前工程で作成したエンドポイントのURLを入力し、Content typeにはapplication/jsonを選択します。
![スクリーンショット 2021-02-02 10.27.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/bdf92d8c-907c-e6c6-f42f-ebda449f0f9e.png)

# おわりに
以上の設定を行うことで、デプロイと同時にこんな感じでSlackに通知を飛ばすことができます。
LambdaとAPI Gatewayを使ったのは初めてだったので勉強になりました。

![スクリーンショット 2021-02-02 11.16.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/1ddb8eb5-e064-79c7-c275-a234ee9b3771.png)