Long story short, I don't want to have to hardcode in ECS task definition revision numbers for tasks into my lambda source codes. It's essentially toil updating my source code each time I have an updated task definition. In the boto3 documentation for ECS run_task()
, it clearly states
taskDefinition (string) -- [REQUIRED]
The family and revision (family:revision ) or full ARN of the task definition to run. If a revision is not specified, the latest ACTIVE revision is used.
However, I am finding that if I define the taskDefinition
parameter in client.run_task()
with no specific revision number, I get a permission error:
An error occurred (AccessDeniedException) when calling the RunTask operation: User: arn:aws:sts::MY_ACCOUNT_ID:assumed-role/my-lambda-role/trigger-ecs-task is not authorized to perform: ecs:RunTask on resource: arn:aws:ecs:MY_REGION:MY_ACCOUNT_ID:task-definition/an-important-task
If I switch my definition to an-important-task:LATEST
or an-important-task:*
, I get another error:
...is not authorized to perform: ecs:RunTask on resource: *
This is strange, because it appears contrary to what the documentation states- when I include a revision number, like an-important-task:5
, the lambda triggers perfectly. In my lambda function, I simply invoke my ECS task:
def lambda_handler(event, context):
client = boto3.client('ecs')
print("Running task.")
response = client.run_task(
cluster='my-cluster',
launchType='FARGATE',
taskDefinition='an-important-task', # <-- notice no revision number
count=1,
platformVersion='LATEST',
networkConfiguration={
'awsvpcConfiguration': {
'subnets': [
'subnet-1',
'subnet-2'
],
'assignPublicIp': 'DISABLED'
}
})
print("Finished invoking task.")
In my Terraform definition, I've attached the necessary policies to my role:
resource "aws_lambda_function" "trigger-ecs-task" {
function_name = "trigger-ecs-task"
handler = "my-lambda-function.lambda_handler"
role = "${aws_iam_role.lambda.arn}"
runtime = "python3.6"
# other stuff related to how I store my source code for the lambda
}
My role definition, and attaching the permissions to run ECS tasks:
resource "aws_iam_role" "lambda" {
name = "my-lambda-ecs-role"
assume_role_policy = "${data.aws_iam_policy_document.lambda-assume-role.json}"
}
data "aws_iam_policy_document" "lambda-assume-role" {
statement {
actions = [
"sts:AssumeRole"]
principals {
type = "Service"
identifiers = [
"lambda.amazonaws.com"]
}
}
}
resource "aws_iam_policy" "run-ecs-policy" {
name = "run-ecs-task-policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "ecs:RunTask",
"Resource": "arn:aws:ecs:MY_REGION:MY_ACCOUNT_ID:task-definition/an-important-task:*"
},
{
"Sid": "Stmt1512361993201",
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": [
"arn:aws:iam::************:role/${data.aws_iam_role.ecs-task-execution-role.name}"
]
}
]
}
EOF
}
I attach the policy below:
resource "aws_iam_role_policy_attachment" "service-role-attach" {
role = "${aws_iam_role.lambda.name}"
policy_arn = "${aws_iam_policy.run-ecs-policy.arn}"
}
Why is AWS refusing to run my task if I don't specify a specific revision? In my policy definition, I am clearly giving permission to runTask
on all revisions of the resource:
arn:aws:ecs:MY_REGION:MY_ACCOUNT_ID:task-definition/an-important-task:*
"You can invoke Lambda functions directly with the Lambda console, the Lambda API, the AWS SDK, the AWS CLI, and AWS toolkits." So you'll have to decide which method is going to work best for your ECS tasks. You will need to set the correct permissions so that your ECS will be able to invoke the Lambda function.
The family and container definitions are required in a task definition. In contrast, task role, network mode, volumes, task placement constraints, and launch type are optional. You can use these parameters in a JSON file to configure your task definition.
Your application can span multiple task definitions. You can do this by combining related containers into their own task definitions, each representing a single component.
I was able to replicate your behavior and resolved the issue with following Resource
in IAM Policy.
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "ecs:RunTask",
"Resource": "arn:aws:ecs:MY_REGION:MY_ACCOUNT_ID:task-definition/an-important-task"
}
If you are planning to provide with revision then the resource should have :*
in it or it has to exactly exactly match with taskDefinition
.
Let me know how it goes at your end!!.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With