Skip to content

Commit 708f4c4

Browse files
fix: fix bug when there're no lambda versions
1 parent e967f04 commit 708f4c4

File tree

2 files changed

+126
-89
lines changed

2 files changed

+126
-89
lines changed

lib/deploy/stepFunctions/compileStateMachines.test.js

Lines changed: 115 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -849,98 +849,131 @@ describe('#compileStateMachines', () => {
849849
expect(lambda2Param).to.eql({ 'Fn::GetAtt': ['HelloDashworldLambdaFunction', 'Arn'] });
850850
});
851851

852-
it('should support using exact versions of functions', () => {
853-
serverless.service.stepFunctions = {
854-
stateMachines: {
855-
myStateMachine1: {
856-
id: 'Test',
857-
useExactVersion: true,
858-
definition: {
859-
StartAt: 'Lambda1',
860-
States: {
861-
Lambda1: {
862-
Type: 'Task',
863-
Resource: 'arn:aws:states:::lambda:invoke',
864-
Parameters: {
865-
FunctionName: {
866-
Ref: 'HelloLambdaFunction',
867-
},
868-
Payload: {
869-
'ExecutionName.$': '$$.Execution.Name',
852+
describe('#useExactVersions', () => {
853+
beforeEach(() => {
854+
serverless.service.stepFunctions = {
855+
stateMachines: {
856+
myStateMachine1: {
857+
id: 'Test',
858+
useExactVersion: true,
859+
definition: {
860+
StartAt: 'Lambda1',
861+
States: {
862+
Lambda1: {
863+
Type: 'Task',
864+
Resource: 'arn:aws:states:::lambda:invoke',
865+
Parameters: {
866+
FunctionName: {
867+
Ref: 'HelloLambdaFunction',
868+
},
869+
Payload: {
870+
'ExecutionName.$': '$$.Execution.Name',
871+
},
870872
},
873+
Next: 'Lambda2',
871874
},
872-
Next: 'Lambda2',
873-
},
874-
Lambda2: {
875-
Type: 'Task',
876-
Resource: {
877-
'Fn::GetAtt': ['WorldLambdaFunction', 'Arn'],
875+
Lambda2: {
876+
Type: 'Task',
877+
Resource: {
878+
'Fn::GetAtt': ['WorldLambdaFunction', 'Arn'],
879+
},
880+
End: true,
878881
},
879-
End: true,
880882
},
881883
},
882884
},
883885
},
884-
},
885-
};
886-
887-
serverlessStepFunctions.serverless.service
888-
.provider.compiledCloudFormationTemplate.Resources
889-
.HelloLambdaFunction = {
890-
Type: 'AWS::Lambda::Function',
891-
};
892-
893-
serverlessStepFunctions.serverless.service
894-
.provider.compiledCloudFormationTemplate.Resources
895-
.Lambda1Version13579 = {
896-
Type: 'AWS::Lambda::Version',
897-
Properties: {
898-
FunctionName: {
899-
Ref: 'HelloLambdaFunction',
900-
},
901-
},
902886
};
903887

904-
serverlessStepFunctions.serverless.service
905-
.provider.compiledCloudFormationTemplate.Resources
906-
.WorldLambdaFunction = {
907-
Type: 'AWS::Lambda::Function',
908-
};
888+
serverlessStepFunctions.serverless.service
889+
.provider.compiledCloudFormationTemplate.Resources
890+
.HelloLambdaFunction = {
891+
Type: 'AWS::Lambda::Function',
892+
};
893+
894+
serverlessStepFunctions.serverless.service
895+
.provider.compiledCloudFormationTemplate.Resources
896+
.WorldLambdaFunction = {
897+
Type: 'AWS::Lambda::Function',
898+
};
899+
});
900+
901+
const compileStateMachines = () => {
902+
serverlessStepFunctions.compileStateMachines();
903+
const stateMachine = serverlessStepFunctions.serverless.service
904+
.provider.compiledCloudFormationTemplate.Resources
905+
.Test;
906+
907+
expect(stateMachine.Properties.DefinitionString).to.haveOwnProperty('Fn::Sub');
908+
expect(stateMachine.Properties.DefinitionString['Fn::Sub']).to.have.lengthOf(2);
909+
910+
const [json, params] = stateMachine.Properties.DefinitionString['Fn::Sub'];
911+
const modifiedDefinition = JSON.parse(json);
912+
913+
const lambda1 = modifiedDefinition.States.Lambda1;
914+
expect(lambda1.Parameters.FunctionName.startsWith('${')).to.eq(true);
915+
const lambda1ParamName = lambda1.Parameters.FunctionName.replace(/[${}]/g, '');
916+
expect(params).to.haveOwnProperty(lambda1ParamName);
917+
const lambda1Param = params[lambda1ParamName];
918+
919+
const lambda2 = modifiedDefinition.States.Lambda2;
920+
expect(lambda2.Resource.startsWith('${')).to.eq(true);
921+
const lambda2ParamName = lambda2.Resource.replace(/[${}]/g, '');
922+
expect(params).to.haveOwnProperty(lambda2ParamName);
923+
const lambda2Param = params[lambda2ParamName];
924+
925+
return { lambda1Param, lambda2Param };
926+
};
909927

910-
serverlessStepFunctions.serverless.service
911-
.provider.compiledCloudFormationTemplate.Resources
912-
.Lambda2Version24680 = {
913-
Type: 'AWS::Lambda::Version',
914-
Properties: {
915-
FunctionName: {
916-
Ref: 'WorldLambdaFunction',
928+
it('should change refs to lambda version when useExactVersion is true', () => {
929+
serverlessStepFunctions.serverless.service
930+
.provider.compiledCloudFormationTemplate.Resources
931+
.Lambda1Version13579 = {
932+
Type: 'AWS::Lambda::Version',
933+
Properties: {
934+
FunctionName: {
935+
Ref: 'HelloLambdaFunction',
936+
},
917937
},
918-
},
919-
};
920-
921-
serverlessStepFunctions.compileStateMachines();
922-
const stateMachine = serverlessStepFunctions.serverless.service
923-
.provider.compiledCloudFormationTemplate.Resources
924-
.Test;
925-
926-
expect(stateMachine.Properties.DefinitionString).to.haveOwnProperty('Fn::Sub');
927-
expect(stateMachine.Properties.DefinitionString['Fn::Sub']).to.have.lengthOf(2);
928-
929-
const [json, params] = stateMachine.Properties.DefinitionString['Fn::Sub'];
930-
const modifiedDefinition = JSON.parse(json);
931-
932-
const lambda1 = modifiedDefinition.States.Lambda1;
933-
expect(lambda1.Parameters.FunctionName.startsWith('${')).to.eq(true);
934-
const lambda1ParamName = lambda1.Parameters.FunctionName.replace(/[${}]/g, '');
935-
expect(params).to.haveOwnProperty(lambda1ParamName);
936-
const lambda1Param = params[lambda1ParamName];
937-
expect(lambda1Param).to.eql({ Ref: 'Lambda1Version13579' });
938-
939-
const lambda2 = modifiedDefinition.States.Lambda2;
940-
expect(lambda2.Resource.startsWith('${')).to.eq(true);
941-
const lambda2ParamName = lambda2.Resource.replace(/[${}]/g, '');
942-
expect(params).to.haveOwnProperty(lambda2ParamName);
943-
const lambda2Param = params[lambda2ParamName];
944-
expect(lambda2Param).to.eql({ Ref: 'Lambda2Version24680' });
938+
};
939+
940+
serverlessStepFunctions.serverless.service
941+
.provider.compiledCloudFormationTemplate.Resources
942+
.Lambda2Version24680 = {
943+
Type: 'AWS::Lambda::Version',
944+
Properties: {
945+
FunctionName: {
946+
Ref: 'WorldLambdaFunction',
947+
},
948+
},
949+
};
950+
951+
const { lambda1Param, lambda2Param } = compileStateMachines();
952+
expect(lambda1Param).to.eql({ Ref: 'Lambda1Version13579' });
953+
expect(lambda2Param).to.eql({ Ref: 'Lambda2Version24680' });
954+
});
955+
956+
it('should not change refs to lambda version if version is not found, even if useExactVersion is true', () => {
957+
const { lambda1Param, lambda2Param } = compileStateMachines();
958+
expect(lambda1Param).to.eql({ Ref: 'HelloLambdaFunction' });
959+
expect(lambda2Param).to.eql({ 'Fn::GetAtt': ['WorldLambdaFunction', 'Arn'] });
960+
});
961+
962+
it('should not change refs to lambda version if not using intrinsic functions, even if useExactVersion is true', () => {
963+
const states = serverless.service.stepFunctions
964+
.stateMachines.myStateMachine1.definition.States;
965+
states.Lambda1.Parameters.FunctionName = 'hello';
966+
states.Lambda2.Resource = 'arn:aws:lambda:us-east-1:1234567890:function:world';
967+
968+
serverlessStepFunctions.compileStateMachines();
969+
const stateMachine = serverlessStepFunctions.serverless.service
970+
.provider.compiledCloudFormationTemplate.Resources
971+
.Test;
972+
973+
const definition = JSON.parse(stateMachine.Properties.DefinitionString);
974+
expect(definition.States.Lambda1.Parameters.FunctionName).to.equal('hello');
975+
expect(definition.States.Lambda2.Resource)
976+
.to.equal('arn:aws:lambda:us-east-1:1234567890:function:world');
977+
});
945978
});
946979
});

lib/utils/aws.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,25 @@ function convertToFunctionVersion(value) {
5151
return version[0];
5252
}
5353

54-
return logicalId;
54+
return null;
5555
};
5656

5757
if (_.has(value, 'Ref') && isFunction(value.Ref)) {
58-
return {
59-
Ref: getVersion(value.Ref),
60-
};
58+
const version = getVersion(value.Ref);
59+
if (version) {
60+
return { Ref: version };
61+
}
62+
return value;
6163
}
6264

6365
// for Lambda function, Get::Att can only return the ARN
6466
// but for Lambda version, you need Ref to get its ARN, hence why we return Ref here
6567
if (_.has(value, 'Fn::GetAtt') && isFunction(value['Fn::GetAtt'][0])) {
66-
return {
67-
Ref: getVersion(value['Fn::GetAtt'][0]),
68-
};
68+
const version = getVersion(value['Fn::GetAtt'][0]);
69+
if (version) {
70+
return { Ref: version };
71+
}
72+
return value;
6973
}
7074

7175
return value;

0 commit comments

Comments
 (0)