refactor: Seclude IAM role resource name resolution logic

This commit is contained in:
Mariusz Nowak 2020-09-02 10:33:22 +02:00 committed by Mariusz Nowak
parent ee2355eb85
commit 6d7103da02
3 changed files with 34 additions and 60 deletions

View File

@ -96,36 +96,9 @@ class AwsCompileSQSEvents {
const queueLogicalId = this.provider.naming.getQueueLogicalId(functionName, queueName);
const funcRole = functionObj.role || this.serverless.service.provider.role;
let dependsOn = '"IamRoleLambdaExecution"';
if (funcRole) {
if (
// check whether the custom role is an ARN
typeof funcRole === 'string' &&
funcRole.indexOf(':') !== -1
) {
dependsOn = '[]';
} else if (
// otherwise, check if we have an in-service reference to a role ARN
typeof funcRole === 'object' &&
'Fn::GetAtt' in funcRole &&
Array.isArray(funcRole['Fn::GetAtt']) &&
funcRole['Fn::GetAtt'].length === 2 &&
typeof funcRole['Fn::GetAtt'][0] === 'string' &&
typeof funcRole['Fn::GetAtt'][1] === 'string' &&
funcRole['Fn::GetAtt'][1] === 'Arn'
) {
dependsOn = `"${funcRole['Fn::GetAtt'][0]}"`;
} else if (
// otherwise, check if we have an import
typeof funcRole === 'object' &&
'Fn::ImportValue' in funcRole
) {
dependsOn = '[]';
} else if (typeof funcRole === 'string') {
dependsOn = `"${funcRole}"`;
}
}
const dependsOn = JSON.stringify(
this.provider.resolveFunctionIamRoleResourceName(functionObj) || []
);
const sqsTemplate = `
{
"Type": "AWS::Lambda::EventSourceMapping",

View File

@ -192,36 +192,7 @@ class AwsCompileStreamEvents {
streamName
);
const funcRole = functionObj.role || this.serverless.service.provider.role;
let dependsOn = 'IamRoleLambdaExecution';
if (funcRole) {
if (
// check whether the custom role is an ARN
typeof funcRole === 'string' &&
funcRole.indexOf(':') !== -1
) {
dependsOn = [];
} else if (
// otherwise, check if we have an in-service reference to a role ARN
typeof funcRole === 'object' &&
'Fn::GetAtt' in funcRole &&
Array.isArray(funcRole['Fn::GetAtt']) &&
funcRole['Fn::GetAtt'].length === 2 &&
typeof funcRole['Fn::GetAtt'][0] === 'string' &&
typeof funcRole['Fn::GetAtt'][1] === 'string' &&
funcRole['Fn::GetAtt'][1] === 'Arn'
) {
dependsOn = funcRole['Fn::GetAtt'][0];
} else if (
// otherwise, check if we have an import or parameters ref
typeof funcRole === 'object' &&
('Fn::ImportValue' in funcRole || 'Ref' in funcRole)
) {
dependsOn = [];
} else if (typeof funcRole === 'string') {
dependsOn = funcRole;
}
}
const dependsOn = this.provider.resolveFunctionIamRoleResourceName(functionObj) || [];
const streamResource = {
Type: 'AWS::Lambda::EventSourceMapping',
DependsOn: dependsOn,

View File

@ -724,6 +724,36 @@ class AwsProvider {
throw new Error(`Unrecognized function address ${functionAddress}`);
}
resolveFunctionIamRoleResourceName(functionObj) {
const customRole = functionObj.role || this.serverless.service.provider.role;
if (customRole) {
if (typeof customRole === 'string') {
// check whether the custom role is an ARN
if (customRole.includes(':')) return null;
return customRole;
}
if (
// otherwise, check if we have an in-service reference to a role ARN
customRole['Fn::GetAtt'] &&
Array.isArray(customRole['Fn::GetAtt']) &&
customRole['Fn::GetAtt'].length === 2 &&
typeof customRole['Fn::GetAtt'][0] === 'string' &&
typeof customRole['Fn::GetAtt'][1] === 'string' &&
customRole['Fn::GetAtt'][1] === 'Arn'
) {
return customRole['Fn::GetAtt'][0];
}
if (
// otherwise, check if we have an import or parameters ref
customRole['Fn::ImportValue'] ||
customRole.Ref
) {
return null;
}
}
return 'IamRoleLambdaExecution';
}
getAlbTargetGroupPrefix() {
const provider = this.serverless.service.provider;
if (!provider.alb || !provider.alb.targetGroupPrefix) {