AWS FireLens を試した

# 概要
コンテナのログを外部にルーティングする機能
TaskDefinition のパラメータで作成する

[カスタムログルーティング - AWS](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/using_firelens.html)

## 必要な要素
- ログ収集：FireLens コンテナ
- ログ対象：LogDriver に awsfirelens を指定したコンテナ
- ログ送信先：Kinesis Data Firehose や CloudWatch Logs 等

## FireLens コンテナの動作
ログ転送ツールとして Fluentd か Fluent Bit を使用

- [Fluentd](https://www.fluentd.org/)　　多機能 自由度高
- [Fluent Bit](https://fluentbit.io/)　簡易的 軽量

## Role
TaskRole と ExecutionRole が必要

- TaskRole
    - タスクで定義したコンテナからのアクセス権限  
    → コンテナ内のアプリケーションが使用する
- ExecutionRole
  - タスクの展開実行のためのアクセス権限   
    → ログ送信先の CloudWatch LogGroup を作成する

# 作成
ECS/Fargate を利用

## 環境
Windows 10

AWS CLI 1.16.191
[AWS CLI のインストール - AWS](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-install.html)


## 構成図
Nginx のログは FireLens と Firehose を通して S3 へ
FireLens のログは CloudWatch Logs へ送信する
![FireLens.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321137/a88616b6-bfa8-7ea1-4e62-90e0ce9e7145.png)

## Kinesis Data Firehose
下記を参考にログの送信先の配信ストリームを作成
[Amazon Kinesis Data Firehose 配信ストリームの作成 - AWS](https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/basic-create.html)

## Role

### TaskRole
Kinesis Firehose への書き込み権限
[Amazon Kinesis Firehose のアクション、リソース、および条件キー - AWS](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/list_amazonkinesisfirehose.html)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "firehose:PutRecord",
                "firehose:PutRecordBatch"
            ],
            "Resource": "*"
        }
    ]
}
```

### ExecutionRole
公式の AmazonECSTaskExecutionRolePolicy に CreateLogGroup を追記
[Amazon ECS タスク実行 IAM ロール - AWS](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_execution_IAM_role.html)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}
```

## CFn で作成
コンテナ定義と注意点だけ記述

```yml
ContainerDefinitions:
  - Name: nginx
    Image: 'nginx:latest'
    Essential: true
    PortMappings:
      - Protocol: tcp
        ContainerPort: 80
    LogConfiguration:
      LogDriver: awsfirelens
      Option:
        Name: firehose
        region: ap-northeast-1
        delivery_stream: firelens-stream
  - Name: firelens
    Image: '906394416424.dkr.ecr.ap-northeast-1.amazonaws.com/aws-for-fluent-bit:latest'
    Essential: true
    FirelensConfiguration:
      Type: fluentbit
    LogConfiguration:
      LogDraiver: awslogs
      Option:
        awslogs-create-group: true
        awslogs-region: ap-northeast-1
        awslogs-group: /ecs/firelens-container
        awslogs-stream-prefix: firelens
```
### Nginx コンテナ
- LogDriver に awsfirelens を指定
  - Option で東京リージョンの firehose の firelens-stream に送信する設定  
    → delivery_stream キーは yaml であっても 'snake_case' で記述

### FireLens コンテナ
- FirelensConfiguration キーを追加
  - Type キーの方に fluentbit を指定  
    → 階層に注意
- LogDriver に awslogs を指定
  - Option で東京リージョンの /ecs/firelens-container の firelens ストリームを作成し送信  
    → 用意していなければ LogGroup は明示的に作る必要がある

## 確認
S3
![S3-Logs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321137/275ffc7a-3eaf-fda8-ddff-ecb147263114.png)
CloudWatch Logs
![CloudWatch-Logs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321137/e6be5145-21f8-dc10-d8c2-f7eb70159fad.png)

# 総括
新しめのサービスなので試すだけでも割と楽しかった
delivery_stream キーと LogGroup 作成忘れでハマったのでもっと CFn 書き慣れていくべきだなという気持ち