Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWS ❤ SAM / Serverless On Stage #9

AWS ❤ SAM / Serverless On Stage #9

The presentation features AWS SAM and some recently introduced tools/features that streamline Serverless project development lifecycle (Cloud9, Traffic Shifting, SAM Local)

Avatar for Francesco Lerro

Francesco Lerro

February 20, 2018
Tweet

More Decks by Francesco Lerro

Other Decks in Technology

Transcript

  1. HELLO! I am Francesco Lerro I am a Solution Architect

    who loves the Cloud Find me on Twitter @flerro
  2. Serverless Application Model ∎ CloudFormation extension for defining serverless application

    ∎ Infrastructure as code, local testing, automated deployment
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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