CodebuildでS3に静的ホスティングを自動化

## 概要
- 10分程で設定可能です。
- AWS Codebuildでビルドを行う。
- Amazon S3に静的ホスティングをする。
- GithubをWebhookして、上記を自動化する。

## 登場人物の紹介
### AWS Codebuild
![codebuild.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/389b3342-49bc-e0e3-0bde-ba329a6acc63.jpeg)

 AWS CodeBuild は、クラウドで動作する完全マネージド型のビルドサービスです。CodeBuild はソースコードをコンパイルし、ユニットテストを実行して、すぐにデプロイできるアーティファクトを生成します。CodeBuild により、独自のビルドサーバーのプロビジョニング、管理、スケーリングが不要になります。Apache Maven、Gradle などの一般的なプログラミング言語とビルドツール用のパッケージ済みのビルド環境を提供します。CodeBuild のビルド環境をカスタマイズして、独自のビルドツールを使用することもできます。CodeBuild​ はピーク時のビルドリクエストに合わせて自動的にスケーリングします。 [公式](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/welcome.html)
 
要するに、**『ビルドを行い、ユニットテストを実行し、すぐにデプロイできるバイナリファイル的なものを作成する』**です。

### Amazon S3
![Amazon S3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/d9668a3a-de8d-680b-9ab7-785aa88641df.png)

 Amazon S3は、Amazon Simple Storage Service はインターネット用のストレージサービスです。また、ウェブスケールのコンピューティングを開発者が簡単に利用できるよう設計されています。
Amazon S3 のウェブサービスインターフェイスはシンプルで、いつでも、ウェブのどこからでも容量に関係なくデータを格納および取得できます。これにより、すべての開発者が、スケーラブルで信頼性が高く、かつ高速で安価なデータストレージインフラストラクチャを利用できるようになります。このインフラストラクチャは、Amazon が使用しているウェブサイトのグローバルネットワークと同じものです。このサービスの目的は、規模の拡大や縮小のメリットを最大限に活かし、開発者に提供することです。

要するに、**『ほぼ無限大に入るストレージ』**です。[公式](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/Welcome.html)

### Github
![github.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/e8c9fcd6-336c-b2f9-87bc-ff5867c6b3ac.png)

省略

以上で登場人物の紹介を終わります。

## 具体的な設定等
### ディレクトリ構造
 AWSでCodeBuildする際は、ディレクトリ構造を正確に把握しておくことが非常に重要です。
 私の場合は、以下のようなディレクトリ構造になっています。
 今回、AWS Codebuildでビルドを行い、デプロイしようとしているのは、frontディレクトリの中身です。 これらのコードをbackendやdatabaseも含めてGithubの任意のリポジトリにPushしておきます。
<img width="234" alt="スクリーンショット 2020-01-14 12.06.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/fb337e13-f89d-6645-f221-d4512d4fe398.png">

### package.jsonのscript部分の内容
```
"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
```

### buildspec.ymlの内容
```
version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 10
  pre_build:
    commands:
      - echo Installing source NPM dependencies...
      - cd front
      - yarn install
  build:
    commands:
      - yarn build
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Distributing to S3...
      - aws s3 sync --exact-timestamps --delete build s3://[デプロイ先バケット名]

```
ディレクトリ構造によっては、pre_buildの`cd front`などが不必要 (各々のディレクトリ構造に合わせて下さい)。

### CodeBuild設定
1. AWSマネジメントコンソールにログイン
2. ログイン後、CodeBuildサービスを選択し、プロジェクトの作成を押下
3. 任意のプロジェクト名を入力
<img width="1440" alt="スクリーンショット 2020-01-14 12.13.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/caf15f2e-0c4d-7cba-4466-f0a92a0d32d8.png">

4. 送信元の設定
・ソースプロバイダ・・Github
・リポジトリ・・Githubアカウントのリポジトリ
・Githubリポジトリ・・先ほどのコードをPushしたリポジトリを選択
<img width="1360" alt="スクリーンショット 2020-01-14 12.14.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/01901431-23f9-12bb-3659-d9ef1a6c8691.png">

5. プライマリソースのウェブフックイベント設定
・ウェブフックオプショナル・・・チェック
・イベントタイプ・・・PULL_REPULL_REQUEST_MERGEDを選択（任意のイベントタイプを選択可）

<img width="1368" alt="スクリーンショット 2020-01-14 12.15.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/03f6ce06-5714-d80c-797e-fe9b46d4d412.png">

6.　環境の設定
・環境イメージ・・・マネージド型イメージ
・オペレーティングシステム・・・Ubuntsu
・ランタイム・・・Standard
・イメージ・・・最新のもの
・イメージのバージョン・・・最新のもの
・環境タイプ・・・Linux

<img width="1417" alt="スクリーンショット 2020-01-14 12.15.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/ecf1e99c-85a5-9597-f17e-1d6c6e0489ae.png">

7.　サービスロールの設定
以下の画像では、既存のサービスロールとなっていますが、初めて使用する方は、新しいサービスロールを選択してください。選択すると、自動でロールのARNが入力されます。

<img width="1360" alt="スクリーンショット 2020-01-14 12.16.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/c884fbbc-f443-22aa-5ba4-eda60d772b7c.png">

8.　Buildspec設定&アーティファクト設定
・ビルド仕様・・・buildspecファイルを使用
・Buildspec名オプショナル・・・front/.buildspec.yml（ディレクトリ構造を紹介した際に、frontの階層の下に、.buildspec.ymlファイルを置いているのがわかるように、今回ビルドする際の設定ファイルをfront/.buildspec.ymlに置いているので、ここを指定します。）
・アーティファクト・・・特に設定しない

<img width="1368" alt="スクリーンショット 2020-01-14 12.17.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/d2eda545-e90c-342b-064e-db91c4183c8e.png">

以上でCodebuildの設定が終了です。

### Amazon S3設定
1. AWSマネジメントコンソールにログイン
2. ログイン後、Amazon S3サービスを選択し、バケットの作成を押下
3. 任意のバケット名を入力し、作成

<img width="1375" alt="スクリーンショット 2020-01-14 12.22.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/4960a747-3e9e-a425-de8c-9e0cd962cd31.png">

4.　作成後、バケットのプロパティの、Static website hostingを選択
<img width="1373" alt="スクリーンショット 2020-01-14 12.23.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/42a1159d-55c0-44e3-b577-83274bfdaaac.png">

5.　Static website hosting設定
・インデックスドキュメント・・・任意のルートファイル(大抵はindex.htmlとなる。)

<img width="1345" alt="スクリーンショット 2020-01-14 12.23.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/8d05e242-b24d-1826-8ee8-70cc9344f2b9.png">

6.　バケットのプロパティのアクセス権限設定のブロックパブリックアクセス設定
以下の画像のように設定する。
<img width="1376" alt="スクリーンショット 2020-01-14 12.31.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/47540d1f-9d1c-3d18-dac6-a4038341b8bb.png">

7.　バケットのプロパティのアクセス権限設定のバケットポリシー設定（セキュリティレベルは自己のサービスなどに合わせて、変更お願いします。）
<img width="1312" alt="スクリーンショット 2020-01-14 12.33.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/527ccf02-4cda-4fb5-57a0-8f8b84b6276d.png">


以上でAmazon S3の設定が終了です。

## 動作確認
Githubのリポジトリに対して、PullRequestがマージされると、CodeBuildが自動で走り、以下の画像のように全てSuccessとなると成功です。S3のホスティングしているURLにアクセスすると、任意のものが表示されるのを確認してください。

<img width="1414" alt="スクリーンショット 2020-01-14 12.25.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395817/fdc45e89-27f2-242f-134f-ad2761464c73.png">

以上で全ての設定が終了です。


次回はバックエンド側（Go）のデプロイフローとして、CodePipeline, CodeBuild, CodeDeploy, ECSを使用した方法について書こうと思います。