ECS Fargate、Fire Lensを使ってWebサーバーのログを直接S3保存（Terraform）

# 前書き

- 相変わらずノリと勢いで書いてしまっています。（悪い癖だ。。）
- 実際に稼働するものを実装した経験に基づき解説していますが、サンプルコードなどは公式のテンプレからとってきて解説していたりするので違和感・過不足あるかも。ごめんなさい。

[https://registry.terraform.io/providers/hashicorp/aws/latest/docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)

# 何をするの

- Fire Lensサービスを使ってFluent BitコンテナをWebサーバーコンテナのサイドカーとして稼働させロギングを任せます。（今回はECS ⇒ S3のパターン）

# 前提

- すでにアプリケーションがECS Fargateへデプロイされている。

# 全体像

関連リソースの作成（S3、Cloud Watch、ECR）
↓
Fluent BitコンテナDockerfileと設定ファイルの実装とECRヘのpush
↓
タスク定義の修正・追加

# 詳細

## ◾️ 関連リソースの作成（S3、Cloud Watch、ECR）

コンテナ稼働のための関連リソースを作成します。

実際に出力するログの保存先となるS3のバケットを作成しておきます。

s3.tf

```go
resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"
  acl    = "private"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}
```

Cloud Watchも。

cloudwatch.tf

```go
resource "aws_cloudwatch_log_group" "yada" {
  name = "Yada"

  tags = {
    Environment = "production"
    Application = "serviceA"
  }
}
```

また、ECRのリポジトリも作成しておきます。

ecr.tf

```go
resource "aws_ecr_repository" "foo" {
  name                 = "bar"
  image_tag_mutability = "MUTABLE"

  image_scanning_configuration {
    scan_on_push = true
  }
}
```

## ◾️ Fluent BitコンテナDockerfileと設定ファイルの実装とECRヘのpush

Fluent BitコンテナのDockerfileと設定ファイルを用意します。

Dockerfile

```go
FROM amazon/aws-for-fluent-bit:2.21.6
COPY ./extra.conf /fluent-bit/etc/extra.conf
```

extra.conf

```go
[OUTPUT]
    Name s3
    Match *
    bucket my-tf-test-bucket
    region ap-northeast-1
    total_file_size 1M
    upload_timeout 1m
    use_put_object On
```

confファイルについて解説していきます。Matchはタグをfilterしています。タグとは？？という感じですが、Fluent Bitを使用したECSからのログ出力では、ログのメッセージに `{コンテナ名}-firelens`という命名でタグなるものができるっぽいですね。

[https://aws.amazon.com/jp/blogs/containers/under-the-hood-firelens-for-amazon-ecs-tasks/#:~:text=されます。-,生成された構成ファイルのログタグ付け,-FluentdおよびFluentBit](https://aws.amazon.com/jp/blogs/containers/under-the-hood-firelens-for-amazon-ecs-tasks/#:~:text=%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82-,%E7%94%9F%E6%88%90%E3%81%95%E3%82%8C%E3%81%9F%E6%A7%8B%E6%88%90%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%83%AD%E3%82%B0%E3%82%BF%E3%82%B0%E4%BB%98%E3%81%91,-Fluentd%E3%81%8A%E3%82%88%E3%81%B3FluentBit)

なので、同じタスク定義内のコンテナごとのFirelensログ出力を制御しているというイメージでしょうか？？

total_file_sizeはS3へ転送する際のファイルサイズ指定（MB）、upload_timeoutはs3へファイルをputする間隔（分）、use_put_objectはS3PutObjectAPI利用のオプションのようです。

ちなみに上記のconf設定は、永続ディスクなしの場合に推奨されている設定です。

永続ディスクがない分、ローカルのバッファリングを少なくし、万が一コンテナが停止してしまった際にログの消失リスクを抑えるためですね。

[https://docs.fluentbit.io/manual/pipeline/outputs/s3#:~:text=このユースケースでは、次の設定をお勧めします。](https://docs.fluentbit.io/manual/pipeline/outputs/s3#:~:text=%E3%81%93%E3%81%AE%E3%83%A6%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%82%B9%E3%81%A7%E3%81%AF%E3%80%81%E6%AC%A1%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E3%81%8A%E5%8B%A7%E3%82%81%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)

上記のDockerfileと設定ファイルが出来上がったらECRへpushしておきましょう。

具体的な手順については以下を参照してください。本記事では割愛です。

[https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-push-ecr-image.html](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-push-ecr-image.html)

あとは残すところタスク定義の修正のみです。

## ◾️ タスク定義の修正・追加

 

やることは主に2つ。

1. これまで出力先をCloud WatchとしていたWebサーバーコンテナ側のロギング設定を修正
2. Fluent Bitコンテナの定義を追加

hogehoge-task-definition-json

まずはWebサーバーコンテナのロギング設定部分を以下のように変えます。

```go
...
// webサーバーコンテナ定義箇所
"name": "httpd",
...
"logConfiguration": {
    "logDriver": "awsfirelens" // ここがawslogsとかになっていると思うので変えます
},
...
```

```go
...
{
    // Fluent Bitコンテナ定義箇所
    "essential": true,
    "name": "{コンテナ名}",
    "image": "{awsアカウントID}/bar:{タグ名}", // あらかじめpushしておいたFluent Bitコンテナイメージを指定してください
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "{ロググループ名}",
        "awslogs-region": "ap-northeast-1",
        "awslogs-stream-prefix": "{ログストリームprefix名}"
      }
    },
    "firelensConfiguration": {
      "type": "fluentbit",
      "options": {
        "config-file-type": "file",
        "config-file-value": "/fluent-bit/etc/extra.conf" // ここはコンテナ側のファイルパスを指定してください。
      }
    }
  }
...
```

これでいつも通りの運用でデプロイし、あたらしくコンテナが起動すれば指定したS3のバケットへログが流れていくはずです。

# 追記

- 忘れていたのですが、Fire Lens経由でのログ出力に際してタスクロールのポリシーもいい感じにアタッチしておかないとダメかも☆

# 補足

だいぶはしょり気味になってしまったので、不足している内容が多々あったかと思います。

お詫びと言ってはなんですが、参考記事をまとめておきましたのでよければどぞ。

クラメソさん

[https://dev.classmethod.jp/articles/fargate-fiirelens-fluentbit/](https://dev.classmethod.jp/articles/fargate-fiirelens-fluentbit/)

[https://dev.classmethod.jp/articles/terraform-ecs-fargate-firelens-log-output/](https://dev.classmethod.jp/articles/terraform-ecs-fargate-firelens-log-output/)

AWS公式

[https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/firelens-taskdef.html](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/firelens-taskdef.html)

Fluent Bit 公式

[https://docs.fluentbit.io/manual/pipeline/outputs/s3#s3-key-format-and-tag-delimiters](https://docs.fluentbit.io/manual/pipeline/outputs/s3#s3-key-format-and-tag-delimiters)