diff --git a/lib/deploy/stepFunctions/compileIamRole.js b/lib/deploy/stepFunctions/compileIamRole.js index a6659e46..02cf6efd 100644 --- a/lib/deploy/stepFunctions/compileIamRole.js +++ b/lib/deploy/stepFunctions/compileIamRole.js @@ -225,6 +225,13 @@ function getLambdaPermissions(state) { }]; } + if (state.Parameters['FunctionName.$']) { + return [{ + action: 'lambda:InvokeFunction', + resource: state.Parameters.AllowedFunctions ? state.Parameters.AllowedFunctions : '*', + }]; + } + // hope for the best... return [{ action: 'lambda:InvokeFunction', diff --git a/lib/deploy/stepFunctions/compileIamRole.test.js b/lib/deploy/stepFunctions/compileIamRole.test.js index 61cfc8d7..de9f8f47 100644 --- a/lib/deploy/stepFunctions/compileIamRole.test.js +++ b/lib/deploy/stepFunctions/compileIamRole.test.js @@ -1831,4 +1831,101 @@ describe('#compileIamRole', () => { 'logs:DescribeLogGroups', ]); }); + + it('should support variable FunctionName', () => { + serverless.service.stepFunctions = { + stateMachines: { + myStateMachine1: { + id: 'StateMachine1', + definition: { + StartAt: 'A', + States: { + A: { + Type: 'Task', + Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken', + Parameters: { + 'FunctionName.$': '$.functionName', + Payload: { + 'model.$': '$.new_model', + 'token.$': '$$.Task.Token', + }, + }, + Next: 'B', + }, + B: { + Type: 'Task', + Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken', + Parameters: { + 'FunctionName.$': '$.functionName', + AllowedFunctions: '*limited*', + Payload: { + 'model.$': '$.new_model', + 'token.$': '$$.Task.Token', + }, + }, + End: true, + }, + }, + }, + }, + }, + }; + serverlessStepFunctions.compileIamRole(); + const statements = serverlessStepFunctions.serverless.service + .provider.compiledCloudFormationTemplate.Resources.StateMachine1Role + .Properties.Policies[0].PolicyDocument.Statement; + const lambdaPermissions = statements.filter(s => _.isEqual(s.Action, ['lambda:InvokeFunction'])); + expect(lambdaPermissions).to.have.lengthOf(1); + expect(lambdaPermissions[0].Resource).to.deep.equal('*'); + // Run the test again with limitations added + serverless.service.stepFunctions = { + stateMachines: { + myStateMachine1: { + id: 'StateMachine1', + definition: { + StartAt: 'A', + States: { + A: { + Type: 'Task', + Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken', + Parameters: { + 'FunctionName.$': '$.functionName', + AllowedFunctions: 'arn:aws:lambda:us-west-2:1234567890:function:foo', + Payload: { + 'model.$': '$.new_model', + 'token.$': '$$.Task.Token', + }, + }, + Next: 'B', + }, + B: { + Type: 'Task', + Resource: 'arn:aws:states:::lambda:invoke.waitForTaskToken', + Parameters: { + 'FunctionName.$': '$.functionName', + AllowedFunctions: '*limited*', + Payload: { + 'model.$': '$.new_model', + 'token.$': '$$.Task.Token', + }, + }, + End: true, + }, + }, + }, + }, + }, + }; + serverlessStepFunctions.compileIamRole(); + const statements2 = serverlessStepFunctions.serverless.service + .provider.compiledCloudFormationTemplate.Resources.StateMachine1Role + .Properties.Policies[0].PolicyDocument.Statement; + const lambdaPermissions2 = statements2.filter(s => _.isEqual(s.Action, ['lambda:InvokeFunction'])); + expect(lambdaPermissions2).to.have.lengthOf(1); + console.log(lambdaPermissions2); + expect(lambdaPermissions2[0].Resource).to.deep.equal([ + 'arn:aws:lambda:us-west-2:1234567890:function:foo', + '*limited*', + ]); + }); });