🤖
ECSからAWS CLIでS3へアクセス
背景
s3へのアクセスをecsから行いたい。
aws configureしなくてもaws cliがecsコンテナ内部から使えるらしいと知ったので試してみた。
設定
こんな感じで、AmazonS3ReadOnlyAccessを付与したecs task execution roleを付与したら行けた.
task_roleとexecution_roleの違いがわからず、若干ハマる...
- task_role: ecsのコンテナ内で実行するプログラムからアクセスする際の権限.
- execution_role: ecsコンテナを起動する際の権限.
ecs.tf
resource "aws_ecs_cluster" "cluster" {
provider = aws.this
name = "${local.app_name}-cluster"
}
resource "aws_iam_role" "ecs_task_execution" {
provider = aws.this
name = "${local.app_name}-ecs-task-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
}
]
})
managed_policy_arns = [
"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
]
}
resource "aws_iam_role" "ecs_task_inside" {
provider = aws.this
name = "${local.app_name}-ecs-task-inside-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
}
]
})
managed_policy_arns = [
"arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess",
aws_iam_policy.ecs_s3_access_policy.arn
]
}
resource "aws_cloudwatch_log_group" "log_group" {
provider = aws.this
name = "${local.app_name}-log-group"
retention_in_days = 7
}
resource "aws_ecs_task_definition" "task" {
provider = aws.this
family = "${local.app_name}-task"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
memory = "1024"
cpu = "512"
execution_role_arn = aws_iam_role.ecs_task_execution.arn
task_role_arn = aws_iam_role.ecs_task_inside.arn
container_definitions = jsonencode([
{
name = "${local.app_name}-container"
image = local.image_url
essential = true
memory = 1024
cpu = 512
portMappings = [
{
containerPort = 80
hostPort = 80
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = aws_cloudwatch_log_group.log_group.name
"awslogs-region" = local.region
"awslogs-stream-prefix" = "ecs"
}
}
}
])
}
s3.tf
resource "aws_s3_bucket" "bucket" {
provider = aws.this
bucket = "${local.app_name}-playground"
}
resource "aws_s3_bucket_ownership_controls" "s3_bucket_ownership_controls" {
provider = aws.this
bucket = aws_s3_bucket.bucket.id
rule {
object_ownership = "BucketOwnerEnforced"
}
}
resource "aws_iam_policy" "ecs_s3_access_policy" {
provider = aws.this
name = "${local.app_name}_ecs_s3_access_policy"
description = "Allow ECS tasks to access S3"
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
Resource = [
"arn:aws:s3:::${aws_s3_bucket.bucket.id}",
"arn:aws:s3:::${aws_s3_bucket.bucket.id}/*"
]
}
]
})
}
実行
こんな感じで実行確認できた
run.sh
aws ecs run-task \
--cluster "$CLUSTER" \
--task-definition "$TASK_ARN" \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[$SUBNETS],securityGroups=[$ECS_ID],assignPublicIp=ENABLED}"
Discussion