为什么我的 Lambda 不允许在 ECS 资源上运行任务?
Why is my Lambda not allowed to RunTask on ECS resource?
我刚刚创建了一个 AWS ECS 集群和任务定义,运行一切正常。我能够连接到服务器。任务在 Fargate 上 运行ning 和按需 运行s。我现在正在尝试创建一个 Lambda,它将 运行 RunTask 命令启动服务器。这是我在 Terraform 中的 Lambda 定义。
data "aws_iam_policy_document" "startup_lambda_assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role" "startup_lambda" {
name = "report_lambda_role"
assume_role_policy = data.aws_iam_policy_document.startup_lambda_assume_role.json
}
resource "aws_cloudwatch_log_group" "startup_lambda" {
name = "/aws/lambda/${aws_lambda_function.startup.function_name}"
retention_in_days = 14
}
data "aws_iam_policy_document" "startup_lambda" {
statement {
effect = "Allow"
actions = [
"logs:CreateLogStream",
"logs:CreateLogGroup",
]
resources = [aws_cloudwatch_log_group.startup_lambda.arn]
}
statement {
effect = "Allow"
actions = ["logs:PutLogEvents"]
resources = ["${aws_cloudwatch_log_group.startup_lambda.arn}:*"]
}
statement {
effect = "Allow"
actions = [
"ecs:RunTask",
]
resources = [
aws_ecs_task_definition.game.arn
]
}
statement {
effect = "Allow"
actions = [
"iam:PassRole",
]
resources = [
aws_iam_role.ecs_task_execution.arn,
aws_iam_role.game_task.arn
]
}
}
resource "aws_iam_role_policy" "startup_lambda" {
name = "startup_lambda_policy"
policy = data.aws_iam_policy_document.startup_lambda.json
role = aws_iam_role.startup_lambda.id
}
data "archive_file" "startup_lambda" {
type = "zip"
source_file = "${path.module}/startup/lambda_handler.py"
output_path = "${path.module}/startup/lambda_handler.zip"
}
resource "aws_lambda_function" "startup" {
function_name = "startup_lambda"
filename = data.archive_file.startup_lambda.output_path
handler = "lambda_handler.handler"
source_code_hash = data.archive_file.startup_lambda.output_base64sha256
runtime = "python3.8"
role = aws_iam_role.startup_lambda.arn
environment {
variables = {
CLUSTER_ARN = aws_ecs_cluster.game.arn,
TASK_ARN = aws_ecs_cluster.game.arn,
SUBNET_IDS = "${aws_subnet.subnet_a.id},${aws_subnet.subnet_b.id},${aws_subnet.subnet_c.id}"
}
}
}
这是我的 Python 代码,位于 startup/lambda_handler.py 中,当我在 AWS 控制台中检查时,它作为函数代码正确显示。
import os
import boto3
def handler (event, callback):
client = boto3.client("ecs")
response = client.run_task(
cluster = os.getenv("CLUSTER_ARN"),
taskDefinition = os.getenv("TASK_ARN"),
launchType = "FARGATE",
count = 1,
networkConfiguration = {
"awsvpcConfiguration": {
"subnets": os.getenv("SUBNET_IDS", "").split(","),
"assignPublicIp": "ENABLED",
},
},
)
当我 运行 使用空 JSON 对象作为参数在控制台中测试 Lambda 函数时,我希望看到我的 ECS 任务启动,但我得到了以下信息错误。
Response
{
"errorMessage": "An error occurred (AccessDeniedException) when calling the RunTask operation: User: arn:aws:sts::703606424838:assumed-role/report_lambda_role/startup_lambda is not authorized to perform: ecs:RunTask on resource: * because no identity-based policy allows the ecs:RunTask action",
"errorType": "AccessDeniedException",
"stackTrace": [
" File \"/var/task/lambda_handler.py\", line 6, in handler\n response = client.run_task(\n",
" File \"/var/runtime/botocore/client.py\", line 386, in _api_call\n return self._make_api_call(operation_name, kwargs)\n",
" File \"/var/runtime/botocore/client.py\", line 705, in _make_api_call\n raise error_class(parsed_response, operation_name)\n"
]
}
请注意,在我的 Lambda 随附的 IAM 策略文档中,我的任务定义中确实有 ecs:RunTask 允许的声明。我不确定为什么这不给 Lambda 权限 运行 任务。
您传递给您的 lambda 容器的 TASK_ARN
是错误的。应该是 aws_ecs_task_definition.game.arn
而不是重复的 aws_ecs_cluster.game.arn
.
我刚刚创建了一个 AWS ECS 集群和任务定义,运行一切正常。我能够连接到服务器。任务在 Fargate 上 运行ning 和按需 运行s。我现在正在尝试创建一个 Lambda,它将 运行 RunTask 命令启动服务器。这是我在 Terraform 中的 Lambda 定义。
data "aws_iam_policy_document" "startup_lambda_assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role" "startup_lambda" {
name = "report_lambda_role"
assume_role_policy = data.aws_iam_policy_document.startup_lambda_assume_role.json
}
resource "aws_cloudwatch_log_group" "startup_lambda" {
name = "/aws/lambda/${aws_lambda_function.startup.function_name}"
retention_in_days = 14
}
data "aws_iam_policy_document" "startup_lambda" {
statement {
effect = "Allow"
actions = [
"logs:CreateLogStream",
"logs:CreateLogGroup",
]
resources = [aws_cloudwatch_log_group.startup_lambda.arn]
}
statement {
effect = "Allow"
actions = ["logs:PutLogEvents"]
resources = ["${aws_cloudwatch_log_group.startup_lambda.arn}:*"]
}
statement {
effect = "Allow"
actions = [
"ecs:RunTask",
]
resources = [
aws_ecs_task_definition.game.arn
]
}
statement {
effect = "Allow"
actions = [
"iam:PassRole",
]
resources = [
aws_iam_role.ecs_task_execution.arn,
aws_iam_role.game_task.arn
]
}
}
resource "aws_iam_role_policy" "startup_lambda" {
name = "startup_lambda_policy"
policy = data.aws_iam_policy_document.startup_lambda.json
role = aws_iam_role.startup_lambda.id
}
data "archive_file" "startup_lambda" {
type = "zip"
source_file = "${path.module}/startup/lambda_handler.py"
output_path = "${path.module}/startup/lambda_handler.zip"
}
resource "aws_lambda_function" "startup" {
function_name = "startup_lambda"
filename = data.archive_file.startup_lambda.output_path
handler = "lambda_handler.handler"
source_code_hash = data.archive_file.startup_lambda.output_base64sha256
runtime = "python3.8"
role = aws_iam_role.startup_lambda.arn
environment {
variables = {
CLUSTER_ARN = aws_ecs_cluster.game.arn,
TASK_ARN = aws_ecs_cluster.game.arn,
SUBNET_IDS = "${aws_subnet.subnet_a.id},${aws_subnet.subnet_b.id},${aws_subnet.subnet_c.id}"
}
}
}
这是我的 Python 代码,位于 startup/lambda_handler.py 中,当我在 AWS 控制台中检查时,它作为函数代码正确显示。
import os
import boto3
def handler (event, callback):
client = boto3.client("ecs")
response = client.run_task(
cluster = os.getenv("CLUSTER_ARN"),
taskDefinition = os.getenv("TASK_ARN"),
launchType = "FARGATE",
count = 1,
networkConfiguration = {
"awsvpcConfiguration": {
"subnets": os.getenv("SUBNET_IDS", "").split(","),
"assignPublicIp": "ENABLED",
},
},
)
当我 运行 使用空 JSON 对象作为参数在控制台中测试 Lambda 函数时,我希望看到我的 ECS 任务启动,但我得到了以下信息错误。
Response
{
"errorMessage": "An error occurred (AccessDeniedException) when calling the RunTask operation: User: arn:aws:sts::703606424838:assumed-role/report_lambda_role/startup_lambda is not authorized to perform: ecs:RunTask on resource: * because no identity-based policy allows the ecs:RunTask action",
"errorType": "AccessDeniedException",
"stackTrace": [
" File \"/var/task/lambda_handler.py\", line 6, in handler\n response = client.run_task(\n",
" File \"/var/runtime/botocore/client.py\", line 386, in _api_call\n return self._make_api_call(operation_name, kwargs)\n",
" File \"/var/runtime/botocore/client.py\", line 705, in _make_api_call\n raise error_class(parsed_response, operation_name)\n"
]
}
请注意,在我的 Lambda 随附的 IAM 策略文档中,我的任务定义中确实有 ecs:RunTask 允许的声明。我不确定为什么这不给 Lambda 权限 运行 任务。
您传递给您的 lambda 容器的 TASK_ARN
是错误的。应该是 aws_ecs_task_definition.game.arn
而不是重复的 aws_ecs_cluster.game.arn
.