Issue description
As I am adding a JWT authorizer, which is supposed to send requests to the Auth0 authorization server, to each endpoint’s Lambda function based on the deployment stage, I am receiving the error below when I tried to deploy by serverless deploy --stage local --region ap-east-1 --verbose
:
yarn run v1.22.19
$ bash ./scripts/deploy-local.sh
$ tsc
make_bucket failed: s3://myapp-users-local-deployments-ap-east-1 An error occurred (BucketAlreadyOwnedByYou) when calling the CreateBucket operation: Your previous request to create the named bucket succeeded and you already own it.
To ensure safe major version upgrades ensure "frameworkVersion" setting in service configuration (recommended setup: "frameworkVersion: ^3.38.0")
(node:57760) NOTE: We are formalizing our plans to enter AWS SDK for JavaScript (v2) into maintenance mode in 2023.
Please migrate your code to use AWS SDK for JavaScript (v3).
For more information, check the migration guide at https://a.co/7PzMCcy
(Use `node --trace-warnings ...` to show where the warning was created)
Deploying myapp-users to stage local (ap-east-1)
✖ Stack myapp-users-local failed to deploy (7s)
Environment: darwin, node 18.18.0, framework 3.38.0, plugin 7.2.0, SDK 4.5.1
Credentials: Local, "default" profile
Docs: docs.serverless.com
Support: forum.serverless.com
Bugs: github.com/serverless/serverless/issues
Error:
Function "localAuthorizer" doesn't exist in this Service
Context
I have defined 3 authorizers under the provider
section and each is used for a specific stage or a specific group of stages. Such implementation is based on the JWT Authorizers
section of the docmentation here: Serverless Framework - AWS Lambda Events - HTTP API (API Gateway v2)
Each function uses a custom variable that is returned based on the deployment stage
and originally defined as a set of function definitions. Each function definition in the set is stage-based and uses an authorizer, which is defined in the provider.httpApi
section and corresponds to the deployment stage
.
My serverless.yml is as follows:
// serverless.yml
custom:
stageBasedFunction: # function definition for `dev`, `staging`, `canary`
createUser:
handler: dist/createUser.handler
events:
- http:
path: user/create
method: post
authorizer:
name: stageBasedJWTAuthorizer
scopes:
- user.id
- user.email
getUser:
handler: dist/getUser.handler
events:
- http:
path: user
method: get
authorizer:
name: stageBasedJWTAuthorizer
scopes:
- user.id
- user.email
updateUser:
handler: dist/updateUser.handler
events:
- http:
path: user/{userId}/update
method: patch
authorizer:
name: stageBasedJWTAuthorizer
scopes:
- user.id
- user.email
deleteUser:
handler: dist/deleteUser.handler
events:
- http:
path: user/{userId}/delete
method: delete
authorizer:
name: stageBasedJWTAuthorizer
scopes:
- user.id
- user.email
createUser:
local:
handler: dist/createUser.handler
events:
- http:
path: user/create
method: post
authorizer:
name: localAuthorizer
scopes:
- user.id
- user.email
dev: ${self:custom.stageBasedFunction.createUser}
staging: ${self:custom.stageBasedFunction.createUser}
canary: ${self:custom.stageBasedFunction.createUser}
prod:
handler: dist/createUser.handler
events:
- http:
path: /user/create
method: post
authorizer:
name: prodAuthorizer
scopes:
- user.id
- user.email
getUser:
local:
handler: dist/getUser.handler
events:
- http:
path: user
method: get
authorizer:
name: localAuthorizer
scopes:
- user.id
- user.email
dev: ${self:custom.stageBasedFunction.getUser}
staging: ${self:custom.stageBasedFunction.getUser}
canary: ${self:custom.stageBasedFunction.getUser}
prod:
handler: dist/getUser.handler
events:
- http:
path: user
method: get
authorizer:
name: prodAuthorizer
scopes:
- user.id
- user.email
updateUser:
local:
handler: dist/updateUser.handler
events:
- http:
path: user/{userId}/update
method: patch
authorizer:
name: localAuthorizer
scopes:
- user.id
- user.email
dev: ${self:custom.stageBasedFunction.updateUser}
staging: ${self:custom.stageBasedFunction.updateUser}
canary: ${self:custom.stageBasedFunction.updateUser}
prod:
handler: dist/updateUser.handler
events:
- http:
path: user/{userId}/update
method: patch
authorizer:
name: prodAuthorizer
scopes:
- user.id
- user.email
deleteUser:
local:
handler: dist/deleteUser.handler
events:
- http:
path: user/{userId}/delete
method: delete
authorizer:
name: localAuthorizer
scopes:
- user.id
- user.email
dev: ${self:custom.stageBasedFunction.deleteUser}
staging: ${self:custom.stageBasedFunction.deleteUser}
canary: ${self:custom.stageBasedFunction.deleteUser}
prod:
handler: dist/deleteUser.handler
events:
- http:
path: user/{userId}/delete
method: delete
authorizer:
name: prodAuthorizer
scopes:
- user.id
- user.email
provider:
name: aws
endpointType: regional
runtime: nodejs20.x
region: ${opt:region, 'ap-east-1'} # Default to ap-east-1 if not specified
stage: ${opt:stage, 'dev'} # Default to dev if not specified
httpApi:
authorizers:
localAuthorizer:
type: jwt
identitySource: $request.header.Authorization
issuerUrl: https://myapp-dev.jp.auth0.com
audience:
- https://myapp-authorizer-identifier-from-auth0
stageBasedJWTAuthorizer:
type: jwt
identitySource: $request.header.Authorization
issuerUrl: https://myapp-${self:provider.stage}.jp.auth0.com
audience:
- https://myapp-authorizer-identifier-from-auth0
prodAuthorizer:
type: jwt
identitySource: $request.header.Authorization
issuerUrl: https://myapp.jp.auth0.com
audience:
- https://myapp-authorizer-identifier-from-auth0
functions:
createUser: ${self:custom.createUser.${self:provider.stage}}
updateUser: ${self:custom.updateUser.${self:provider.stage}}
deleteUser: ${self:custom.deleteUser.${self:provider.stage}}
getUser: ${self:custom.getUser.${self:provider.stage}}