AWS CodePipelineでGitHubのソースをS3へデプロイする

## はじめに
CodePipeline 設定手順の備忘録。

## やりたいこと

- GitHubへのpushをトリガーにして、S3に自動デプロイしたい
- 環境を分けたい（開発、ステージング、本番）
- デプロイ結果をslack通知したい

## 構成図

![code1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/0f7e2eff-2c60-6745-3086-084805062e4f.png)

※ ng new コマンドで作成した Angular のサンプルコードをデプロイします。


## 設定手順

### 1. CodePipeline の設定

「パイプラインの作成」から作成を開始します。
![スクリーンショット_2021-03-14_22_17_22（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/bec52669-6aa0-1bd6-7152-b72951b54b94.png)

パイプライン名を入力して、初回はロールを新規で作成します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/7161c85c-ad06-79b1-ae8e-e7b492b5af0b.png)

ソースプロバイダーはGitHubを選択。（バージョン1は非推奨となっているため、バージョン2を選択。）

参考：

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/update-github-action-connections.html

![スクリーンショット 2021-03-14 22.16.06（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/0f21a1bc-79fb-9a44-2cf9-75ff400c7c42.png)

「新しいアプリをインストールする」を選択。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/a9cf9309-5095-350d-ae95-38c31c867831.png)

リポジトリを選択し、「Install」を押下します。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/7e4a61f9-db41-ba00-08f7-5f3c652461d8.png)

CodePipelineの設定画面に戻るので、リポジトリとブランチを選択します。
~~（開発やステージング、本番で環境を分けて使う場合は、環境ごとにブランチとパイプラインを作成するのがいいのでしょうか？）~~  → 環境ごとにブランチを分ける、というのは本来のgitの使い方ではないためNG
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/d3b6cbe1-ef0b-c8dd-4119-d442a63211cb.png)

次にビルドステージを設定します。
AWS CodeBuild と Jenkins が選択可能ですが、ここでは AWS CodeBuild を選択。
「プロジェクト名」項目では、「プロジェクトを作成する」を選択する。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/d0ffa08c-ee5f-9fba-24a2-bfd46a26b1e5.png)


プロジェクトを作成します。
（ここで設定した環境変数は、buildspec.ymlで呼べるらしい。）
![screencapture-ap-northeast-1-console-aws-amazon-codesuite-codebuild-project-new-2021-03-14-14_31_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/3bc63bec-0115-ec5b-19b5-2a0fe53f8a8d.png)


最後にデプロイステージの設定。S3を選択します。（バケットは事前に作成しておきます）
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/922553e8-59ac-5206-d81e-1ee7e4a57e23.png)

設定が完了すると、設定したパイプラインが実行されますが、CodeBuild の実行で失敗します。
CodeBuild を実行するには、buildspec.yml というyamlファイルにビルド時に実行するシェルコマンドを記述し、デプロイするソースコードのルートディレクトリに配置する必要があります。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/684058f8-82f4-5345-5888-2e4e28887efb.png)

ルートディレクトリに以下のような buildspec.yml を作ります。
ng build で出力された dist ディレクトリ配下のファイルを S3 にアップロードしています。

```bash
version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 12
    commands:
      - npm install -g
      - npm install --save-dev @angular-devkit/build-angular
      - npm install -g @angular/cli
  build:
    commands:
      - ng build
      - aws s3 sync dist s3://src-2021/application
artifacts:
  files:
    - '**/*'
  base-directory: 'dist*'
```



参考：

https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html#runtime-versions-buildspec-file

（runtime-versions で指定する node.js のバージョンは、10と12のみのようです。）
![node_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/da77f4dd-89a9-6d6e-3cb4-75f3bb825f8a.png)

buildspec.yml を git push すると、パイプラインが実行され、今度は成功です。
![success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/e749a6e8-9284-2c42-632a-ed2ca76b9e1b.png)

S3 にデプロイされました。
![S3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/be98f309-d12c-d1d7-e3ab-d3d2b29a9ad1.png)

備考：
CodeBuild のロールに S3 へのアクセス許可ポリシーをアタッチしておく必要あり。
![iam_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/1fb1f5db-b4ed-a500-8dfb-ca9e6f2e9612.png)

### 2. slack への通知設定
CodePipeline, CodeCommit, CodeBuild は、SNS もしくは ChatBot と連携ができるので、
ChatBot と連携させて slack　通知します。
![通知_pipeline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/ea39328b-e215-c29f-ab55-9d081d73e20f.png)

成功や失敗時以外にも、トリガーとなるイベントがいろいろ選択可能です。
![通知_pipeline2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/f3ea8951-ffcb-0aff-a7be-a160db52578c.png)

設定後、再度パイプラインを実行して、slack通知を確認できました。
![slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917499/4b69f8d8-f0ba-a61b-21ad-3b4a655d4cfe.png)

以上で設定完了です。

## 追記
・GitHubへのpushをトリガーするというのは、手軽にデプロイができすぎてしまうので、本番環境の場合は考える必要がある。