I have been banging my head against a wall for days trying to get this to work…
We’re trying to deploy a serverless microservice using Azure DevOps CI/CD pipelines, and trying to implement the solution found here: https://medium.com/@bishwash.aryal/serverless-framework-build-immutable-package-for-ci-cd-pipeline-949b49f7df91
I need to be able to create immutable packages to promote through our pipeline, so this seemed to be a good workaround solution.
In my build step, I run serverless package to a folder and then delete the CF templates and state file, leaving only the generated myzipfile.zip. I then copy the serverless.yml and package.json files into that folder and zip the whole thing up into an outer zip file. This gets saved as the immutable artifact for the deployment stage.
Here’s the issue… in the deployment stage, when I extract this outer zip file on the build agent (I’ve also run in a local linux environment as a sanity check and get the same behavior), and try to run this command from the directory containing the serverless.yml, package.json, and myzipfile.zip:
serverless deploy --artifact myzipfile.zip --stage qa --region us-east-2
I get this error:
No matching handler found for 'handler' in '<directory-I'm-currently-in>'. Check your service definition.
Here’s my serverless.yml file (with some names changed for security reasons):
service:
name: my-service
package:
artifact: ${opt:artifact, ""}
# Add the serverless-webpack plugin
plugins:
- serverless-webpack
- serverless-offline
- serverless-domain-manager
custom:
stage: ${opt:stage, self:provider.stage}
domains:
prod: my-prod-domain.com
qa: my-qa-domain.com
dev: my-dev-domain.com
serverless-offline: ## add this two lines
port: 4000 ## bellow "custom:" line
customDomain:
domainName: ${self:custom.domains.${self:custom.stage}}
basePath: 'my-basebath' # This will be prefixed to all routes
stage: ${self:custom.stage}
createRoute53Record: true
provider:
name: aws
runtime: nodejs8.10
functions:
GetSomething:
handler: handler.GetSomething
events:
- http:
method: get
path: /{search_string}
cors: true
GetAllSomethings:
handler: handler.GetAllSomethings
events:
- http:
method: get
path: /
cors: true
I cannot figure out what the problem is. According to the documentation I’d expect the underlying serverless package to use the zip file I gave it, and not attempt to look for a source file… It seems like it’s trying to resolve the handler by looking for a file called handler in the directory, when handler.js is inside the myzipfile.zip file.
Can someone please help me with this?
Thanks!
Matt