I tried Serverless framework with Python+AWS Lambda.
Node.js and npm:
$ node -v
v10.19.0
$ npm -v
7.5.2
I created my serverless account with Google SSO:
sudo npm install -g serverless
Create a project:
$ serverless
Serverless: No project detected. Do you want to create a new one? Yes
Serverless: What do you want to make? AWS Python
Serverless: What do you want to call this project? hello-sl-python
Project successfully created in 'hell-sl-python' folder.
You can monitor, troubleshoot, and test your new service with a free Serverless account.
Serverless: Would you like to enable this? Yes
You are not logged in or you do not have a Serverless account.
Serverless: Do you want to login or register? login
Serverless: Logging you in via your default browser...
Serverless: You sucessfully logged in to Serverless.
Serverless: Please run 'serverless' to configure your service
Serverless: What do you want to name this application? hello-serverless
Your project is setup for monitoring, troubleshooting and testing
Serverless: Would you like to setup a command line <tab> completion? Yes
Serverless: Which Shell do you use ? bash
Serverless: We will install completion to ~/.bashrc, is it ok ? Yes
Command line <tab> completion was successfully setup. Make sure to reload your SHELL.
You may uninstall it by running: serverless config tabcompletion uninstall
Deploy your project and monitor, troubleshoot and test it:
- Run “serverless deploy” to deploy your service.
- Run “serverless dashboard” to view the dashboard.
hello-sl-python
directory structure:
.
├── handler.py
└── serverless.yml
handler.py
:
import json
def hello(event, context):
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
# Use this code if you don't use the http event with the LAMBDA-PROXY
# integration
"""
return {
"message": "Go Serverless v1.0! Your function executed successfully!",
"event": event
}
"""
Default serverless.yml
without comment lines:
service: hello-sl-python
app: hello-serverless
org: atlex00
frameworkVersion: '2'
provider:
name: aws
runtime: python3.8
lambdaHashingVersion: 20201221
functions:
hello:
handler: handler.hello
Change functions
as follows:
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: post
Deploy the handler
:
$ serverless deploy -v
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Installing dependencies for custom CloudFormation resources...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - hello-sl-python-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_IN_PROGRESS - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_COMPLETE - AWS::S3::BucketPolicy - ServerlessDeploymentBucketPolicy
CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - hello-sl-python-dev
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service hello-sl-python.zip file to S3 (81.83 KB)...
Serverless: Uploading custom CloudFormation resources...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - hello-sl-python-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - ApiGatewayLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleCustomResourcesLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleCustomResourcesLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - ApiGatewayLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - HelloLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - ApiGatewayLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::SubscriptionFilter - CloudWatchLogsSubscriptionFilterHelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::SubscriptionFilter - CloudWatchLogsSubscriptionFilterApiGatewayLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::SubscriptionFilter - CloudWatchLogsSubscriptionFilterHelloLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::SubscriptionFilter - CloudWatchLogsSubscriptionFilterApiGatewayLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::SubscriptionFilter - CloudWatchLogsSubscriptionFilterHelloLogGroup
CloudFormation - CREATE_COMPLETE - AWS::Logs::SubscriptionFilter - CloudWatchLogsSubscriptionFilterApiGatewayLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - EnterpriseLogAccessIamRole
CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - EnterpriseLogAccessIamRole
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleCustomResourcesLambdaExecution
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - CustomDashresourceDashapigwDashcwDashroleLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - CustomDashresourceDashapigwDashcwDashroleLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - CustomDashresourceDashapigwDashcwDashroleLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - EnterpriseLogAccessIamRole
CloudFormation - CREATE_IN_PROGRESS - Custom::ApiGatewayAccountRole - CustomApiGatewayAccountCloudWatchRole
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersionu0ef7NQRbLbF3GnoljE9IcuPhKydwlJy6rHj1t8AKrU
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloPost
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloPost
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - HelloLambdaVersionu0ef7NQRbLbF3GnoljE9IcuPhKydwlJy6rHj1t8AKrU
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloPost
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - HelloLambdaVersionu0ef7NQRbLbF3GnoljE9IcuPhKydwlJy6rHj1t8AKrU
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1614622959161
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1614622959161
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1614622959161
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - Custom::ApiGatewayAccountRole - CustomApiGatewayAccountCloudWatchRole
CloudFormation - CREATE_COMPLETE - Custom::ApiGatewayAccountRole - CustomApiGatewayAccountCloudWatchRole
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - hello-sl-python-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - hello-sl-python-dev
Serverless: Stack update finished...
Service Information
service: hello-sl-python
stage: dev
region: us-east-1
stack: hello-sl-python-dev
resources: 18
api keys:
None
endpoints:
POST - https://wi1enxyvse.execute-api.us-east-1.amazonaws.com/dev/hello
functions:
hello: hello-sl-python-dev-hello
layers:
None
Stack Outputs
EnterpriseLogAccessIamRole: arn:aws:iam::{{ my_account_ID }}:role/hello-sl-python-dev-EnterpriseLogAccessIamRole-1TGHCKLT2ISA2
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:{{ my_account_ID }}:function:hello-sl-python-dev-hello:1
ServiceEndpoint: https://wi1enxyvse.execute-api.us-east-1.amazonaws.com/dev
ServerlessDeploymentBucketName: hello-sl-python-dev-serverlessdeploymentbucket-k82rer3pefda
Serverless: Publishing service to the Serverless Dashboard...
Serverless: Successfully published your service to the Serverless Dashboard: https://app.serverless.com/atlex00/apps/hello-serverless/hello-sl-python/dev/us-east-1
hello-sl-python-dev-hello
<- API gateway pass to here, Laufzeit=Python 3.8hello-sl-python-dev-custom-resource-apigw-cw-role
:Laufzeit=Nodejs 12.x??Check:
$ curl -X POST https://wi1enxyvse.execute-api.us-east-1.amazonaws.com/dev/hello -vvv
* Trying 13.226.220.22:443...
* TCP_NODELAY set
* Connected to wi1enxyvse.execute-api.us-east-1.amazonaws.com (13.226.220.22) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=*.execute-api.us-east-1.amazonaws.com
* start date: May 7 00:00:00 2020 GMT
* expire date: Jun 7 12:00:00 2021 GMT
* subjectAltName: host "wi1enxyvse.execute-api.us-east-1.amazonaws.com" matched cert's "*.execute-api.us-east-1.amazonaws.com"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55cd1cf23800)
> POST /dev/hello HTTP/2
> Host: wi1enxyvse.execute-api.us-east-1.amazonaws.com
> user-agent: curl/7.68.0
> accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< content-type: application/json
< content-length: 2479
< date: Mon, 01 Mar 2021 18:26:42 GMT
< x-amzn-requestid: a1408afb-fbc6-4120-aa6e-0c01c8406b05
< x-amz-apigw-id: bhS7YFdmIAMFhcg=
< x-amzn-trace-id: Root=1-603d31e2-5187350962e6ac3c1376724a;Sampled=0
< x-cache: Miss from cloudfront
< via: 1.1 7f8004828cd106219da01f6385b03338.cloudfront.net (CloudFront)
< x-amz-cf-pop: LAX50-C1
< x-amz-cf-id: zaQiF2KGsewASi0a6_MsNVkYmZVIidZiEUjH4qHK_jWv__nWNTgivA==
<
{"message": "Go Serverless v1.0! Your function executed successfully!", "input": {"resource": "/hello", "path": "/hello", "httpMethod": "POST", "headers": {"Accept": "*/*", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "DE", "Host": "wi1enxyvse.execute-api.us-east-1.amazonaws.com", "User-Agent": "curl/7.68.0", "Via": "2.0 7f8004828cd106219da01f6385b03338.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "zaQiF2KGsewASi0a6_MsNVkYmZVIidZiEUjH4qHK_jWv__nWNTgivA==", "X-Amzn-Trace-Id": "Root=1-603d31e2-5187350962e6ac3c1376724a", "X-Forwarded-For": "xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https"}, "multiValueHeaders": {"Accept": ["*/*"], "CloudFront-Forwarded-Proto": ["https"], "CloudFront-Is-Desktop-Viewer": ["true"], "CloudFront-Is-Mobile-Viewer": ["false"], "CloudFront-Is-SmartTV-Viewer": ["false"], "CloudFront-Is-Tablet-Viewer": ["false"], "CloudFront-Viewer-Country": ["DE"], "Host": ["wi1enxyvse.execute-api.us-east-1.amazonaws.com"], "User-Agent": ["curl/7.68.0"], "Via": ["2.0 7f8004828cd106219da01f6385b03338.cloudfront.net (CloudFront)"], "X-Amz-Cf-Id": ["zaQiF2KGsewASi0a6_MsNVkYmZVIidZiEUjH4qHK_jWv__nWNTgivA=="], "X-Amzn-Trace-Id": ["Root=1-603d31e2-5187350962e6ac3c1376724a"], "X-Forwarded-For": ["xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx"], "X-Forwarded-Port": ["443"], "X-Forwarded-Proto": ["https"]}, "queryStringParameters": null, "multiValueQueryStringParameters": null, "pathParameters": null, "stageVariables": null, "requestContext": {"resourceId": "rckpj2", "resourcePath": "/hello", "httpMethod": "POST", "extendedRequestId": "bhS7YFdmIAMFhcg=", "requestTime": "01/Mar/2021:18:26:42 +0000", "path": "/dev/hello", "accountId": "{{ my_account_ID }}", "protocol": "HTTP/1.1", "stage": "dev", "domainPrefix": "wi1enxyvse", "requestTimeEpoch": 1614623202306, "requestId": "a1408afb-fbc6-4120-aa6e-0c01c8406b05", "identity"* Connection #0 to host wi1enxyvse.execute-api.us-east-1.amazonaws.com left intact
: {"cognitoIdentityPoolId": null, "accountId": null, "cognitoIdentityId": null, "caller": null, "sourceIp": "xxx.xxx.xxx.xxx", "principalOrgId": null, "accessKey": null, "cognitoAuthenticationType": null, "cognitoAuthenticationProvider": null, "userArn": null, "userAgent": "curl/7.68.0", "user": null}, "domainName": "wi1enxyvse.execute-api.us-east-1.amazonaws.com", "apiId": "wi1enxyvse"}, "body": null, "isBase64Encoded": false}}
Another way to check:
$ serverless invoke -f hello -l
Serverless: Deprecation warning: Starting with next major version, API Gateway naming will be changed from "{stage}-{service}" to "{service}-{stage}".
Set "provider.apiGateway.shouldStartNameWithService" to "true" to adapt to the new behavior now.
More Info: https://www.serverless.com/framework/docs/deprecations/#AWS_API_GATEWAY_NAME_STARTING_WITH_SERVICE
{
"statusCode": 200,
"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}
--------------------------------------------------------------------
START RequestId: 57d5a998-08a2-4e1a-a967-bb3191a38873 Version: $LATEST
SERVERLESS_ENTERPRISE {"c": true, "b": "{{ long_base64_like_strings }}", "origin": "sls-agent"}
END RequestId: 57d5a998-08a2-4e1a-a967-bb3191a38873
REPORT RequestId: 57d5a998-08a2-4e1a-a967-bb3191a38873 Duration: 4.43 ms Billed Duration: 5 msMemory Size: 1024 MB Max Memory Used: 64 MB
After playing, delete the environment:
$ serverless remove
Serverless: Deprecation warning: Starting with next major version, API Gateway naming will be changed from "{stage}-{service}" to "{service}-{stage}".
Set "provider.apiGateway.shouldStartNameWithService" to "true" to adapt to the new behavior now.
More Info: https://www.serverless.com/framework/docs/deprecations/#AWS_API_GATEWAY_NAME_STARTING_WITH_SERVICE
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack delete progress...
.........................
Serverless: Stack delete finished...
Serverless: Stack delete finished...
Serverless: Publishing service to the Serverless Dashboard...
Serverless: Successfully published your service to the Serverless Dashboard: https://app.serverless.com/atlex00/apps/hello-serverless/hello-sl-python/dev/us-east-1