初学者によるDocker理解まとめ⑥　〜CodeDeployとCodePipelineを使ってEC2インスタンスにdockerコンテナを自動デプロイするまで〜

# はじめに
ようやくDockerを学び始めたので自分の理解をまとめておく。

前回 => https://qiita.com/theFirstPenguin/items/bdaf0035e7b44cd33822

# やったこと
* [前回](https://qiita.com/theFirstPenguin/items/bdaf0035e7b44cd33822)の続き
* [前回](https://qiita.com/theFirstPenguin/items/bdaf0035e7b44cd33822)はgithubのレポジトリを`git clone`し、updateの度に`git pull` + `docker-compose up`していた。
* 上記の一連の動作を`CodeDeploy`を使って置換する
* `CodePipeline`を使って上記一連の流れを自動化する
![スクリーンショット 2020-10-26 17.09.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/b98af18c-7f74-a273-10c0-0b766fc66d23.png)


そして今回もdockerはあまり関係ありません。。

# 前提
[前々回](https://qiita.com/theFirstPenguin/items/b5f6ed253bed95fbec5a)の時点でEC2インスタンスを起動して`docker`と`docker-compose`をインストールできている状態。
![スクリーンショット 2020-10-26 14.05.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/ce06fc4c-680a-e503-4e5d-e18512203430.png)

# 手順
* EC2インスタンスに`CodeDeployエージェント`をインストール
* `AWSCodeDeployRole`ポリシーをアタッチしたIAMロールを作成し、EC2インスタンスにアタッチ
* `CodeDeploy`の設定
    * アプリケーションの作成
    * デプロイメントグループの作成
    * `appspec.yml`と`ApplicationStart.bash`の作成
    * デプロイの作成
* `CodePipeline`の設定

## EC2インスタンスに`CodeDeployエージェント`をインストール
[ここ](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html)と[ここ](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/resource-kit.html#resource-kit-bucket-names)を参照

```
# まずはEC2にログイン
ssh -i "ec2-key.pem" ec2-user@XXX.YYY.ZZZ.XXX

# インストール
sudo yum update
sudo yum install ruby
sudo yum install wget
cd /home/ec2-user

# ここは環境ごとにbucket-nameとregion-identifierを変更する
wget https://bucket-name.s3.region-identifier.amazonaws.com/latest/install

chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent status
```

ちなみに、上記をインスタンス起動設定のユーザーデータに記載しておけば、AutoScallingなどのインスタンス作成時に自動的に実行される。今回は関係ないけど。


## `AWSCodeDeployRole`ポリシーをアタッチしたIAMロールを作成し、EC2インスタンスにアタッチ

###まずはIAMコンソールからロールの作成を選択
![スクリーンショット 2020-10-26 14.32.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/5f6794c4-93e9-f39b-ad32-6c6253855d4e.png)

### エンティティとしてEC2を選択
![スクリーンショット 2020-10-26 14.33.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/2f85cb84-805d-5100-8f44-f82156d1d938.png)

### `AWSCodeDeployRole`ポリシーをアタッチ
![スクリーンショット 2020-10-26 14.36.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/f7fbf65d-0c0b-1329-7c29-c9d332e708d9.png)

### 適当なタグとロール名をつけて、ロールを作成
![スクリーンショット 2020-10-26 14.44.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/1260a269-03a1-2345-9602-d8dd909c2c9d.png)

### EC2インスタンスに作成したロールをアタッチ
![スクリーンショット 2020-10-26 15.04.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/aa0ba2fa-00ab-4921-f0aa-2f71d903d207.png)
![スクリーンショット 2020-10-26 15.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/d2763e99-3efd-2e36-b0fd-3ed56a9053de.png)

##`CodeDeploy`の設定
### まずはCodeDeployコンソール
![スクリーンショット 2020-10-26 15.11.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/6ad56a6f-dc6a-9f1f-8ea2-dd59df069266.png)

### アプリケーションの設定
プラットフォームはEC2を選択
![スクリーンショット 2020-10-26 15.13.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/6d617b75-9931-7c33-41a1-b3f71aad4e11.png)

### CodeDeployのためのロールを作成
先ほどのEC2のためのロール作成と同じ手順。
![スクリーンショット 2020-10-26 15.17.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/ec6f1ecc-74ef-decf-07b1-7a09f3fb14b9.png)
![スクリーンショット 2020-10-26 15.18.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/388f7ec9-77f9-2122-d52d-8a378891d22b.png)
![スクリーンショット 2020-10-26 15.21.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/a88da6c3-e142-ab25-5fde-cae6ae0c6344.png)


### 作成したアプリケーションに、デプロイグループを作成
デプロイグループ名は適当に。
サービスロールは先ほど作成したCodeDeployのためのロールをアタッチ。
![スクリーンショット 2020-10-26 15.23.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/2ac78e4d-3b4c-15b8-c288-632bf5784f91.png)

デプロイタイプはインプレースを選択。
環境設定はEC"インスタンスを設定。
ここでは、どのEC2にデプロイするかを判定するためにタグを使う。選択したタグをもつ全てのEC2にデプロイされる。
同時にいくつものEC2にデプロイするためには便利。

![スクリーンショット 2020-10-26 15.24.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/2d6072dc-7ef9-5981-c1bf-e6ca87ad5fe7.png)

デプロイ設定はデフォルトを指定。
今回はLoad balancerを使わない。

![スクリーンショット 2020-10-26 15.30.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/dc8cc89d-8b19-3a01-d227-2a12233564e3.png)

##`appspec.yml`と`ApplicationStart.bash`の作成
gitレポジトリと連携させてコードをデプロイするのだが、ソースコードに加え、どうやってデプロイするかを記述したファイルをgitレポジトリのルートディレクトリに保存する必要がある。そしてファイル名は`appspec.yml`で固定。
具体的な書き方は[こちら](https://developers.fukurou-labo.co.jp/ci-cd%E5%AE%9F%E8%A3%85%E7%B7%A8/)や[こちら](https://dev.classmethod.jp/articles/code-deploy-appspec/)の記事を参照させていただいた。
ありがとうございます。

```appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/simple-docker-pjt
    runas: ec2-user
permissions:
  - object: /
    pattern: '**'
    owner: ec2-user
    group: ec2-user
hooks:
  ApplicationStart:
    - location: scripts/ApplicationStart.bash
      runas: ec2-user
```

また、`appspec.yml`にしたがって、EC2にコードをコピーインストールした後、実際に`docker-compose up`をする必要がある。
それを`ApplicationStart.bash`に記述する。
くれぐれも`docker-compose up -d`の`-d`の部分にお気をつけください。バックグラウンドで実行しないと、永遠にデプロイが終わりません。

```./scripts/ApplicationStart.bash
#!/bin/bash -e
cd /home/ec2-user/simple-docker-pjt
sudo systemctl start docker
docker-compose up -d
```

##デプロイの作成
アプリケーションを選択し、「デプロイの作成」、をクリック。
![スクリーンショット 2020-10-26 15.35.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/2a625b19-ecaf-4c0a-371e-c3ede65bf725.png)
「リビジョンタイプ」にgithubを選択し、トークン名として自分のアカウント名を記入。そして接続する。
また、接続先のレポジトリ名とデプロイしたい任意の時点のコミットIDを指定する。
![スクリーンショット 2020-10-26 15.37.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/e9523e1b-d528-d8c4-599c-c62647edcefe.png)

これでデプロイを作成すれば、問題なくデプロイできるはず。ここまで来ました。
![スクリーンショット 2020-10-26 17.12.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/e6634bd6-805b-85d8-f204-df6df37a6979.png)



## `CodePipeline`の設定

### パイプラインを作成する
CodePipelineのコンソールから新しいパイプラインを作成する。
パイプライン名を適当に設定すると、自動でサービスロール名も設定される。
![スクリーンショット 2020-10-26 17.16.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/3341b779-0dad-959b-b0fd-cdd8efd2896b.png)

ソースステージはgithub(ver.1)を選択し、自分のアカウントに接続する。
![スクリーンショット 2020-10-26 17.18.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/3ae138b9-a320-7d18-f532-bd2d55ddcf19.png)

レポジトリとブランチを選択する。
![スクリーンショット 2020-10-26 17.21.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/645f5dc8-1c44-6161-c6ba-17db87a3d21d.png)

ビルドステージは（今回はビルド不要の言語なので）スキップする
![スクリーンショット 2020-10-26 17.23.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/dfcdf4af-1ae3-2a21-404b-7bab2f61e31d.png)

デプロイプロバイダーは`CodeDeploy`を選択し、先ほど作成したアプリケーションとデプロイグループを選択する。
![スクリーンショット 2020-10-26 17.26.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/210676bf-c8a5-1741-b795-b0a057638fe4.png)

### EC2にS3へのアクセス権限を追加する。
EC2がCodePipelineを利用するためには、S3へのアクセスが必要となる。
そのため、先ほどEC2にアタッチしたロールに`AmazonS3FullAccess`ポリシーを追加でアタッチする。
![スクリーンショット 2020-10-26 17.30.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/e1137ff3-6e81-e609-dbd3-3876398c5058.png)

これで設定ができました。
gitにコードをpushすると自動的にEC2にデプロイされます。
![スクリーンショット 2020-10-26 17.09.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/07935ffa-7428-3bb4-6ff9-dc4b2ee1141b.png)


# 参考サイト
くろかわさんのyoutube。いつも参考にさせていただいております。
https://youtu.be/8mPm7jolnVk