AWS CodeDeployで公式サンプルを動かす(入門者向け・WebUIベース・インプレースデプロイ)

# 概要

AWS CodeDeploy(以下CodeDepoy)の入門者向けに[「CodeDeployが提供しているサンプルアプリケーション」](https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/samples/latest/SampleApp_Linux.zip)を使って、WebUIベースでCodeDeployの動作を確認します。

公式チュートリアルの内容をさらに簡易化したものですので、実運用の際はIAMロールの設定内容等、適宜ご確認ください。

![スクリーンショット 2018-04-13 18.38.59.png](https://qiita-image-store.s3.amazonaws.com/0/50184/5176b086-636b-9dbb-71bb-e68447369af4.png)


# チュートリアル

## CodeDeploy→EC2用ロールの作成

CodeDeployが、デプロイ対象のEC2インスタンスにアクセスできるようにします。
「IAM」→「ロール」→「ロールの作成」から、「AWSサービス」「CodeDeploy」「CodeDeploy」と選択。

<img width="800" alt="スクリーンショット 2018-04-12 16.44.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/5a991564-716c-e916-9034-fda60af4d0cb.png">

「AWSCodeDeployRole」が選択されているのを確認します。

<img width="800" alt="スクリーンショット 2018-04-12 16.46.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/59249ae1-5c03-3542-4b37-d39ae5314992.png">

「ロール名」を入力してロールを作成。ここでは`CodeDeployRole`としました。

<img width="800" alt="スクリーンショット 2018-04-12 16.49.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/48cd088d-1a93-a110-130c-6ee344ee11f7.png">


作成された`CodeDeployRole`を選択し、「インラインポリシーの追加」から、CodeDeployがEC2へアクセスできるように、インラインポリシーを作成します。[^1]

[^1]: ここではわかりやすさ重視でCodeDeployがどのEC2へもアクセスできるようにしてありますが、実運用される場合は適宜制限をかけてあげるのが良いと思います。

<img width="800" alt="スクリーンショット 2018-04-12 16.54.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/393d2677-a532-80b9-2f31-0e72bd6e0f1c.png">

<img width="800" alt="スクリーンショット 2018-04-12 16.57.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/666aba7a-890d-41eb-ac33-fbb164689199.png">

```JSON:json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:Describe*",
            "Resource": "*"
        }
    ]
}
```


名前を適当につけて保存します。ここでは`CodeDeployPolicy`としました。

<img width="800" alt="スクリーンショット 2018-04-12 17.03.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/70bb342f-dcc1-ae96-b8c5-38f5d0ac6c0e.png">

最終的には以下のようになります。ARNは最終的にCodeDeployに設定するので、控えておくと良いかもしれません。

<img width="800" alt="スクリーンショット 2018-04-12 17.08.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/8295bf12-58fe-5976-2545-85b37bc18466.png">

## EC2→S3用ロールの作成

EC2インスタンス上のCodeDeploy Agentは基本的にはS3を経由してソースコードを取得するので[^2]、EC2インスタンスからS3へアクセスできるようなロールを設定してやる必要があります。

[^2]: デプロイ時のリポジトリタイプとして「GitHub」を指定した場合は不要だと思われますが、確認していません。　参考: [CircleCI\+AWS\-CodedeployでStaging環境などに自動デプロイさせる \- Qiita](https://qiita.com/devalon/items/99373f54998f238ec47a)

「IAM」→「ロール」→「ロールの作成」から、「AWSサービス」「EC2」と選択。

<img width="800" alt="スクリーンショット 2018-04-13 16.54.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/ff94fb1b-1851-7ce0-acb5-e15bf2b00ea0.png">

S3への`ReadOnlyAccess`を設定します。

<img width="800" alt="スクリーンショット 2018-04-13 16.54.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/f1132259-4723-5af9-6f64-c95d31370027.png">

名前をつけて保存してください。ここでは「EC2Role」という名前にしました。

<img width="800" alt="スクリーンショット 2018-04-13 16.55.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/ed9d4c05-9161-3711-2be6-e2f0349c4c6d.png">

## EC2インスタンスの作成

続いて、デプロイ対象となるEC2インスタンスを作成します。
注意すべきは以下3点です。

1. 作成した「EC2→S3用ロール」をIAMロールとして設定すること
2. インスタンスに「タグ」を設定すること
3. インスタンスに「CodeDeploy Agent」をインストール、起動させておくこと

今回は以下のように作成しました。

* t2.nano
  * Amazon Linux AMI 2017.09.1 (HVM) | 64bit
  * セキュリティグループでHTTP(80番), SSH(22番)を開放
      * サンプルアプリケーションがHTTPポート(80番)を利用するため 
  * IAMロールに`EC2Role`を設定
  <img width="800" alt="スクリーンショット 2018-04-13 17.33.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/82b8604b-082d-9f0f-88a0-b1965d5b1e45.png">
  * タグに`deploy=sample`を設定
  <img width="800" alt="スクリーンショット 2018-04-13 17.33.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/b85db555-386c-0a27-9eff-fcda6adaa2b7.png">

タグはデプロイ対象のインスタンスを特定するために後ほど必要になりますが、キー:値は何でもかまいません。

インスタンスが作成できたら、SSHログインして「CodeDeploy Agent」をインストールしましょう。

```
$ aws s3 cp s3://aws-codedeploy-ap-northeast-1/latest/install . --region ap-northeast-1
download: s3://aws-codedeploy-ap-northeast-1/latest/install to ./install
$ chmod +x ./install
$ sudo ./install auto
I, [2018-04-13T08:45:57.432536 #2692]  INFO -- : Starting Ruby version check.
(略)
完了しました!
I, [2018-04-13T08:45:59.421154 #2692]  INFO -- : Update check complete.
I, [2018-04-13T08:45:59.421229 #2692]  INFO -- : Stopping updater.

$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 2738
```

※aws s3コマンドでcredentialエラーが出る場合、IAMRoleが設定されていない可能性が高いです。ご確認ください。

## CodeDeploy アプリケーション作成

ここまでできれば準備完了です。CodeDeployのアプリケーション(ソースコードのデプロイ単位)を作成します。

最初はウィザードが立ち上がりますが、「CodeDeploy」→「アプリケーションの作成」→「カスタムデプロイ」としてください。

<img width="800" alt="スクリーンショット 2018-04-12 17.11.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/5ff9228d-af2e-6b4e-37b2-a300f85c5ade.png">

続いてアプリケーションを作成します。ここでは

* アプリケーション名: `CodeDeploySampleApplication`
* デプロイグループ名: `CodeDeploySampleDeployGroup`
* デプロイタイプ: `インプレースデプロイ`
* タググループ: EC2に設定したタグ(`deploy=sample`) 
* サービスロール: `CodeDeployRole` (CodeDeploy->EC2へのアクセス権限を設定したロール)

としました。

<img width="800" alt="68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f35303138342f33633733303261362d316630642d303561342d346663302d3739393630376139396438372e706e67.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/f2f70011-4746-e48f-f6ee-0075d8417f6f.png">
<img width="800" alt="スクリーンショット 2018-04-13 17.50.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/d4d324cf-488a-90f6-a688-c0dc847510ed.png">
<img width="800" alt="スクリーンショット 2018-04-13 17.54.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/f81398c6-5bed-ca8b-31ba-ea5f014310b2.png">


## デプロイ実行

あとは実際にソースコードをデプロイします。
作成したアプリケーション、デプロイグループを選択し、「アクション」→「新しいリビジョンのデプロイ」と選択。

<img width="800" alt="スクリーンショット 2018-04-12 17.44.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/c9be74f7-0038-0dd6-d1a1-631329d1b636.png">

公式のサンプルアプリケーションをデプロイします。

* リポジトリタイプ: `Amazon S3`
* リビジョンの場所: `s3://aws-codedeploy-ap-northeast-1/samples/latest/SampleApp_Linux.zip`

<img width="800" alt="スクリーンショット 2018-04-12 17.47.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/600dd76d-119c-5f34-319a-f8799bdb225e.png">
<img width="800" alt="スクリーンショット 2018-04-13 18.07.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/0979d16b-47c4-766e-414e-e4250c39bed3.png">


「デプロイ」を押下してステータスが成功になれば、デプロイ完了です。

<img width="800" alt="スクリーンショット 2018-04-13 18.00.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/bdc0d00e-0774-e17f-c84f-e9c2c730f743.png">

http://{IPアドレス}/ でアクセスし、以下のような画面が表示されることを確認してください。お疲れ様でした。

<img width="800" alt="スクリーンショット 2018-04-13 18.05.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/bd4b9483-3bc5-2e08-faca-a7fea5a112d8.png">


## うまくいかない場合

以下をご確認ください。

* IAMロールの権限は適切に設定されているか？
* デプロイ終了後、EC2インスタンス上で`/var/www/html/index.html`は配置されているか？
  * 配置されているのにエラーになっている場合は80番ポートが開放されてないとか、appspec.yml経由でのセットアップスクリプトがyum installで失敗しているといった可能性があります 
* EC2インスタンス上でcodedeploy-agentはきちんと立ち上がっているか？
  * `sudo service codedeploy-agent status`でPIDはきちんと帰ってくるか？
* `/var/log/aws/codedeploy-agent/codedeploy-agent.log`のログにエラーが出ていないか？

とくにcodedeploy-agent.logの中味は重要で、例えばEC2にIAMRoleを設定し忘れていた場合、以下のように出力されていました。うまくいかない場合はまずご確認ください。

```
InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Missing credentials - please check if this instance was started with an IAM instance profile
```


以上、ご参考になれば幸いです。