Skip to content

Commit b9525e5

Browse files
feat: support local function names instead of logical id
1 parent 03d4f71 commit b9525e5

File tree

3 files changed

+51
-14
lines changed

3 files changed

+51
-14
lines changed

lib/deploy/stepFunctions/compileIamRole.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const _ = require('lodash');
44
const BbPromise = require('bluebird');
55
const path = require('path');
6-
const { isIntrinsic } = require('../../utils/aws');
6+
const { isIntrinsic, translateLocalFunctionNames } = require('../../utils/aws');
77

88
function getTaskStates(states) {
99
return _.flatMap(states, (state) => {
@@ -177,7 +177,7 @@ function getLambdaPermissions(state) {
177177
// so you should be able to use Fn::GetAtt here to get the ARN
178178
return [{
179179
action: 'lambda:InvokeFunction',
180-
resource: functionName,
180+
resource: translateLocalFunctionNames.bind(this)(functionName),
181181
}];
182182
} if (_.has(functionName, 'Ref')) {
183183
// because the FunctionName parameter can be either a name or ARN
@@ -188,7 +188,7 @@ function getLambdaPermissions(state) {
188188
'Fn::Sub': [
189189
'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${FunctionName}',
190190
{
191-
FunctionName: functionName,
191+
FunctionName: translateLocalFunctionNames.bind(this)(functionName),
192192
},
193193
],
194194
},
@@ -239,16 +239,16 @@ function consolidatePermissionsByResource(permissions) {
239239
.value(); // unchain
240240
}
241241

242-
function getIamPermissions(serverless, taskStates) {
242+
function getIamPermissions(taskStates) {
243243
return _.flatMap(taskStates, (state) => {
244244
switch (state.Resource) {
245245
case 'arn:aws:states:::sqs:sendMessage':
246246
case 'arn:aws:states:::sqs:sendMessage.waitForTaskToken':
247-
return getSqsPermissions(serverless, state);
247+
return getSqsPermissions(this.serverless, state);
248248

249249
case 'arn:aws:states:::sns:publish':
250250
case 'arn:aws:states:::sns:publish.waitForTaskToken':
251-
return getSnsPermissions(serverless, state);
251+
return getSnsPermissions(this.serverless, state);
252252

253253
case 'arn:aws:states:::dynamodb:updateItem':
254254
return getDynamoDBPermissions('dynamodb:UpdateItem', state);
@@ -274,16 +274,16 @@ function getIamPermissions(serverless, taskStates) {
274274

275275
case 'arn:aws:states:::lambda:invoke':
276276
case 'arn:aws:states:::lambda:invoke.waitForTaskToken':
277-
return getLambdaPermissions(state);
277+
return getLambdaPermissions.bind(this)(state);
278278

279279
default:
280280
if (isIntrinsic(state.Resource) || state.Resource.startsWith('arn:aws:lambda')) {
281281
return [{
282282
action: 'lambda:InvokeFunction',
283-
resource: state.Resource,
283+
resource: translateLocalFunctionNames.bind(this)(state.Resource),
284284
}];
285285
}
286-
serverless.cli.consoleLog('Cannot generate IAM policy statement for Task state', state);
286+
this.serverless.cli.consoleLog('Cannot generate IAM policy statement for Task state', state);
287287
return [];
288288
}
289289
});
@@ -317,7 +317,7 @@ module.exports = {
317317
customRolesProvided.push('role' in stateMachineObj);
318318

319319
const taskStates = getTaskStates(stateMachineObj.definition.States);
320-
iamPermissions = iamPermissions.concat(getIamPermissions(this.serverless, taskStates));
320+
iamPermissions = iamPermissions.concat(getIamPermissions.bind(this)(taskStates));
321321
});
322322
if (_.isEqual(_.uniq(customRolesProvided), [true])) {
323323
return BbPromise.resolve();

lib/deploy/stepFunctions/compileStateMachines.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const _ = require('lodash');
44
const BbPromise = require('bluebird');
55
const Chance = require('chance');
6-
const { isIntrinsic } = require('../../utils/aws');
6+
const { isIntrinsic, translateLocalFunctionNames } = require('../../utils/aws');
77

88
const chance = new Chance();
99

@@ -83,13 +83,17 @@ module.exports = {
8383
.replace(/\\n|\\r|\\n\\r/g, '');
8484
} else {
8585
const functionMappings = Array.from(getIntrinsicFunctions(stateMachineObj.definition));
86+
const definitionString = JSON.stringify(stateMachineObj.definition, undefined, 2);
87+
8688
if (_.isEmpty(functionMappings)) {
87-
DefinitionString = JSON.stringify(stateMachineObj.definition, undefined, 2);
89+
DefinitionString = definitionString;
8890
} else {
91+
const f = translateLocalFunctionNames.bind(this);
92+
const params = _.fromPairs(functionMappings.map(([k, v]) => [k, f(v)]));
8993
DefinitionString = {
9094
'Fn::Sub': [
91-
JSON.stringify(stateMachineObj.definition, undefined, 2),
92-
_.fromPairs(functionMappings),
95+
definitionString,
96+
params,
9397
],
9498
};
9599
}

lib/utils/aws.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,39 @@ function isIntrinsic(obj) {
55
&& Object.keys(obj).some(k => k.startsWith('Fn::') || k === 'Ref');
66
}
77

8+
// translates local function names, e.g. hello-world
9+
// to logical resource name, e.g. HelloDashworldLambdaFunction
10+
function translateLocalFunctionNames(value) {
11+
const resources = this.serverless.service.provider.compiledCloudFormationTemplate.Resources;
12+
const functions = this.serverless.service.functions;
13+
14+
const translate = (logicalId) => {
15+
if (!_.has(resources, logicalId) && _.has(functions, logicalId)) {
16+
const functionName = logicalId;
17+
return this.provider.naming.getLambdaLogicalId(functionName);
18+
}
19+
20+
return logicalId;
21+
};
22+
23+
if (_.has(value, 'Ref')) {
24+
const logicalId = value.Ref;
25+
return {
26+
Ref: translate(logicalId),
27+
};
28+
}
29+
30+
if (_.has(value, 'Fn::GetAtt')) {
31+
const [logicalId, prop] = value['Fn::GetAtt'];
32+
return {
33+
'Fn::GetAtt': [translate(logicalId), prop],
34+
};
35+
}
36+
37+
return value;
38+
}
39+
840
module.exports = {
941
isIntrinsic,
42+
translateLocalFunctionNames,
1043
};

0 commit comments

Comments
 (0)