Serverless
Table of Contents
Overview
You can use Serverless CLI with serverless
or sls
command.
Subcommands:
config ........................ Configure Serverless
config credentials ............ Configures a new provider profile for the Serverless Framework
create ........................ Create new Serverless service
deploy ........................ Deploy a Serverless service
deploy function ............... Deploy a single function from the service
deploy list ................... List deployed version of your Serverless Service
deploy list functions ......... List all the deployed functions and their versions
info .......................... Display information about the service
install ....................... Install a Serverless service from GitHub or a plugin from the Serverless registry
invoke ........................ Invoke a deployed function
invoke local .................. Invoke function locally
logs .......................... Output the logs of a deployed function
metrics ....................... Show metrics for a specific function
package ....................... Packages a Serverless service
Reference
serverless.yml
serverless-domain-manager
serverless-dynamodb-local
dynamodb:
start:
seed: true
seed:
<category>:
sources:
- table: domain-widgets
sources: [./data.json]
serverless-python-requirements
dockerizePip: non-linux
for making Lambda compatible packaging- Supports
Pipenv
by default
serverless-wsgi
service: example
provider:
name: aws
runtime: python2.7
plugins:
- serverless-wsgi
functions:
api:
handler: wsgi.handler
events:
- http: ANY /
- http: ANY {proxy+}
custom:
wsgi:
app: api.app
IS_OFFLINE
envvar is included when serving (1.4.1)
* Running on http://localhost:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 109-942-480
Topics
Services
users/
serverless.yml # Contains 4 functions that do Users CRUD operations and the Users database
posts/
serverless.yml # Contains 4 functions that do Posts CRUD operations and the Posts database
comments/
serverless.yml # Contains 4 functions that do Comments CRUD operations and the Comments database
serverless.yml
- Declare a Serverless service
- Define one or more functions in the service
- Define the provider the service will be deployed to (and the runtime if provided)
- Define any custom plugins to be used
- Define events that trigger each function to execute (e.g. HTTP requests)
- Define a set of resources (e.g. 1 DynamoDB table) required by the functions in this service
- Allow events listed in the events section to automatically create the resources required for the event upon deployment
- Allow flexible configuration using Serverless Variables
Functions
- Your functions can either inherit their settings from the
provider
property.
functions:
functionOne:
handler: handler.functionOne
description: optional description for your Lambda
functionTwo:
handler: handler.functionTwo
functionThree:
handler: handler.functionThree
provider:
name: aws
environment:
SYSTEM_NAME: mySystem
TABLE_NAME: tableName1
functions:
hello:
handler: handler.users
environment:
TABLE_NAME: tableName2 # overrides
Events
Resources
- Based on getStackName, though not explicitly documented, it seems that every stack is related to
stage
!<Function>
syntax is not supported- https://github.com/serverless/serverless/issues/3184#issuecomment-304671007
Resource:
"Fn::Sub": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table..."
provider:
name: aws
runtime: nodejs6.10
# Allow for cf "AWS::" variables, see https://serverless.com/framework/docs/providers/aws/guide/variables#using-custom-variable-syntax
variableSyntax: "\\${(?!AWS::)([ :a-zA-Z0-9._,\\-\\/\\(\\)]+?)}"
Deploying
serverless deploy --verbose # uses AWS CloudFormation Stack Update
serverless deploy function --function myFunction # updates AWS Lambda only
serverless deploy --stage production --region eu-central-1
Variables
x: ${env:NAME} # Environment Variables
x: ${env:NAME, 'temp'} # default
x: ${opt:stage} # CLI Options
x: ${cf:service.name} # CloudFormation
x: ${self:custom.stage} # self reference
x: ${s3:bucket/key} # value(content) of the s3 object
x: ${file(../config.yml):name} # js, json or yaml, can be json object or equivalents
Packaging
Serverless will run the glob patterns in order. At first it will apply the globs defined in exclude
. After that it'll add all the globs from include
.
module.exports = {
defaultExcludes: [
'.git/**',
'.gitignore',
'.DS_Store',
'npm-debug.log',
'serverless.yml',
'serverless.yaml',
'serverless.json',
'serverless.js',
'.serverless/**',
'.serverless_plugins/**',
],
IAM
As those statements will be merged into the CloudFormation template, you can use
Join
,Ref
or any other CloudFormation method or feature.
Additional Policies on the generated policies
- provider.iamRoleStatements
- Define additional policies in the CloudFormation format
- provider.iamManagedPolicies
- Additional policies managed outside of serverless
service: new-service
provider:
name: aws
iamRoleStatements:
- Effect: "Allow"
Action:
- "s3:ListBucket"
Resource:
Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: ServerlessDeploymentBucket
- Effect: "Allow"
Action:
- "s3:PutObject"
Resource:
Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: ServerlessDeploymentBucket
- "/*"
iamManagedPolicies:
- 'some:aws:arn:xxx:*:*'
- 'someOther:aws:arn:xxx:*:*'
- { 'Fn::Join': [':', ['arn:aws:iam:', { Ref: 'AWSAccountId' }, 'some/path']] }
Completely custom roles
Using this way means that
iamRoleStatements
you've defined on the provider level won't be applied anymore. Furthermore, you need to provide the corresponding permissions for your Lambdas logs and stream events.
provider:
name: aws
# declare one of the following...
role: myDefaultRole # must validly reference a role defined in the service
role: arn:aws:iam::0123456789:role//my/default/path/roleInMyAccount # must validly reference a role defined in your account
role: # must validly resolve to the ARN of a role you have the rights to use
Fn::GetAtt:
- myRole
- Arn
Plugins
How-to
Deploy Flask App
Set Custom Domains
plugins:
- serverless-domain-manager
custom:
customDomain:
domainName: <registered_domain_name>
basePath: ''
stage: ${self:provider.stage}
createRoute53Record: true
If you're using a certificate that doesn't exactly match your domain name, such as a wildcard certificate, you'll need to specify the certificate name with a
certificateName
property undercustomDomain
.
custom:
domain:
dev: MY_DEV_DOMAIN
prod: MY_PROD_DOMAIN
customDomain:
basePath: ''
domainName: ${self:custom.domain.${opt:stage}}
stage: ${opt:stage}
createRoute53Record: true
Enable CORS
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
cors:
origin: '*'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
allowCredentials: false
If you want to use CORS with the lambda-proxy integration, You should handle CORS within your application.
For Lambda or HTTP proxy integrations, you can still set up the required
OPTIONS
response headers in API Gateway. However, you must rely on the back end to return theAccess-Control-Allow-Origin
headers because the integration response is disabled for the proxy integration.