From 532bdc19bbc40aa4d6874945ab0edb66e9822281 Mon Sep 17 00:00:00 2001 From: Aleksander Dikanski Date: Wed, 14 Feb 2018 00:03:02 +0100 Subject: [PATCH 1/6] Add support for referenced custom authorizer lambdas --- lib/stackops/apiGateway.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/stackops/apiGateway.js b/lib/stackops/apiGateway.js index 8d7f218..b307682 100644 --- a/lib/stackops/apiGateway.js +++ b/lib/stackops/apiGateway.js @@ -225,7 +225,8 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const authorizerType = _.get(authorizer, 'Properties.Type'); if (authorizerType === 'TOKEN' || authorizerType === 'REQUEST') { const uriParts = authorizer.Properties.AuthorizerUri['Fn::Join'][1]; - const funcIndex = _.findIndex(uriParts, part => _.has(part, 'Fn::GetAtt')); + const funcIndex = _.findIndex(uriParts, part => + _.has(part, 'Fn::GetAtt') || (part.startsWith && part.startsWith('arn:aws:lambda'))); // Use the SERVERLESS_ALIAS stage variable to determine the called function alias uriParts.splice(funcIndex + 1, 0, ':${stageVariables.SERVERLESS_ALIAS}'); @@ -267,7 +268,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName)); // Adjust references and alias permissions - permission.Properties.FunctionName = { Ref: aliasName }; + permission.Properties.FunctionName = aliasName ? { Ref: aliasName } : permission.Properties.FunctionName; if (permission.Properties.SourceArn) { // Authorizers do not set the SourceArn property permission.Properties.SourceArn = { @@ -287,7 +288,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac } // Add dependency on function version - permission.DependsOn = [ versionName, aliasName ]; + permission.DependsOn = [ versionName, aliasName ].filter(name => name); delete stageStack.Resources[name]; }); From 74823219dda4b231d12bb2f1d119d477fa1cb4b7 Mon Sep 17 00:00:00 2001 From: Aleksander Dikanski Date: Wed, 14 Feb 2018 00:19:23 +0100 Subject: [PATCH 2/6] Resolve linting issues --- lib/stackops/apiGateway.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/stackops/apiGateway.js b/lib/stackops/apiGateway.js index b307682..eafed3b 100644 --- a/lib/stackops/apiGateway.js +++ b/lib/stackops/apiGateway.js @@ -225,8 +225,8 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const authorizerType = _.get(authorizer, 'Properties.Type'); if (authorizerType === 'TOKEN' || authorizerType === 'REQUEST') { const uriParts = authorizer.Properties.AuthorizerUri['Fn::Join'][1]; - const funcIndex = _.findIndex(uriParts, part => - _.has(part, 'Fn::GetAtt') || (part.startsWith && part.startsWith('arn:aws:lambda'))); + const funcIndex = _.findIndex(uriParts, part => + _.has(part, 'Fn::GetAtt') || _.startsWith(part, 'arn:aws:lambda')); // Use the SERVERLESS_ALIAS stage variable to determine the called function alias uriParts.splice(funcIndex + 1, 0, ':${stageVariables.SERVERLESS_ALIAS}'); @@ -288,7 +288,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac } // Add dependency on function version - permission.DependsOn = [ versionName, aliasName ].filter(name => name); + permission.DependsOn = _.compact([ versionName, aliasName ]); delete stageStack.Resources[name]; }); From c8bad858f639d67b7947af84870b86f980dd9776 Mon Sep 17 00:00:00 2001 From: Aleksander Dikanski Date: Wed, 14 Feb 2018 00:24:20 +0100 Subject: [PATCH 3/6] Fix intendation --- lib/stackops/apiGateway.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/stackops/apiGateway.js b/lib/stackops/apiGateway.js index eafed3b..5c29e9d 100644 --- a/lib/stackops/apiGateway.js +++ b/lib/stackops/apiGateway.js @@ -225,7 +225,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const authorizerType = _.get(authorizer, 'Properties.Type'); if (authorizerType === 'TOKEN' || authorizerType === 'REQUEST') { const uriParts = authorizer.Properties.AuthorizerUri['Fn::Join'][1]; - const funcIndex = _.findIndex(uriParts, part => + const funcIndex = _.findIndex(uriParts, part => _.has(part, 'Fn::GetAtt') || _.startsWith(part, 'arn:aws:lambda')); // Use the SERVERLESS_ALIAS stage variable to determine the called function alias @@ -288,7 +288,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac } // Add dependency on function version - permission.DependsOn = _.compact([ versionName, aliasName ]); + permission.DependsOn = _.compact([ versionName, aliasName ]); delete stageStack.Resources[name]; }); From c7d49a1b51ebf7a8b2ddccfce3f9e75a5fd171a2 Mon Sep 17 00:00:00 2001 From: Aleksander Dikanski Date: Thu, 15 Feb 2018 21:32:46 +0100 Subject: [PATCH 4/6] Seperate code path for referenced authorizers permissions --- lib/stackops/apiGateway.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/stackops/apiGateway.js b/lib/stackops/apiGateway.js index 5c29e9d..8bd33ba 100644 --- a/lib/stackops/apiGateway.js +++ b/lib/stackops/apiGateway.js @@ -266,9 +266,12 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const functionName = _.replace(name, /LambdaPermissionApiGateway$/, ''); const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName)); const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName)); - + const isExternalRef = _.startsWith(permission.Properties.FunctionName, 'arn:aws:lambda'); + // Adjust references and alias permissions - permission.Properties.FunctionName = aliasName ? { Ref: aliasName } : permission.Properties.FunctionName; + if (!isExternalRef) { + permission.Properties.FunctionName = { Ref: aliasName }; + } if (permission.Properties.SourceArn) { // Authorizers do not set the SourceArn property permission.Properties.SourceArn = { @@ -286,9 +289,13 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac ] }; } - + // Add dependency on function version - permission.DependsOn = _.compact([ versionName, aliasName ]); + if (!isExternalRef) { + permission.DependsOn = [ versionName, aliasName ]; + } else { + permission.DependsOn = _.compact([ versionName, aliasName ]); + } delete stageStack.Resources[name]; }); From 79e0e71e8a7da2e22d511b380971f4aeef355226 Mon Sep 17 00:00:00 2001 From: Aleksander Dikanski Date: Fri, 16 Feb 2018 00:13:54 +0100 Subject: [PATCH 5/6] Add test for referenced authorizers --- lib/stackops/apiGateway.js | 11 +- test/data/auth-stack-2.json | 425 +++++++++++++++++++++++++++++++ test/stackops/apiGateway.test.js | 39 +++ 3 files changed, 471 insertions(+), 4 deletions(-) create mode 100644 test/data/auth-stack-2.json diff --git a/lib/stackops/apiGateway.js b/lib/stackops/apiGateway.js index 8bd33ba..9996f66 100644 --- a/lib/stackops/apiGateway.js +++ b/lib/stackops/apiGateway.js @@ -225,11 +225,13 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const authorizerType = _.get(authorizer, 'Properties.Type'); if (authorizerType === 'TOKEN' || authorizerType === 'REQUEST') { const uriParts = authorizer.Properties.AuthorizerUri['Fn::Join'][1]; - const funcIndex = _.findIndex(uriParts, part => - _.has(part, 'Fn::GetAtt') || _.startsWith(part, 'arn:aws:lambda')); + if(_.every(uriParts, part => !_.startsWith(part, 'arn:aws:lambda'))) { + const funcIndex = _.findIndex(uriParts, part => + _.has(part, 'Fn::GetAtt') || _.startsWith(part, 'arn:aws:lambda')); - // Use the SERVERLESS_ALIAS stage variable to determine the called function alias - uriParts.splice(funcIndex + 1, 0, ':${stageVariables.SERVERLESS_ALIAS}'); + // Use the SERVERLESS_ALIAS stage variable to determine the called function alias + uriParts.splice(funcIndex + 1, 0, ':${stageVariables.SERVERLESS_ALIAS}'); + } } authorizer.Properties.Name = `${authorizer.Properties.Name}-${this._alias}`; @@ -268,6 +270,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName)); const isExternalRef = _.startsWith(permission.Properties.FunctionName, 'arn:aws:lambda'); + console.log('checking permission: ', name, JSON.stringify(permission), ' isExternalRef: ' + isExternalRef); // Adjust references and alias permissions if (!isExternalRef) { permission.Properties.FunctionName = { Ref: aliasName }; diff --git a/test/data/auth-stack-2.json b/test/data/auth-stack-2.json new file mode 100644 index 0000000..fc70a41 --- /dev/null +++ b/test/data/auth-stack-2.json @@ -0,0 +1,425 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "The AWS CloudFormation template for this Serverless application", + "Resources": { + "ServerlessDeploymentBucket": { + "Type": "AWS::S3::Bucket" + }, + "Testfct1LogGroup": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "/aws/lambda/sls-test-project-dev-testfct1" + } + }, + "TestauthLogGroup": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "/aws/lambda/sls-test-project-dev-testauth" + } + }, + "IamRoleLambdaExecution": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + }, + "Action": [ + "sts:AssumeRole" + ] + } + ] + }, + "Policies": [ + { + "PolicyName": { + "Fn::Join": [ + "-", + [ + "dev", + "sls-test-project", + "lambda" + ] + ] + }, + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "logs:CreateLogStream" + ], + "Resource": [ + { + "Fn::Sub": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/sls-test-project-dev-testfct1:*" + }, + { + "Fn::Sub": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/sls-test-project-dev-testauth:*" + } + ] + }, + { + "Effect": "Allow", + "Action": [ + "logs:PutLogEvents" + ], + "Resource": [ + { + "Fn::Sub": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/sls-test-project-dev-testfct1:*:*" + }, + { + "Fn::Sub": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/sls-test-project-dev-testauth:*:*" + } + ] + } + ] + } + } + ], + "Path": "/", + "RoleName": { + "Fn::Join": [ + "-", + [ + "sls-test-project", + "dev", + "us-east-1", + "lambdaRole" + ] + ] + } + } + }, + "Testfct1LambdaFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "ServerlessDeploymentBucket" + }, + "S3Key": "serverless/sls-test-project/dev/1496754891214-2017-06-06T13:14:51.214Z/sls-test-project.zip" + }, + "FunctionName": "sls-test-project-dev-testfct1", + "Handler": "handlers/testfct1/handler.handle", + "MemorySize": 512, + "Role": { + "Fn::GetAtt": [ + "IamRoleLambdaExecution", + "Arn" + ] + }, + "Runtime": "nodejs4.3", + "Timeout": 15, + "Description": "Echo function echoes alias", + "Environment": { + "Variables": { + "SERVERLESS_PROJECT_NAME": "sls-test-project", + "SERVERLESS_PROJECT": "sls-test-project", + "SERVERLESS_STAGE": "dev", + "SERVERLESS_REGION": "us-east-1", + "TEST_TABLE_NAME": { + "Ref": "TestDynamoDbTable" + } + } + } + }, + "DependsOn": [ + "Testfct1LogGroup", + "IamRoleLambdaExecution" + ] + }, + "Testfct1LambdaVersionrvZ7KY7UgzQ2OKbOvZoG1zLgodltc7toF3qYeORU": { + "Type": "AWS::Lambda::Version", + "DeletionPolicy": "Retain", + "Properties": { + "FunctionName": { + "Ref": "Testfct1LambdaFunction" + }, + "CodeSha256": "rvZ7KY7UgzQ2OKbOvZoG1zLgodltc7+to/F3q+YeORU=", + "Description": "Echo function echoes alias" + } + }, + "TestauthLambdaFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "ServerlessDeploymentBucket" + }, + "S3Key": "serverless/sls-test-project/dev/1496754891214-2017-06-06T13:14:51.214Z/sls-test-project.zip" + }, + "FunctionName": "sls-test-project-dev-testauth", + "Handler": "handlers/testauth/handler.handle", + "MemorySize": 512, + "Role": { + "Fn::GetAtt": [ + "IamRoleLambdaExecution", + "Arn" + ] + }, + "Runtime": "nodejs4.3", + "Timeout": 15, + "Description": "A custom authorizer", + "Environment": { + "Variables": { + "SERVERLESS_PROJECT_NAME": "sls-test-project", + "SERVERLESS_PROJECT": "sls-test-project", + "SERVERLESS_STAGE": "dev", + "SERVERLESS_REGION": "us-east-1", + "TEST_TABLE_NAME": { + "Ref": "TestDynamoDbTable" + } + } + } + }, + "DependsOn": [ + "TestauthLogGroup", + "IamRoleLambdaExecution" + ] + }, + "TestauthLambdaVersionrvZ7KY7UgzQ2OKbOvZoG1zLgodltc7toF3qYeORU": { + "Type": "AWS::Lambda::Version", + "DeletionPolicy": "Retain", + "Properties": { + "FunctionName": { + "Ref": "TestauthLambdaFunction" + }, + "CodeSha256": "rvZ7KY7UgzQ2OKbOvZoG1zLgodltc7+to/F3q+YeORU=", + "Description": "A custom authorizer" + } + }, + "ApiGatewayRestApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Name": "dev-sls-test-project" + } + }, + "ApiGatewayResourceFunc1": { + "Type": "AWS::ApiGateway::Resource", + "Properties": { + "ParentId": { + "Fn::GetAtt": [ + "ApiGatewayRestApi", + "RootResourceId" + ] + }, + "PathPart": "func1", + "RestApiId": { + "Ref": "ApiGatewayRestApi" + } + } + }, + "ApiGatewayMethodFunc1Get": { + "Type": "AWS::ApiGateway::Method", + "Properties": { + "HttpMethod": "GET", + "RequestParameters": {}, + "ResourceId": { + "Ref": "ApiGatewayResourceFunc1" + }, + "RestApiId": { + "Ref": "ApiGatewayRestApi" + }, + "AuthorizationType": "CUSTOM", + "AuthorizerId": { + "Ref": "TestauthApiGatewayAuthorizer" + }, + "Integration": { + "IntegrationHttpMethod": "POST", + "Type": "AWS_PROXY", + "Uri": { + "Fn::Join": [ + "", + [ + "arn:aws:apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "Testfct1LambdaFunction", + "Arn" + ] + }, + "/invocations" + ] + ] + } + }, + "MethodResponses": [] + }, + "DependsOn": "TestauthApiGatewayAuthorizer" + }, + "TestauthApiGatewayAuthorizer": { + "Type": "AWS::ApiGateway::Authorizer", + "Properties": { + "AuthorizerResultTtlInSeconds": 0, + "IdentitySource": "method.request.header.Authorization", + "Name": "testauth", + "RestApiId": { + "Ref": "ApiGatewayRestApi" + }, + "AuthorizerUri": { + "Fn::Join": [ + "", + [ + "arn:aws:apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + "arn:aws:lambda:us-east-1:", + { + "Ref": "AWS::AccountId" + }, + ":function:custom-auth", + "/invocations" + ] + ] + }, + "Type": "TOKEN" + } + }, + "TestauthApiGatewayRequestAuthorizer": { + "Type": "AWS::ApiGateway::Authorizer", + "Properties": { + "AuthorizerResultTtlInSeconds": 0, + "IdentitySource": "method.request.header.Authorization", + "Name": "testauthrequest", + "RestApiId": { + "Ref": "ApiGatewayRestApi" + }, + "AuthorizerUri": { + "Fn::Join": [ + "", + [ + "arn:aws:apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + { + "Fn::GetAtt": [ + "TestauthLambdaFunction", + "Arn" + ] + }, + "/invocations" + ] + ] + }, + "Type": "REQUEST" + } + }, + "CognitoTestApiGatewayAuthorizer": { + "Type": "AWS::ApiGateway::Authorizer", + "Properties": { + "AuthorizerResultTtlInSeconds": 0, + "IdentitySource": "method.request.header.Authorization", + "Name": "cognitoauth", + "RestApiId": { + "Ref": "ApiGatewayRestApi" + }, + "ProviderARNs": [ + "arn:aws:cognito-idp:us-west-2:xxxxx:userpool/us-west-xxxx" + ], + "Type": "COGNITO_USER_POOLS" + } + }, + "ApiGatewayDeployment1496754891256": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "RestApiId": { + "Ref": "ApiGatewayRestApi" + }, + "StageName": "dev" + }, + "DependsOn": [ + "ApiGatewayMethodFunc1Get" + ] + }, + "Testfct1LambdaPermissionApiGateway": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "FunctionName": { + "Fn::GetAtt": [ + "Testfct1LambdaFunction", + "Arn" + ] + }, + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Join": [ + "", + [ + "arn:aws:execute-api:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":", + { + "Ref": "ApiGatewayRestApi" + }, + "/*/*" + ] + ] + } + } + }, + "TestauthLambdaPermissionApiGateway": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "FunctionName": "arn:aws:lambda:us-east-1:${AWS::AccountId}:function:custom-auth", + "Action": "lambda:InvokeFunction", + "Principal": "apigateway.amazonaws.com" + } + } + }, + "Outputs": { + "ServerlessDeploymentBucketName": { + "Value": { + "Ref": "ServerlessDeploymentBucket" + } + }, + "Testfct1LambdaFunctionQualifiedArn": { + "Description": "Current Lambda function version", + "Value": { + "Ref": "Testfct1LambdaVersionrvZ7KY7UgzQ2OKbOvZoG1zLgodltc7toF3qYeORU" + } + }, + "TestauthLambdaFunctionQualifiedArn": { + "Description": "Current Lambda function version", + "Value": { + "Ref": "TestauthLambdaVersionrvZ7KY7UgzQ2OKbOvZoG1zLgodltc7toF3qYeORU" + } + }, + "ServiceEndpoint": { + "Description": "URL of the service endpoint", + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Ref": "ApiGatewayRestApi" + }, + ".execute-api.us-east-1.amazonaws.com/dev" + ] + ] + } + } + } +} diff --git a/test/stackops/apiGateway.test.js b/test/stackops/apiGateway.test.js index 8efee40..a4eb9f7 100644 --- a/test/stackops/apiGateway.test.js +++ b/test/stackops/apiGateway.test.js @@ -642,6 +642,7 @@ describe('API Gateway', () => { ] ] }; + const template = serverless.service.provider.compiledCloudFormationTemplate = stackTemplate; const cogAuth = _.cloneDeep(template.Resources.CognitoTestApiGatewayAuthorizer); cogAuth.Properties.Name += "-myAlias"; @@ -661,6 +662,44 @@ describe('API Gateway', () => { ])); }); + it('should support externally referenced custom authorizers', () => { + stackTemplate = _.cloneDeep(require('../data/auth-stack-2.json')); + const template = serverless.service.provider.compiledCloudFormationTemplate = stackTemplate; + const compiledAliasTemplate = serverless.service.provider.compiledCloudFormationAliasTemplate = aliasTemplate; + return expect(awsAlias.aliasHandleApiGateway({}, [], {})).to.be.fulfilled + .then(() => BbPromise.all([ + expect(template) + .to.have.a.nested.property("Resources.ApiGatewayMethodFunc1Get.Properties.AuthorizerId") + .that.deep.equals({ Ref: "TestauthApiGatewayAuthorizermyAlias" }), + expect(template) + .to.have.a.nested.property("Resources.ApiGatewayMethodFunc1Get.DependsOn") + .that.equals("TestauthApiGatewayAuthorizermyAlias"), + expect(template) + .to.have.a.nested.property('Resources.TestauthApiGatewayAuthorizermyAlias.Properties.AuthorizerUri') + .that.deep.equals({ + "Fn::Join": [ + "", + [ + "arn:aws:apigateway:", + { + "Ref": "AWS::Region" + }, + ":lambda:path/2015-03-31/functions/", + "arn:aws:lambda:us-east-1:", + { + "Ref": "AWS::AccountId" + }, + ":function:custom-auth", + "/invocations" + ] + ]}), + expect(compiledAliasTemplate) + .to.have.a.nested.property('Resources.TestauthLambdaPermissionApiGateway.DependsOn') + .that.is.empty + ])); + + }); + it('should transform string dependencies and references to authorizers', () => { const template = serverless.service.provider.compiledCloudFormationTemplate = stackTemplate; serverless.service.provider.compiledCloudFormationAliasTemplate = aliasTemplate; From 59529dcd638ab5d46ae4c85c382901ab1f955d93 Mon Sep 17 00:00:00 2001 From: Aleksander Dikanski Date: Fri, 16 Feb 2018 00:28:11 +0100 Subject: [PATCH 6/6] Fix linting errors --- lib/stackops/apiGateway.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/stackops/apiGateway.js b/lib/stackops/apiGateway.js index 9996f66..fdbca2f 100644 --- a/lib/stackops/apiGateway.js +++ b/lib/stackops/apiGateway.js @@ -225,7 +225,8 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const authorizerType = _.get(authorizer, 'Properties.Type'); if (authorizerType === 'TOKEN' || authorizerType === 'REQUEST') { const uriParts = authorizer.Properties.AuthorizerUri['Fn::Join'][1]; - if(_.every(uriParts, part => !_.startsWith(part, 'arn:aws:lambda'))) { + const isExternalRefAuthorizer = _.every(uriParts, part => !_.startsWith(part, 'arn:aws:lambda')); + if (isExternalRefAuthorizer) { const funcIndex = _.findIndex(uriParts, part => _.has(part, 'Fn::GetAtt') || _.startsWith(part, 'arn:aws:lambda')); @@ -269,8 +270,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName)); const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName)); const isExternalRef = _.startsWith(permission.Properties.FunctionName, 'arn:aws:lambda'); - - console.log('checking permission: ', name, JSON.stringify(permission), ' isExternalRef: ' + isExternalRef); + // Adjust references and alias permissions if (!isExternalRef) { permission.Properties.FunctionName = { Ref: aliasName };