ElasticBeanstalk(MultiContainer)の利用方法

## 概要
Dockerを利用した本番運用をしたくなり、ElasticBeanstalkについて調べたのでまとめる。

## ElasticBeanstalkとは
定義ファイルを準備する事で、AWS上のリソース(EC2,ECS,ELB...etc)を利用した環境を構築してくれるサービスであり、MultiContainerパターンではCloudFormation + ECSと同等の環境を設定ファイルのみで構築できる。

## マルチコンテナパターン概要
- Dockerrun.aws.jsonにコンテナの関係を定義して、ElasticBeanstalkのコマンドを叩けばデプロイされる。  
    + [公式のサンプル](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_docker_v2config.html) 
- 冗長化構成やスケール設定をしたい場合は.ebextensions内に追加設定を書いていくことで実現できる。
    + [拡張設定値一覧](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options-general.html)

## サンプルの構成図
サンプルのリソース関係図・構成図は下記のようになる

### AWSリソース関係図
![ElasticBeanstalk01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23306/b5437100-88ba-916d-2608-706b649d14e3.png)

### EC2内のContainer構成図
![ElasticBeanstalk2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23306/50437ba0-a4be-1776-c8f8-bd6b1218944f.png)

## Dockerrun.aws.jsonのサンプル
ECRを利用したサンプルを下記に示す(書き方はdocker-composeのjson版？)

```Dockerrun.aws.json
{
  "AWSEBDockerrunVersion": 2,
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "xxxxx.amazonaws.com/xxxxx/nginx:latest",
      "essential": true,
      "memory": 128,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 80
        }
      ],
      "links": [
        "rails-app"
      ],
      // Log設定(今回はCloudWatchLogsを利用する)
      "logConfiguration" : {
        "logDriver": "awslogs",
        "options": {
          "awslogs-region": "ap-northeast-1",
          "awslogs-group": "/xxxxx/develop/nginx"
        }
      }
    },
    {
      "name": "rails-app",
      "image": "xxxxx.amazonaws.com/xxxxx/rails-app:latest",
      "essential": true,
      "memory": 256,
      "portMappings": [
        {
          "containerPort": 3000
        }
      ],
      "logConfiguration" : {
        "logDriver": "awslogs",
        "options": {
          "awslogs-region": "ap-northeast-1",
          "awslogs-group": "/xxxxx/develop/rails-app"
        }
      }
    }
  ]
}
```

### ログの運用について
デフォルトでは各コンテナの標準出力がS3に保存されるが、それだと見づらいためCloudWatchLogsを利用する。
[設定方法はこちらを参照](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html)
※ ElasticBeanstalkを利用する場合はLoggingDriverとしてFluentdを指定できない(カスタムAMIでなんとかいけるがオススメできない)

## Deployまでの流れ
1. AWS-CLIとEB-CLIの準備
1. DockerImageの作成(説明省略)
1. ImageをECRにPush([こちらを参照](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-push-ecr-image.html))
1. EB-CLIでcreate or deploy

### AWS-CLIとEB-CLIの準備
AWS-CLIのインストール

```
$ brew install awscli
```

EB-CLIのインストール

```
$ brew install awsebcli
```

### EB-CLIでDeploy
#### 初期設定
```
$ eb init
9) ap-northeast-1 : Asia Pacific (Tokyo) 
2) [ Create new Application ]
8) Multi-container Docker

残りはお好きなように設定
```

#### 新規作成
```
$ eb create rails-app-develop
```
#### デプロイ
```
$ eb deploy rails-app-develop
```

## オートスケールなどの細かい設定について
- Docker.run.jsonと同階層に.ebextensionsを作成し、そこに追加設定ファイルを置く
- 「ファイル名.config」としないと認識しないため注意
- [拡張設定値はこちらを参照](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options-general.html)

### 階層サンプル
```
.
├── .ebextensions
│   ├── 00-vpc.config
│   └── 01-autoscaling.config
├── .elasticbeanstalk 
│   └── config.yml
└── Dockerrun.aws.json
```