Develop, deploy, troubleshoot and secure your serverless applications with radically less overhead and cost by using the Serverless Framework. The Serverless Framework consists of an open source CLI and a hosted dashboard. Together, they provide you with full serverless application lifecycle management.
https://www.serverless.com/framework/docs/getting-started
Including stage parameters, etc.
https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml
https://www.serverless.com/framework/docs/providers/aws/guide/variables
npm install serverless
npm install serverless@3.39.0
//npm install [package-name]@[version-number]
//-g = global
//-i = skip the execution of any scripts that are defined in the package.json file
npm update -g serverless
npx serverless
Deploy static files to, eg S3, using the plugin finch
sls client deploy --stage dev
sls create --template aws-nodejs
serverless deploy --region eu-west-1 --stage dev
Install local DynamoDB, which can be use later w/ sls offline start
sls dynamodb install
Migrate database
sls dynamodb migrate
Service information, endpoints (eg: of a lambda), functions, layers
serverless info
serverless info --region eu-west-1 --stage labs
Invoke a deployed function
sls invoke -f hello
Invoke a non-deployed function
sls invoke local -f hello
Retrieve logs of function
sls logs myfunction
sls offline start
The sls remove command will remove the deployed service, defined in your current working directory, from the provider.
serverless remove --region eu-west-1 --stage dev
Eg: sixqueue
https://www.serverless.com/plugins/serverless-add-api-key
To create api key and usage pattern (if they don't already exist) and associate them to the Rest Api.
It matches API Key by name, ignores it if it already exists.
Eg: sixqueue
https://www.serverless.com/plugins/serverless-plugin-ifelse
It allows conditional serverless.yml
Eg: gsm, sixqueue
https://www.serverless.com/plugins/serverless-prune-plugin
Following deployment, the Serverless Framework does not purge previous versions of functions from AWS, so the number of deployed versions can grow out of hand rather quickly. This plugin allows pruning of all but the most recent version(s) of managed functions from AWS.
Install:
npm install --save-dev serverless-prune-plugin
and add it to the serverless.yml:
plugins:
- serverless-prune-plugin
Usage, delete all but the n-most recent versions of each function deployed. Versions references by an alias are automatically preserved:
sls prune -n <number of version to keep>
For serverless version < 2.50.0; it allows to use #{AWS::AccountId}, #{AWS::Region}, etc. in any of your config strings.
https://www.npmjs.com/package/serverless-pseudo-parameters
Install w/ npm:
npm install --save serverless-pseudo-parameters
and add it to the serverless.yml plugins list:
plugins:
- serverless-pseudo-parameters
Eg: sixqueue
https://www.serverless.com/plugins/serverless-python-requirements
The plugin will bundle your python dependencies specified in your Pipfile when you run sls deploy.
Add the plugin to package.json and the plugins section of serverless.yml
sls plugin install -n serverless-python-requirements
You can reference SSM Parameters as the source of your variables with the ssm:/path/to/param syntax. For example:
${ssm:/${self:provider.stackTags.env}/${self:provider.stackTags.ci}/salesforce_username}
For decrypting SecureString (WithDecryption: true) add ~true. Eg:
${ssm:/${self:provider.stackTags.env}/${self:provider.stackTags.ci}/salesforce_password~true}
a) If using HTTP API (API Gateway v2), not REST API:
provider:
environment:
API_URL: !GetAtt HttpApi.ApiEndpoint
Example:
!Join ['', [!GetAtt HttpApi.ApiEndpoint, '/mylambda']]
b) If using REST API (API Gateway v1), not HTTP API:
provider:
environment:
API_URL: !Sub 'https://${ApiGatewayRestApi}.execute-api.${aws:region}.amazonaws.com/${sls:stage}'
In serverless.yml:
provider:
iamRoleStatements:
- Effect: "Allow"
Action:
- "ssm:GetParameter"
Resource: arn:aws:ssm:${self:provider.region}:#{AWS::AccountId}:parameter/${self:provider.stackTags.UOCEnv}/${self:provider.stackTags.ci}/*
- Effect: "Allow"
Action:
- "kms:Decrypt"
Resource: arn:aws:kms:*:#{AWS::AccountId}:key/alias/aws/ssm
and in the functions section:
functions:
create:
handler: event.jobs
layers:
- arn:aws:lambda:eu-west-1:015030872274:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11
events:
- http:
path: ${self:service}/jobs
method: post
cors: true
private: true
Sample request:
import urllib.parse
import urllib.request
aws_session_token = get_env('AWS_SESSION_TOKEN')
req = urllib.request.Request('http://localhost:2773/systemsmanager/parameters/get?name=' + urllib.parse.quote('/env/ci/cl_id') + '&withDecryption=true')
req.add_header('X-Aws-Parameters-Secrets-Token', aws_session_token)
config = urllib.request.urlopen(req).read().decode('utf-8')
Sample response:
{"Parameter":{"ARN":"arn:aws:ssm:eu-west-1:434374682878:parameter/env/ci/cl_id","DataType":"text","LastModifiedDate":"2024-01-08T16:16:42.673Z","Name":"/env/ci/cl_id","Selector":null,"SourceResult":null,"Type":"String","Value":"MyValue","Version":1},"ResultMetadata":{}}
It allows to add CloudFormation resources to the servelss.yml
resources:
Resources:
SecurityGroupLambda: #AWS CloudFormation yaml synxtax
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'Assigned to authorizer lambda and configured on the OAuth server to allow connections from it'
GroupName: ${self:provider.stackTags.env}-${self:provider.stackTags.ci}-lambda-sg
SecurityGroupEgress:
- CidrIp: 0.0.0.0/0
Description: 'IPv4 allow all outbound traffic, eg to the OAuth server'
IpProtocol: -1
- CidrIpv6: ::/0
Description: 'IPv6 allow all outbound traffic, eg to the OAuth server'
IpProtocol: -1
#SecurityGroupIngress: ~
VpcId: ${param:vpc_id}
Outputs:
SgIdForOauth:
Description: 'SG id to be configured in the OAuth server to allow connections from this lambda authorizer'
Value: !Ref SecurityGroupLambda
The id of the created SG can be referenced this way:
securityGroupIds:
- Ref: SecurityGroupLambda
The 'output' (the id of the created security group in this case) can be obtained with:
aws cloudformation describe-stacks --stack-name <ci>-<stage> --output text --region eu-west-1 --query "Stacks[0].Outputs[?OutputKey=='SgIdForOauth'].OutputValue"
package.json contains the 'version' in a Serveless package.
It can be obtained from a Python lambda via:
import json
def lambda_handler(event, context):
with open('package.json', 'r') as f_ver:
f_ver_dict = json.load(f_ver)
tech_comp_version = f_ver_dict.get("version")
logger.info("======== Artifact version: %s ========", tech_comp_version)
TLDR: Manually delete the cloud formation stack in AWS console, and then redeploy.