個人的な備忘録：Terraform で ECS タスク定義に CloudWatch Logs を設定し、エラーを解析してみた

## はじめに
ECSで動作するコンテナのログをAWS CloudWatch Logsに送信することで、リアルタイムのモニタリングやデバッグが容易になります。

:::note info
**特に、Terraformを使ってECSタスク定義(`aws_ecs_task_definition`)にCloudWatch Logsを設定すると、コードベースで一元管理でき、環境構築の自動化も可能です。**
:::

本記事では、CloudWatch Logsの設定方法やメリットを解説し、実際の活用事例も紹介します。

## 書こうと思ったきっかけ
今回、ITスクールのハッカソンでインフラのコード化を行った際に、ECSのコンテナが起動しないトラブルに直面しました。

:::note warn
***原因を特定するためにCloudWatch Logsを設定したところ、コンテナ内部のエラーログを詳細に確認でき、スムーズにデバッグが可能となりました。***
:::

この経験をもとに、CloudWatch Logsの設定手順と実際の活用方法を整理し、備忘録としてまとめました。

## CloudWatch Logs を設定するメリット

- **リアルタイム監視**  
  - コンテナのログを AWS マネジメントコンソールでリアルタイムに確認可能。  

- **トラブルシューティング**  
  - アプリのクラッシュやエラーの原因を素早く特定できる。  

- **一元管理**  
  - 各 ECS タスクのログを一か所に集約し、検索・分析が容易。  

- **セキュアなログ管理**  
  - AWS IAM によるアクセス制御が可能で、不要なログの削除や保存期間の設定もできる。  


## 実際に解説してみた

### 1. CloudWatch Logs グループを作成
まず、CloudWatch Logs にログを送信するためのロググループを作成します。

```hcl
resource "aws_cloudwatch_log_group" "ecs_log_group" {
  name              = "/ecs/my-ecs-task"
  retention_in_days = 7  # ログの保持期間（必要に応じて変更）
}
```

- **name**：ロググループ名（`/ecs/タスク名` の形式が推奨）  
- **retention_in_days**：ログの保持期間（例: `7` は 7 日間）  

### 2. ECS タスク実行ロールに CloudWatch のログ書き込み権限を付与
ECS タスクが CloudWatch にログを送信できるように、適切な IAM ロールを設定します。

```hcl
resource "aws_iam_role" "ecs_task_execution_role" {
  name = "ecs-task-execution-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "ecs-tasks.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
  role       = aws_iam_role.ecs_task_execution_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
```

このポリシー (`AmazonECSTaskExecutionRolePolicy`) により、ECS タスクが CloudWatch Logs にログを送信できるようになります。

### 3. ECS タスク定義で CloudWatch Logs を設定
`logConfiguration` を追加し、コンテナのログを CloudWatch に送信するように設定します。

```hcl
resource "aws_ecs_task_definition" "my_task" {
  family                   = "my-ecs-task"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  cpu                      = "256"
  memory                   = "512"

  container_definitions = jsonencode([
    {
      name      = "my-app"
      image     = "my-docker-image"
      essential = true

      logConfiguration = {
        logDriver = "awslogs"
        options = {
          awslogs-group         = aws_cloudwatch_log_group.ecs_log_group.name
          awslogs-region        = "ap-northeast-1"
          awslogs-stream-prefix = "my-app"
        }
      }
    }
  ])
}
```

- **logDriver = "awslogs"**：CloudWatch Logs を使用する  
- **awslogs-group**：作成した CloudWatch ロググループ名  
- **awslogs-region**：リージョンを指定  
- **awslogs-stream-prefix**：ログストリームのプレフィックス（コンテナごとに識別しやすくするため）  

### ここまでの設定のまとめ

| 設定項目 | 説明 |
|----------|------|
| **CloudWatch Logs グループ作成** | `aws_cloudwatch_log_group` でログ保存先を定義 |
| **IAM ロールの設定** | `AmazonECSTaskExecutionRolePolicy` を付与 |
| **ECS タスク定義の logConfiguration** | `logDriver = "awslogs"` で CloudWatch にログ送信 |
| **Terraform 適用** | `terraform apply` で反映 |

この設定で、ECS のコンテナログを CloudWatch で簡単に管理できます！

## 実際にログを取得してみた
今回、受講しているITスクールのハッカソンでインフラをコード化しました。**詳細は省略しますが、以下のリポジトリにコードを公開しています。**

https://github.com/Winter-Hackathon-2025-A-Team/skill-typing-infra-Terraform

実際にコンテナ内部でエラーが発生し、起動しないトラブルがありました。そのため、上記の手順に沿ってCloudWatch Logsグループを設定しました。

![Screenshot 2025-02-06 at 10.42.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/10a253c5-ad4a-ecaf-d8fc-6443247e3ab7.png)

すると、以下のようにエラーログが大量に出力され、コンテナ内部の状況を可視化できました。

![Screenshot 2025-02-06 at 10.43.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ceed61b7-1dcc-d876-1626-ed75acb3144a.png)

このように、CloudWatch Logsを設定することでアプリケーション内部のエラーログを簡単に確認でき、トラブルシューティングがスムーズになります。

## まとめ

- **ECS タスク定義で CloudWatch Logs を設定すると、コンテナのログをリアルタイムで確認可能。**  
- **エラー発生時のトラブルシューティングがしやすくなり、デバッグ作業がスムーズになる。**  
- **Terraform を使うことで、インフラのコード管理ができ、環境構築を自動化できる。**  
- **CloudWatch Logs は、開発・運用の両方で有用なツールであり、今後も積極的に活用したい。**  

今後も、**実際の開発・運用の現場で CloudWatch Logs を活用し、より効率的な監視とデバッグの仕組みを構築** していきたいと考えています。