Step by StepでBlue/Greenデプロイ(by AWS CodeDeploy)

# はじめに

AWS CodeDeployを使ってBlue/Greenデプロイを行うサンプルです。

ネット上に情報はちらほらあるのですが（大変参考にさせていただきました）、実際のWebアプリケーションデプロイ手順に近いサンプルがなかったので、こちらにまとめてみました。
「Blue-Green Deploymentに興味はあるんだけど、めんどくさそうだしなあ…」という方の助けになれば幸いです。


# 1.「普通に」デプロイ

まずはWebアプリケーションを「通常のデプロイ手順どおり」デプロイします。CodeDeployを動かしながらWebアプリのデプロイをトライアンドエラーしていくのは**大変しんどい**です。Webアプリ側は**「手順書通りにやれば、確実にアプリケーションが動かせる」**状態にしておきましょう。

今回はこちらのサンプルWebアプリケーションを利用させていただきました。[uzulla/Tinitter: PHP sample web application](https://github.com/uzulla/Tinitter)
Slim+Eloquentで作られているシンプルなWebアプリで、PHPのWebアプリ経験者ならだいたい何をやってるのか想像つくかと思いますので、細かい説明は省いてます。ご容赦ください。[^1]

[^1]: デプロイのサンプルにいい感じのWebアプリないかなー…とGitHubを検索していて見つけました。フルスタックなPHP製WebAppのエッセンスをうまくチュートリアルレベルに落とし込んである印象で、覚えることが多い初学者には良いサンプルなんじゃないかなと思いました。本の中味は読んでないんですが、この記事書き終わったら買ってみます…

* t2.micro
  * Amazon Linux AMI 2017.09.1 | 64bit
  * t2.micro
  * セキュリティグループで`HTTP 80, SSH 22`を開放

インスタンス作成後、SSHログインして進めていきます。

```
// OS設定
$ sudo yum -y update
$ sudo cp /etc/localtime /etc/localtime.org && \
    sudo cp -p /usr/share/zoneinfo/Japan /etc/localtime

// PHP(5.6)の導入
//   4年前の書籍のソースコードなので、楽に入れられて互換性問題が起きにくそうな、5.6系を入れる
$ sudo yum install php56 php56-pdo php56-mbstring

$ php -v
PHP 5.6.35 (cli) (built: Apr  3 2018 21:27:01)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

// DBにはsqliteを使うので確認
$ php -i | grep pdo_sqlite
/etc/php-5.6.d/30-pdo_sqlite.ini,
PHP Warning:  Unknown: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Unknown on line 0
pdo_sqlite

// php.iniの設定
$ sudo cp /etc/php.ini /etc/php.ini.orig
$ sudo sed -i 's/;internal_encoding =/internal_encoding = UTF-8/g' /etc/php.ini
$ sudo sed -i 's@;date.timezone =@date.timezone = "Asia/Tokyo"@g' /etc/php.ini

// ソースコードの配置
//   ここではgit clone(ssh agent利用)でソースコードを取得していますが、wget等でも可
$ cd ~/
$ sudo yum -y install git
$ git clone git@github.com:uzulla/Tinitter.git

$ sudo mv ~/Tinitter /
$ ls /Tinitter
LICENSE  README.md  composer.json  composer.lock  config.php.sample  htdocs  lib  schema.mysql.sql  schema.sqlite3.sql  templates  test
```

ビルトインのWebサーバを使い、疎通を確認。

```
// Composer配置、ライブラリ導入 
$ cd /Tinitter
$ php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
$ php composer.phar install

// アプリケーションのセットアップ
$ cp config.php.sample config.php
$ sqlite3 sqlite.db < schema.sqlite3.sql

// 動作確認
$ cd /Tinitter/htdocs
$ sudo php -S 0.0.0.0:80
PHP 5.6.35 Development Server started at Wed Apr 11 09:04:30 2018
Listening on http://0.0.0.0:80
Document root is /home/ec2-user/Tinitter
Press Ctrl-C to quit.
```

http://{IPアドレス}/ にアクセスして、画面が表示されるのを確認。単体テストもあるので確認しておきます。

```
$ cd /Tinitter/test/
$ ../vendor/bin/phpunit
PHPUnit 3.7.28 by Sebastian Bergmann.

Configuration read from /home/ec2-user/Tinitter/test/phpunit.xml

..........

Time: 635 ms, Memory: 17.00Mb

OK (10 tests, 41 assertions)
```

続いてMW設定を行います。ビルトインサーバでも問題ないんですが、サンプルに丁度いいのでApache(httpd)で動かします。

```
// .htaccess(rewrite系)を設定
$ cd /Tinitter/htdocs
$ cp .htaccess.sample .htaccess

// バーチャルホストを設定
$ sudo rm -rf /etc/httpd/conf.d/welcome.conf
$ cat <<EOL >> tinitter.conf
<VirtualHost *:80>
    DocumentRoot "/Tinitter/htdocs"
    <Directory "/Tinitter/htdocs">
        AllowOverride All
        Options All
        Require all granted
    </Directory>
</VirtualHost>
EOL
$ sudo mv tinitter.conf /etc/httpd/conf.d/tinitter.conf

// httpdからアクセスできるように権限周りを設定
$ sudo chown -R apache:apache /Tinitter
$ sudo chmod 777 /Tinitter/sqlite.db

// httpd起動・自動起動設定
$ sudo service httpd start
Starting httpd:                                            [  OK  ]
$ sudo chkconfig httpd on
```

<img width="800" alt="スクリーンショット 2018-04-11 18.19.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/c43d2c7d-c567-a253-528d-d73bd4038985.png">


# 2. CodeDeployの動作確認

次に、AWS CodeDeploy(以下CodeDeploy)の動作確認を行いますが、長くなったので別記事に分けました。
[AWS CodeDeployで公式サンプルを動かす\(入門者向け・WebUIベース・インプレースデプロイ\) \- Qiita](https://qiita.com/terukizm/items/e2c1400d129042868731)

慣れている人は省略してしまっても良いですが、IAM等が絡んでめんどくさいので、単体で動作確認をしておくのがオススメです。
(なお、今回作成したEC2に公式のCodeDeployサンプルアプリケーションを載せようとすると、php5.6が利用しているapacheと、公式が入れようとしているApacheのバージョン不整合でエラーになります。ご注意ください)


# 3. CodeDeployで既存インスタンスにインプレースデプロイ

ここから本編です。まずは作成した既存のインスタンスに、インプレースデプロイでリポジトリからソースコードを配備して動かします。

## appspec.ymlの追加

forkして`appspec.yml`を追加します。[terukizm/Tinitter: PHP sample web application](https://github.com/terukizm/Tinitter)

```appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /Tinitter

hooks:
  BeoreInstall:
    - location: script/before_install.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: script/after_install.sh
      timeout: 300
      runas: root
```

ソースコードを`/Tinitter`に配備する前、配備した後の処理もスクリプト化しておきましょう。ここではMW関係のインストールや設定は省略しています。(そちらはAMI化するところで入れます)

```script/before_install.sh
#!/bin/sh

rm -rf /Tinitter
```

```script/after_install.sh
#!/bin/sh

cd /Tinitter
php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
php composer.phar install

cp config.php.sample config.php
sqlite3 sqlite.db < schema.sqlite3.sql

cd /Tinitter/htdocs
cp .htaccess.sample .htaccess

chown -R apache:apache /Tinitter
chmod 777 /Tinitter/sqlite.db
```

参考: [CodedeployのLifeCycleに関するメモ \- Qiita](https://qiita.com/n-kashimoto/items/36b77c0a448037678f1d)

## ソースコードの配備

リポジトリ内のソースコードをデプロイする方法ですが、二通りあります。

1. CodeDeployとGitHubを連携させ、ソースコードを直接デプロイ
2. GitHubのソースコードをzipに固めてS3に格納し、S3経由でデプロイ

GitHubを利用する前提なら1.が楽ですが[^2]、今回は汎用性が高い(S3にzipで固めて置ければVCS等の種類を問わない)2.の方法で進めます。
デプロイ用のS3バケット(`code-deploy-s3-sample`)を作成し、リポジトリを`git archive`コマンドでzipに固めたものを、適当な名前でUploadします。

[^2]: GitHub決めうちでやる場合は、こちらが参考になります。 [GitHubへのpush時にCodeDeployを使ってEC2にアプリケーションをデプロイする \- Qiita](https://qiita.com/toshihirock/items/4ab08afcab2a0e7628a8)

```
$ git clone git@github.com:terukizm/Tinitter.git
$ git archive HEAD --output=/tmp/tinitter-1.0.0.zip
```

<img width="800" alt="スクリーンショット 2018-04-13 21.02.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/95fa6cb2-b473-d6da-41d1-11af64914e28.png">

ここでは`https://s3-ap-northeast-1.amazonaws.com/code-deploy-s3-sample/tinitter-1.0.0.zip`としました。


## WebUI経由でのデプロイ

まずはWebUIからデプロイを実施します。「リビジョンの場所」に先程のS3のURLを入力してください。

<img width="800" alt="スクリーンショット 2018-04-13 21.13.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/3a47f091-88a4-9a4b-2fd9-bfa020a20c01.png">
<img width="800" alt="スクリーンショット 2018-04-13 21.13.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/017a526d-f75b-57d6-e4da-6f6497cfd8d7.png">

<img width="800" alt="スクリーンショット 2018-04-14 13.05.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/655e93dd-e372-af4d-f2a1-2f4606c92952.png">

http://{EC2のIP}/にもアクセスし、Webアプリがきちんと動作していることも確認しておきましょう。


## awscli経由でのデプロイ

毎回WebUI経由でS3にzipをUploadしたり、デプロイを作成したりするのはしんどいです。後々のCIツールとの連携を考えればawscliを使うのがオススメです。

### CodeDeploy用のIAMユーザ払い出し

CIツール等から利用することを考慮して、CodeDeploy用のIAMユーザを払い出しておきましょう。まずはCodeDeployへのアクセス権限と、S3への書き込み権限を付与したポリシー(ここでは`CodeDeployUserPolicy`)を作成します。[^3]「IAM」→「ポリシー」→「ポリシーの作成」→「JSON」で作成してください。

[^3]: サンプル用にResourceをかなり緩く設定しています。実運用の際はapplication, deploymentgroup, s3のbacketなどをきちんと設定するようにしてください。

<img width="800" alt="スクリーンショット 2018-04-14 17.18.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/de1b0e35-f9ec-59a3-134b-634e273dc2e2.png">

```json:JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "codedeploy:RegisterApplicationRevision",
        "codedeploy:GetApplicationRevision"
      ],
      "Resource": [
        "arn:aws:codedeploy:*:*:application:*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "codedeploy:CreateDeployment",
        "codedeploy:GetDeployment"
      ],
      "Resource": [
        "arn:aws:codedeploy:*:*:deploymentgroup:*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "codedeploy:GetDeploymentConfig"
      ],
      "Resource": [
        "arn:aws:codedeploy:*:*:deploymentconfig:CodeDeployDefault.OneAtATime",
        "arn:aws:codedeploy:*:*:deploymentconfig:CodeDeployDefault.HalfAtATime",
        "arn:aws:codedeploy:*:*:deploymentconfig:CodeDeployDefault.AllAtOnce"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::*/*"
      ]
    }
  ]
}
```

このポリシーが設定されているユーザ(ここでは`CodeDeploySampleUser`としました)を作成します。「IAM」→「ユーザー」→「ユーザーを追加」からユーザを作成し、アクセスキー、シークレットキーを払い出してください。

<img width="800" alt="スクリーンショット 2018-04-14 17.19.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/edea7e1d-aaa8-b84e-a5c3-a031de1c5247.png">
<img width="800" alt="スクリーンショット 2018-04-14 17.27.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/76b5de66-a79e-73bd-8952-9f52d1646843.png">
<img width="800" alt="スクリーンショット 2018-04-14 17.20.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/3d85d57d-ff57-abca-1886-5a2d7496cfbe.png">
<img width="800" alt="スクリーンショット 2018-04-14 17.26.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/0ee0d056-b4ce-933b-c46e-7a72bf1cbea5.png">

### awscli経由での動作確認

awscliに作成したユーザのアクセスキー、シークレットキーを設定します。
参照: [AWS CLI で S3 にファイルをアップロード \- Qiita](https://qiita.com/seyself/items/43426f57c50021ea55f8)

```
// MacOSから実行
$ brew install awscli

// アクセスキー、シークレットキーを設定(profile = code-deploy-sample)
$ aws configure --profile code-deploy-sample
AWS Access Key ID [None]: XXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

あとはWebUIから手動で行ったものと同じです。慣れればこっちの方が断然楽ですね。

```
// zipで固める
$ git archive HEAD --output=/tmp/tinitter-1.0.1.zip

// S3にアップロード
$ aws s3 cp /tmp/tinitter-1.0.1.zip s3://code-deploy-s3-sample/ --profile code-deploy-sample
upload: ../../../../tmp/tinitter-1.0.1.zip to s3://code-deploy-s3-sample/tinitter-1.0.1.zip

// CodeDeployでインプレースデプロイ
$ aws deploy create-deployment \
    --region ap-northeast-1 \
    --application-name CodeDeploySampleApplication \
    --deployment-group-name CodeDeploySampleDeployGroup \
    --s3-location bucket=code-deploy-s3-sample,key=tinitter-1.0.1.zip,bundleType=zip \
    --profile code-deploy-sample
{
    "deploymentId": "d-YXO73HUSR"
}
```

deploymentIdが払い出されるので、きちんとデプロイできていることを確認しましょう。

<img width="800" alt="スクリーンショット 2018-04-14 17.58.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/0d1f7fc9-dde0-7862-4027-b4e708467445.png">

# 4. CodeDeployでELB+AutoScaling環境にインプレースデプロイ

ELB+AutoScalingの環境にデプロイできることを確認します。なお、この環境が初回Blue/Greenデプロイでの「Blue」環境に相当するものになります。

## AMI作成

Blue/Greenデプロイは、デプロイの度に新しいインスタンスを生成します。元となるAMIは既存インスタンスから手動で作っても良いのですが、[packerでコード化しておく](https://github.com/uzulla/Tinitter/pull/1/commits/77c3b53ce2e66ccd94d61420c06b129d65870808)と後々のメンテナンスが楽です。

```
// MacOSから実行
$ brew install packer

$ cd ~/Tinitter/packer
$ cp credential.json.example credential.json

$ vi credential.json
---
(AWSKEY, SECRETKEYを設定)
---

$ packer build --force -var-file=credential.json ami.json
==> amazon-ebs: Force Deregister flag found, skipping prevalidating AMI Name
    amazon-ebs: Found Image ID: ami-df455ba3
(略)
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
ap-northeast-1: ami-df455ba3
```

<img width="800" alt="スクリーンショット 2018-04-15 19.01.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/d61c7c0e-fe30-348f-f9c8-2cf3050cbd21.png">


## Tinitterアプリケーションへの修正

Blue/Greenデプロイとは無関係ですが、[TinitterアプリケーションにインスタンスIDを表示させるように](https://github.com/uzulla/Tinitter/pull/1/commits/9f38174137dc7372e6b8e882a9e0731bf3d32dea)しておきます。
参考: [EC2インスタンス内から情報を取得する方法 \- Qiita](https://qiita.com/akikinyan/items/c6be02e1d48de46fca53)

これで、新しいインスタンスで稼働していること、ロードバランシングされていることがわかりやすくなります。

## ELB(ALB)の作成

「AWS EC2」→「ロードバランシング」→「ロードバランサー」→「ロードバランサーの作成」→「Application Load Balancer」としてELB(ALB)を作成します。
ここでは以下の設定で作成しました。

* CodeDeploySampleELB
    * ターゲットグループ
        * CodeDeploySampleTargetGroup
    * セキュリティグループ
        * 80番(HTTP)のみ開放
    * アベイラビリティゾーン
        * ap-northeast-1a
        * ap-northeast-1c

<img width="800" alt="スクリーンショット 2018-04-15 14.49.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/ead23c80-a2d5-08f5-4152-d021b134c868.png">
<img width="800" alt="スクリーンショット 2018-04-15 14.49.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/48a55e28-2104-2a05-90af-fdc6c3f10e46.png">
<img width="800" alt="スクリーンショット 2018-04-15 14.50.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/4d95b3f3-c767-846a-30aa-22641988aad0.png">

## Auto Scalingの作成

続いてAuto Scaling、 AutoScalingグループを作成します。「AWS EC2」→「AUTO SCALING」→「起動設定」として、先程作成したAMIを指定。

<img width="800" alt="スクリーンショット 2018-04-15 15.45.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/ec39fb13-f151-faa5-71fb-645bba014ebd.png">

あとは概ねインプレースデプロイと同じです。

* ec2.nano (2つ起動するので一番安いのにしました)
    * IAMロール: EC2->S3のアクセス権限ロール(EC2User)
    * セキュリティグループ: 80番と22番を開放

<img width="800" alt="スクリーンショット 2018-04-15 15.46.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/73b7c6e3-4821-ffd0-6cb3-0b17122d9c59.png">

そのままAuto Scalingグループも作成。2インスタンスで起動します。

<img width="800" alt="スクリーンショット 2018-04-15 15.47.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/af3be9f3-73ed-923c-160b-f3f8e310c04f.png">

AutoScalingを利用する場合、タグでインスタンスを区別する必要はないのですが、設定しておくとわかりやすいので、適宜設定しておくと良いかもしれません。

<img width="800" alt="スクリーンショット 2018-04-15 15.48.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/e9c7ee6e-0a6a-ff4f-2540-70d942ee79fe.png">
<img width="800" alt="スクリーンショット 2018-04-15 15.48.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/f582c924-7e8c-3356-e5e2-204a18e1f2db.png">

作成完了後、2インスタンスが起動していればOKです。

<img width="800" alt="スクリーンショット 2018-04-15 15.54.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/c37e6c0d-41ce-9a11-c163-e8aa32580c54.png">

## デプロイタイプ変更

「AWS CodeDeploy」→「アプリケーション」→「作成したアプリケーション(CodeDeploySampleApplication)」→「作成したデプロイグループ(CodeDeploySampleDeployGroup)」と選択。「アクション」→「編集」から、「Auto Scalingグループ」に、先程作成したAuto Scaling グループを設定します。

以下の設定も一緒にやっておきましょう。

* ロードバランシング
    * 作成したELB(ALB)を指定
* デプロイ方式
    * 一番わかりやすいAllAtOnceに

<img width="800" alt="スクリーンショット 2018-04-15 16.05.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/ee8c4e17-7d10-f875-4456-314c5488690e.png">
<img width="800" alt="スクリーンショット 2018-04-15 16.05.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/ab1aaefe-af06-c3eb-ff93-b4cfb3197906.png">

起動している2インスタンスが自動的に選択されているのを確認し、「デプロイ設定が変更されました」にチェックを入れて「保存して今すぐデプロイ」を押下。前回のデプロイ内容で自動的にデプロイが開始されます。

<img width="800" alt="スクリーンショット 2018-04-15 16.12.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/7923c53e-9728-06dc-c90e-9622ca5894e0.png">

あとはELBに設定されているDNS名でアクセスし、

* アプリケーションがデプロイされていること
* 2インスタンスにロードバランシングされていること

が確認できればOKです。

<img width="800" alt="スクリーンショット 2018-04-15 16.48.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/7e671a24-c076-ec75-b39b-f2db92bb8da7.png">


# 5. CodeDeployでBlue/Green デプロイ

ここまで来れば、あとは「インプレースデプロイ」から「Blue/Greenデプロイ」に変更するだけです。

<img width="800" alt="スクリーンショット 2018-04-15 16.48.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/02b8fa90-513e-2cb9-9840-a7518e92d561.png">
<img width="800" alt="スクリーンショット 2018-04-15 16.49.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/bda292d6-d168-5aae-b006-0951481de641.png">

オートスケーリングにかかるのと同じくらいの時間で新環境が生成され、そちらにトラフィックが流れれば成功です。お疲れ様でした！

<img width="800" alt="スクリーンショット 2018-04-15 18.17.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/849c9657-b81d-b771-8486-f086fe8aedd6.png">
<img width="800" alt="スクリーンショット 2018-04-15 18.19.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/d0069cbe-281e-4a94-6f57-41c2b9e97afc.png">
<img width="800" alt="スクリーンショット 2018-04-15 18.19.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/3e5036da-3946-b7f6-c771-2cfc2561071f.png">

なお、デフォルト設定ではデプロイ成功後もBlue環境が1時間並行稼働するので(切り戻し対策？)、適宜変更してください。

<img width="800" alt="スクリーンショット 2018-04-15 17.13.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/0ccbd63a-1699-0d6d-8921-b4bf6b7c4295.png">

 
# 終わりに

CodeDeployを使ったBlue/GreenデプロイはIAMやELB、AutoScalingなど考慮する部分が多くて複雑に見えますが、一歩ずつ進めていけば意外とシンプルなのかなと思いました。是非お試しください。


## ■備考(サンプルアプリケーションについて)

単体やインプレースデプロイで動かしている分には問題なかったのですが、やっていくうちに以下の問題が出てきました。

* sqliteでやっているのでオートスケールできない
    * DBの内容も吹っ飛ぶ、migrationとかもない 
    * プログラム的にはmysqlにも対応しているので、RDSを使うようにしてやればいいはず
        * ただもうCodeDeployと戯れているだけでめんどくさくなり…
* ELB上で動かしたときに"CSRF token"エラーになる
    * SlimのSession周りとか、csrfプラグインくさい？
      * めんどくさくなって以下のようにスティッキーセッションにしてしまいました…

<img width="800" alt="スクリーンショット 2018-04-15 16.59.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/50184/c65beeee-8f18-aa2d-b6a9-02f210d8d9ec.png">

当たり前ですが、**Blue/Greenデプロイで動かすWebアプリケーションは、スケーラブルな環境で動くようにしておかないといけない**ですね…


# 参考 

* [やってみて分かった AWS CodeDeploy の落とし穴 \- Qiita](https://qiita.com/sugiyasu-qr/items/c44179a468ba4732c3d3)
* [CircleCI と CodeDeploy のチュートリアル（出来るだけ awscli でやるよ） \| cloudpack\.media](https://cloudpack.media/31695)