From 2f841492976f17c4324b469bf3967268006bd17b Mon Sep 17 00:00:00 2001 From: Renan William Alves de Paula Date: Fri, 18 Jul 2025 10:48:44 -0300 Subject: [PATCH] fix: add missing ecs:TagResource permission for ECS tasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using serverless-step-functions to deploy ECS tasks with tags, the auto-generated IAM policies were missing the ecs:TagResource permission. This caused Step Functions executions to fail with an AccessDeniedException when attempting to tag ECS tasks. This commit adds the ecs:TagResource permission to the getEcsPermissions function, allowing ECS tasks to be properly tagged during execution. Fixes #656 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- lib/deploy/stepFunctions/compileIamRole.js | 2 +- lib/deploy/stepFunctions/compileIamRole.test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/deploy/stepFunctions/compileIamRole.js b/lib/deploy/stepFunctions/compileIamRole.js index c3675c8..d01a53e 100644 --- a/lib/deploy/stepFunctions/compileIamRole.js +++ b/lib/deploy/stepFunctions/compileIamRole.js @@ -176,7 +176,7 @@ function getGluePermissions() { function getEcsPermissions() { return [{ - action: 'ecs:RunTask,ecs:StopTask,ecs:DescribeTasks,iam:PassRole', + action: 'ecs:RunTask,ecs:StopTask,ecs:DescribeTasks,ecs:TagResource,iam:PassRole', resource: '*', }, { action: 'events:PutTargets,events:PutRule,events:DescribeRule', diff --git a/lib/deploy/stepFunctions/compileIamRole.test.js b/lib/deploy/stepFunctions/compileIamRole.test.js index 8bc28f7..ea92a91 100644 --- a/lib/deploy/stepFunctions/compileIamRole.test.js +++ b/lib/deploy/stepFunctions/compileIamRole.test.js @@ -1651,7 +1651,7 @@ describe('#compileIamRole', () => { .provider.compiledCloudFormationTemplate.Resources.StateMachine1Role .Properties.Policies[0].PolicyDocument.Statement; - const ecsPermissions = statements.filter(s => _.isEqual(s.Action, ['ecs:RunTask', 'ecs:StopTask', 'ecs:DescribeTasks', 'iam:PassRole'])); + const ecsPermissions = statements.filter(s => _.isEqual(s.Action, ['ecs:RunTask', 'ecs:StopTask', 'ecs:DescribeTasks', 'ecs:TagResource', 'iam:PassRole'])); expect(ecsPermissions).to.have.lengthOf(1); expect(ecsPermissions[0].Resource).to.equal('*'); @@ -2694,7 +2694,7 @@ describe('#compileIamRole', () => { const expectation = (policy, lambdaArns, sns, sqsArn) => { const statements = policy.PolicyDocument.Statement; - const ecsPermissions = statements.filter(s => _.isEqual(s.Action, ['ecs:RunTask', 'ecs:StopTask', 'ecs:DescribeTasks', 'iam:PassRole'])); + const ecsPermissions = statements.filter(s => _.isEqual(s.Action, ['ecs:RunTask', 'ecs:StopTask', 'ecs:DescribeTasks', 'ecs:TagResource', 'iam:PassRole'])); expect(ecsPermissions).to.have.lengthOf(1); expect(ecsPermissions[0].Resource).to.equal('*');