Amazon ECSで log driverとしてawslogsを設定したいのだけどecs-agentが未対応なのでfluentdでお茶を濁す

タイトル長いですね。。

## 動機

[2016/5/5 ECS Agent1.9.0からawslogs logging driverがサポートされました。](https://github.com/aws/amazon-ecs-agent/releases/tag/v1.9.0)

この記事はもはや駄文です。下記公式ドキュメントを参照して安心してawslogsドライバーを使ってください。
See: http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/using_awslogs.html

----------

1. Docker1.9から[logging-driverとしてawslogs（CloudWatch Logs）](https://docs.docker.com/engine/reference/logging/awslogs/)に対応した。
2. ところがどっこいAmazon ECSはまだ対応してなかった
    * ecs-agentがまだ対応していない
    *  http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_storage
        *  ``logDriver": "json-file"|"syslog"|"journald"|"gelf"|"fluentd"``
3. fluentdなら対応している
4. fluentd->CloudWatch Logsならできる  
  https://github.com/ryotarai/fluent-plugin-cloudwatch-logs

ちなみにECSとしては近日対応されそうな雰囲気のプルリクが進行中です。

* https://github.com/aws/amazon-ecs-agent/pull/251
* https://github.com/aws/amazon-ecs-agent/pull/366 ←2016/04/1２にマージされた様子

~~この記事の利用価値はそれまでの命でしょう。~~→もはや天寿を全うしています。興味本位以外の役に立ちません。

## やりかた

1. [こんな感じのDockerfile](https://github.com/NewGyu/docker-fluentd-awslogs)を書いてfluentdをコンテナとして起動します。
    * ポートマッピングで `localhost:22424` でfluentdにアクセスできるようにする（ポート番号はご自由に）
2. 上記の`localhost:22424`をTaskDefinitionのオプションに指定する

![](https://cacoo.com/diagrams/V55Sg3UVjneVSwQv-09A0D.png)

### fluentdコンテナ

#### Dockerimageの定義

```Dockerfile
FROM fluent/fluentd:latest
USER fluent
WORKDIR /home/fluent
ENV FLUENTD_PORT=22424
EXPOSE $FLUENTD_PORT
RUN gem install fluent-plugin-cloudwatch-logs
```

はっきり言って``FROM fluent/fluentd``がよく出来ているのでほとんど何もすることはありません。
``gem install fluent-plugin-cloudwatch-logs``するくらいです。

#### Log収集コンテナのTaskDefinition定義

```json
  "containerDefinitions": [
    {
        :
      "name": "fluent-awslogs",
      "image": "newgyu/fluent-awslogs",
      "portMappings": [
        {
          "hostPort": 22424,
          "containerPort": 22424,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "AWSLOGS_GROUP",
          "value": "personalize/batch/test"
        },
        {
          "name": "AWSLOGS_STREAM",
          "value": "batch"
        },
        {
          "name": "AWS_REGION",
          "value": "ap-northeast-1"
        }
      ],
       :
    }
  ],
```

ポイントは以下です。

* ポートマッピングでホストのポートを開ける
* environmentを指定
    * AWSLOGS_GROUP      ...予めLogGroupは作っておいてください
    * AWSLOGS_STREAM     ...名前だけ指定すれば初回に作成されます
    * AWS_REGION         ...必須です

#### 必要なAWSの権限

ECSインスタンスに以下のポリシーが許可されたIAM Roleを付与してください。

```json
{
    "Statement": [
        {
            "Resource": "*",
            "Action": [
                "ecs:CreateCluster",
                "ecs:DeregisterContainerInstance",
                "ecs:DiscoverPollEndpoint",
                "ecs:Poll",
                "ecs:RegisterContainerInstance",
                "ecs:StartTelemetrySession",
                "ecs:Submit*",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:Describe*"
            ],
            "Effect": "Allow"
        }
    ]
}
```

* ecs:* はそもそもECSインスタンスとして必要なものです
* logs: はCloudWatch Logsに必要なものです。
    * `awslogs`ではDescribeは必要ないのですが、`fluent-plugin-cloudwatch-logs`では必要な様子

### mainコンテナにオプション指定

TaskDefinitionの`logConfiguration`に以下のように設定します。

```json
  "containerDefinitions": [
    {
        :
      "logConfiguration": {
        "logDriver": "fluentd",
        "options": {
          "fluentd-address": "127.0.0.1:22424"
        }
      },
        :
    }
  ]
```

さて、ここで自分は一つハマりました。

http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html
をみるとlogging driverとしてfluentd を指定可能っぽい書き方でしたが、実際に指定するとRun Taskするときに

```
Run tasks failed
Reasons : ATTRIBUTE
```
と言われてしまいました。

どうやらデフォでは有効なlogging-driverは

```
ECS_AVAILABLE_LOGGING_DRIVERS=["json-file","syslog"]
```
となっているようで、[このようにECSインスタンスにuser-dataで指定してやる](https://github.com/NewGyu/cfnz-sample/commit/7cac1829215907a9c9881b7d39bbf7315fe202a1)必要がありました。

ドキュメント的にはこの辺のNoteがそれに当たるみたいです。
http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_storage
> Note
> The Amazon ECS container agent running on a container instance must register the logging drivers available on that instance with the ECS_AVAILABLE_LOGGING_DRIVERS environment variable before containers placed on that instance can use these log configuration options. For more information, see Amazon ECS Container Agent Configuration.