AWS ECSでS3アクセスエラーを解決！ecsTaskExecutionRoleとecsTaskRoleの正しい使い分け

## 背景
ECSからS3にアクセスできないので解決していく

## やったこと

エラーを見ると`Unable to locate credentials` となっているので、
既存の ecs_task_execution_role に権限追加してやればいいのかな？

```
resource "aws_ecs_task_definition" "style_assistant_backend_task" {
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
}

resource "aws_iam_role" "ecs_task_execution_role" {
  name = "ecs_task_execution_role"

  inline_policy {
    name = "ecs_task_execution_policy"
    policy = jsonencode({
      Version = "2012-10-17",
      Statement = [
        {
          Effect = "Allow",
          Action = [
            "ecr:GetDownloadUrlForLayer",
            "ecr:BatchGetImage",
            "ecr:BatchCheckLayerAvailability",
            "ecr:GetAuthorizationToken",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
          ],
          Resource = "*"
        }
      ]
    })
  }
}
```

追加してみる
```
resource "aws_iam_role" "ecs_task_execution_role" {
  name = "ecs_task_execution_role"

  inline_policy {
    name = "ecs_task_execution_policy"
    policy = jsonencode({
      Version = "2012-10-17",
      Statement = [
        {
          Effect = "Allow",
          Action = [
            "ecr:GetDownloadUrlForLayer",
            "ecr:BatchGetImage",
            "ecr:BatchCheckLayerAvailability",
            "ecr:GetAuthorizationToken",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
          ],
          Resource = "*"
        },
        {
          Effect = "Allow",
          Action = [
            "s3:PutObject",
            "s3:GetObject",
            "s3:DeleteObject"
          ],
          Resource = "arn:aws:s3:::your_bucket_name/*"
        }
      ]
    })
  }
}
```

エラー消えない。何故？

GPTに聞いてみて試行錯誤してる時、こんな記事を見つけた
https://stackoverflow.com/questions/65992423/unable-to-locate-credentials-inside-fargate-container-using-boto3

ecsTaskExecutionRole と別に ecsTaskRole があるらしい。
使い分けはざっくりこんな感じ。

> ecsTaskExecutionRole: Docker Image などの操作
> ecsTaskRole： S3の操作


早速、ecsTaskRole　追加してみる。
```
resource "aws_ecs_task_definition" "style_assistant_backend_task" {
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  task_role_arn            = aws_iam_role.ecs_task_role.arn
}

resource "aws_iam_role" "ecs_task_role" {
  name = "ecs_task_role"

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

  inline_policy {
    name = "ecs_task_policy"
    policy = jsonencode({
      Version = "2012-10-17",
      Statement = [
        {
          Effect = "Allow",
          Action = [
            "s3:GetObject",
            "s3:PutObject",
            "s3:DeleteObject"
          ],
          Resource = "arn:aws:s3:::your_bucket_name/*"
        }
      ]
    })
  }
}
```

ECSからS3にアクセスできた。

## 学んだこと
ECS は ecsTaskExecutionRole と ecsTaskRole は、異なる２つの権限を持つ。
使い分けが必要

### ecsTaskExecutionRole
#### 目的
ECS 実行に必要な権限を提供する

#### 一般的な権限
- ECR からコンテナイメージをプルするためのアクセス
- CloudWatch Logs にログを送信するためのアクセス
- その他のタスク管理に必要な基本的な AWS サービスへのアクセス権限

### ecsTaskRole
#### 目的 
ECS 実行中に必要な権限を提供する

### 一般的な権限
- Amazon S3、DynamoDB、RDS など、他の AWS サービスへのアクセス
- アプリケーションに必要な外部リソースへのリクエストを扱うための権限
- AWS SDK や API コールを通じて他のサービスとやり取りするためのアクセス権限

### おまけ
ChatGPT はやはり万能ではない。StackOverflow や Qiita などで調べた方がサクッと解決することもあると改めて思った。

世の中のAIがもっと賢くなってもらうために、ここに記事を残す。

おしまい