Slide 1

Slide 1 text

AWS SAM Serverless On Stage #9 - Milan, 20/02/2018

Slide 2

Slide 2 text

Serverless is amazing, but managing a Serveless project lifecycle is not easy

Slide 3

Slide 3 text

HELLO! I am Francesco Lerro I am a Solution Architect who loves the Cloud Find me on Twitter @flerro

Slide 4

Slide 4 text

Serverless Application Model ∎ CloudFormation extension for defining serverless application ∎ Infrastructure as code, local testing, automated deployment

Slide 5

Slide 5 text

.YAML A SAM template featuring Lambda, DynamoDB and API Gateway

Slide 6

Slide 6 text

PROVISIONING aws cloudformation package --template-file template.yaml --output-template-file my-app.yaml --s3-bucket my-bucket aws cloudformation deploy --template-file my-app.yaml --capabilities CAPABILITY_IAM --stack-name my-app

Slide 7

Slide 7 text

CloudFormation {"AWSTemplateFormatVersion":"2010-09-09","Description":"Creates an API gateway that's backed by a Lambda function","Parameters":{"APIName":{"Description":"Name of the API to create","Type":"String","AllowedPattern":"[A-Za-z0-9]*","MinLength":"4","MaxLength":"2 048","ConstraintDescription":"must contain only alphanumeric characters (at least four)"},"APIDescription":{"Description":"Description of the API to create","Type":"String","Default":"No description provided. Provide 'APIDescription' param to override this."},"APIPath":{"Description":"URL path for the API","Type":"String","Default":"api","AllowedPattern":"[A-Za-z0-9]*","MinLength":"1"," MaxLength":"64","ConstraintDescription":"must contain only alphanumeric characters (1-64 chars)"},"APIStageName":{"Description":"Stage name to deploy the API to","Type":"String","Default":"dev","AllowedPattern":"[A-Za-z0-9]*","MinLength":"1","M axLength":"64","ConstraintDescription":"must contain only alphanumeric characters (1-64 chars)"},"LambdaCodeBucket":{"Description":"Name of the S3 bucket that's storing the Lamba function's zip file","Type":"String"},"LambdaCodePath":{"Description":"Path to the zip file of code for the Lambda function","Type":"String"},"APIGatewayCustomResourceARN":{"Description":"The ARN pointing to the Lambda function that creates custom API gateway resources (install from https://apigatewaycloudformation.bynordenfelt.com/). Example: arn:aws:lambda:us-east-1:123456789012:function:APIGatewayCustomResource-LambdaFunction -ABCDEFG123","Type":"String"},"DynamoReadCapacityUnits":{"Description":"Provisioned read throughput","Type":"Number","Default":"1","MinValue":"1","MaxValue":"10000","Constrain tDescription":"must be between 1 and 10000"},"DynamoWriteCapacityUnits":{"Description":"Provisioned write throughput","Type":"Number","Default":"1","MinValue":"1","MaxValue":"10000","Constrain tDescription":"must be between 1 and 10000"}},"Resources":{"BackingLambdaFunction":{"Type":"AWS::Lambda::Function","Propert ies":{"Code":{"S3Bucket":{"Ref":"LambdaCodeBucket"},"S3Key":{"Ref":"LambdaCodePath"}}, "FunctionName":{"Fn::Join":["-",[{"Ref":"AWS::StackName"},{"Ref":"APIName"}]]},"Handle r":"index.handler","MemorySize":"128","Role":{"Fn::GetAtt":["BackingLambdaExecutionRol e","Arn"]},"Runtime":"nodejs4.3","Timeout":"3"}},"BackingLambdaInvokePermission":{"Typ e":"AWS::Lambda::Permission","Properties":{"FunctionName":{"Fn::GetAtt":["BackingLambd aFunction","Arn"]},"Action":"lambda: InvokeFunction","Principal":"apigateway.amazonaws.com"}},"BackingLambdaExecutionRole": {"Type":"AWS::IAM::Role","Properties":{"AssumeRolePolicyDocument":{"Version":"2012-10- 17","Statement":[{"Effect":"Allow","Principal":{"Service":["lambda.amazonaws.com"]},"A ction":["sts:AssumeRole"]}]},"Policies":[{"PolicyName":{"Fn::Join":["-",[{"Ref":"AWS:: StackName"},"UseDBPolicy"]]},"PolicyDocument":{"Version":"2012-10-17","Statement":[{"E InvokeFunction","Principal":"apigateway.amazonaws.com"}},"BackingLambdaExecutionRole":{"Type ":"AWS::IAM::Role","Properties":{"AssumeRolePolicyDocument":{"Version":"2012-10-17","Stateme nt":[{"Effect":"Allow","Principal":{"Service":["lambda.amazonaws.com"]},"Action":["sts:Assum eRole"]}]},"Policies":[{"PolicyName":{"Fn::Join":["-",[{"Ref":"AWS::StackName"},"UseDBPolicy "]]},"PolicyDocument":{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["dyna modb:DeleteItem","dynamodb:GetItem","dynamodb:PutItem","dynamodb:Query","dynamodb:Scan","dyn amodb:UpdateItem"],"Resource":{"Fn::Join":["",["arn:aws:dynamodb:",{"Ref":"AWS::Region"},":" ,{"Ref":"AWS::AccountId"},":table/",{"Ref":"APIDynamoDBTable"}]]}},{"Effect":"Allow","Action ":["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],"Resource":"*"}]}}]}}," MainAPI":{"Type":"Custom::RestApi","Properties":{"name":{"Fn::Join":["-",[{"Ref":"AWS::Stack Name"},{"Ref":"APIName"}]]},"description":{"Ref":"APIDescription"},"ServiceToken":{"Ref":"AP IGatewayCustomResourceARN"}}},"MainAPIResource":{"Type":"Custom::ApiResource","Properties":{ "ServiceToken":{"Ref":"APIGatewayCustomResourceARN"},"restApiId":{"Ref":"MainAPI"},"parentId ":{"Fn::GetAtt":["MainAPI","parentResourceId"]},"pathPart":{"Ref":"APIPath"},"corsConfigurat ion":{"allowMethods":["GET","POST"],"allowHeaders":["x-my-header","some-other-header"],"allo wDefaultHeaders":true,"allowOrigin":"*","exposeHeaders":["some-header","x-another-header"]," maxAge":1800}}},"APIMethodGet":{"Type":"Custom::ApiMethod","Properties":{"ServiceToken":{"Re f":"APIGatewayCustomResourceARN"},"restApiId":{"Ref":"MainAPI"},"resourceId":{"Ref":"MainAPI Resource"},"method":{"httpMethod":"GET","parameters":["querystring.sortBy","header.x-test-he ader","path.entityType"]},"integration":{"type":"AWS","uri":{"Fn::Join":[":",["arn:aws:apiga teway",{"Ref":"AWS::Region"},"lambda:path/2015-03-31/functions/arn:aws:lambda",{"Ref":"AWS:: Region"},{"Ref":"AWS::AccountId"},"function",{"Fn::Join":["/",[{"Fn::Join":["-",[{"Ref":"AWS ::StackName"},{"Ref":"APIName"}]]},"invocations"]]}]]},"httpMethod":"POST","requestTemplates ":{"application/json":["input-pass-through-full",{"DynamoDBTableName":{"Ref":"APIDynamoDBTab le"}}]},"requestParameters":{"integration.request.querystring.sortBy":"'hardcodedValue'"}}," responses":{"default":{"statusCode":"200","headers":{"X-Custom-Header":"'hardcodedValue'"}}, ".*NotFound.*":{"statusCode":"404"}}}},"APIMethodPost":{"Type":"Custom::ApiMethod","Properti es":{"ServiceToken":{"Ref":"APIGatewayCustomResourceARN"},"restApiId":{"Ref":"MainAPI"},"res ourceId":{"Ref":"MainAPIResource"},"method":{"httpMethod":"POST","parameters":["querystring. sortBy","header.x-test-header","path.entityType"]},"integration":{"type":"AWS","uri":{"Fn::J oin":[":",["arn:aws:apigateway",{"Ref":"AWS::Region"},"lambda:path/2015-03-31/functions/arn: aws:lambda",{"Ref":"AWS::Region"},{"Ref":"AWS::AccountId"},"function",{"Fn::Join":["/",[{"Fn ::Join":["-",[{"Ref":"AWS::StackName"},{"Ref":"APIName"}]]},"invocations"]]}]]},"httpMethod" :"POST","requestTemplates":{"application/json":["input-pass-through-full",{"DynamoDBTableNam e":{"Ref":"APIDynamoDBTable"}}]},"requestParameters":{"integration.request.querystring.sortB y":"'hardcodedValue'"}},"responses":{"default":{"statusCode":"200","headers":{"X-Custom-Head er":"'hardcodedValue'"}},".*NotFound.*":{"statusCode":"404"}}}},"DeployApi":{"Type":"Custom: :ApiDeploy","DependsOn":["APIMethodGet","APIMethodPost"],"Properties":{"ServiceToken":{"Ref" :"APIGatewayCustomResourceARN"},"restApiId":{"Ref":"MainAPI"},"stageName":{"Ref":"APIStageNa

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

SAM LOCAL sam local generate-event api --method GET --path /products > event_payload.json sam local invoke MyFunction \ --log-file output.log \ -e event_payload.json sam local start-api \ --debug-port 5858

Slide 11

Slide 11 text

Cloud9 A full-featured IDE, featuring SAM support, Lambda debug and real-time collaboration

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Serverless framework Features: ∎ Provider-agnostic DSL for serverless application definition ∎ CLI commands for local debugging / testing and deployment ∎ Plugin ecosystem to manage additional aspects of app lifecycle

Slide 16

Slide 16 text

SAM or Serverless framework? ∎ Similar features for local development, debugging and deploy ∎ SAM is more integrated with AWS ecosystem, but less mature ∎ Serverless framework has strong pugin ecosystem, but it is developed by a third party

Slide 17

Slide 17 text

THANKS! Any questions? Content released under Public Domain Presentation template by SlidesCarnival