Skip to content

Commit 1246f0d

Browse files
committed
feat: add IAM role to distributed_map to start the state machine
1 parent 42bd423 commit 1246f0d

File tree

2 files changed

+79
-7
lines changed

2 files changed

+79
-7
lines changed

lib/deploy/stepFunctions/compileIamRole.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,27 @@ const { getArnPartition } = require('../../utils/arn');
88

99
const logger = require('../../utils/logger');
1010

11-
function getTaskStates(states) {
11+
function getTaskStates(states, stateMachineName) {
1212
return _.flatMap(states, (state) => {
1313
switch (state.Type) {
1414
case 'Task': {
1515
return [state];
1616
}
1717
case 'Parallel': {
1818
const parallelStates = _.flatMap(state.Branches, branch => _.values(branch.States));
19-
return getTaskStates(parallelStates);
19+
return getTaskStates(parallelStates, stateMachineName);
2020
}
2121
case 'Map': {
2222
const mapStates = state.ItemProcessor ? state.ItemProcessor.States : state.Iterator.States;
23-
return getTaskStates(mapStates);
23+
const taskStates = getTaskStates(mapStates, stateMachineName);
24+
if (state.ItemProcessor && state.ItemProcessor.ProcessorConfig.Mode === 'DISTRIBUTED') {
25+
taskStates.push({
26+
Resource: 'arn:aws:states:::states:startExecution',
27+
Mode: 'DISTRIBUTED',
28+
StateMachineName: stateMachineName,
29+
});
30+
}
31+
return taskStates;
2432
}
2533
default: {
2634
return [];
@@ -299,9 +307,16 @@ function getLambdaPermissions(state) {
299307
}
300308

301309
function getStepFunctionsPermissions(state) {
302-
const stateMachineArn = state.Parameters['StateMachineArn.$']
303-
? '*'
304-
: state.Parameters.StateMachineArn;
310+
let stateMachineArn = state.Mode === 'DISTRIBUTED' ? {
311+
'Fn::Sub': [
312+
`arn:aws:states:\${AWS::Region}:\${AWS::AccountId}:stateMachine:${state.StateMachineName}`,
313+
],
314+
} : null;
315+
316+
if (!stateMachineArn) {
317+
stateMachineArn = state.Parameters['StateMachineArn.$'] ? '*'
318+
: state.Parameters.StateMachineArn;
319+
}
305320

306321
return [{
307322
action: 'states:StartExecution',
@@ -575,7 +590,7 @@ module.exports = {
575590
throw new Error(`Missing "definition" for state machine ${stateMachineName}`);
576591
}
577592

578-
const taskStates = getTaskStates(stateMachineObj.definition.States);
593+
const taskStates = getTaskStates(stateMachineObj.definition.States, stateMachineName);
579594
let iamPermissions = getIamPermissions.bind(this)(taskStates);
580595

581596
if (stateMachineObj.loggingConfig) {

lib/deploy/stepFunctions/compileIamRole.test.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,6 +2232,63 @@ describe('#compileIamRole', () => {
22322232
expect(lambdaPermissions[0].Resource).to.deep.equal(lambdaArns);
22332233
});
22342234

2235+
it('should support Distributed Map state type', () => {
2236+
const getStateMachine = (id, lambdaArn) => ({
2237+
id,
2238+
definition: {
2239+
StartAt: 'A',
2240+
States: {
2241+
A: {
2242+
Type: 'Map',
2243+
ItemProcessor: {
2244+
ProcessorConfig: {
2245+
Mode: 'DISTRIBUTED',
2246+
},
2247+
StartAt: 'B',
2248+
States: {
2249+
B: {
2250+
Type: 'Task',
2251+
Resource: lambdaArn,
2252+
End: true,
2253+
},
2254+
},
2255+
},
2256+
End: true,
2257+
},
2258+
},
2259+
},
2260+
});
2261+
2262+
serverless.service.stepFunctions = {
2263+
stateMachines: {
2264+
myStateMachine: getStateMachine('StateMachine1', 'arn:aws:lambda:us-west-2:1234567890:function:foo'),
2265+
},
2266+
};
2267+
2268+
serverlessStepFunctions.compileIamRole();
2269+
const statements = serverlessStepFunctions.serverless.service
2270+
.provider.compiledCloudFormationTemplate.Resources.StateMachine1Role
2271+
.Properties.Policies[0].PolicyDocument.Statement;
2272+
2273+
const lambdaPermissions = statements.filter(s => _.isEqual(s.Action, ['lambda:InvokeFunction']));
2274+
expect(lambdaPermissions).to.have.lengthOf(1);
2275+
2276+
const lambdaArns = [
2277+
'arn:aws:lambda:us-west-2:1234567890:function:foo',
2278+
getAlias('arn:aws:lambda:us-west-2:1234567890:function:foo'),
2279+
];
2280+
expect(lambdaPermissions[0].Resource).to.deep.equal(lambdaArns);
2281+
2282+
const stepFunctionPermission = statements.filter(s => _.isEqual(s.Action, ['states:StartExecution']));
2283+
expect(stepFunctionPermission).to.have.lengthOf(1);
2284+
expect(stepFunctionPermission[0].Resource).to.deep.eq([{
2285+
'Fn::Sub': [
2286+
'arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:myStateMachine',
2287+
],
2288+
},
2289+
]);
2290+
});
2291+
22352292
it('should support nested Map state type', () => {
22362293
const getStateMachine = (id, lambdaArn1, lambdaArn2) => ({
22372294
id,

0 commit comments

Comments
 (0)