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

Serverless with CDK

Aletheia
September 19, 2019

Serverless with CDK

Serverless is the new normal for modern app development, but managing serverless projects require a number of tasks to be accomplished. One of the best pattern, Infrastructure as Code becomes unfeasible without a framework. AWS CDK offers a new approach to CloudFormation, with support to template creation programmatically.

Aletheia

September 19, 2019
Tweet

More Decks by Aletheia

Other Decks in Technology

Transcript

  1. www.neosperience.com | blog.neosperience.com | [email protected] Neosperience Empathy in Technology How

    to define cloud architectures using your preferred language with AWS CDK Sep, 19th 2019
  2. Luca Bianchi Who am I? Chief Technology Officer @ Neosperience

    github.com/aletheia @bianchiluca https://it.linkedin.com/in/lucabianchipavia https://speakerdeck.com/aletheia Chief Technology Officer @ WizKey Serverless Meetup Italy manager ServerlessDays co-organizer
  3. Serverless means no servers. No hardware to provision or manage

    No IT service team installing hardware But still it’s someone else server Server VM OS frameworks code your duty
  4. Serverless means no VMs. No under or over provisioning Never

    pay for idle No VM disaster recovery VM OS frameworks code your duty
  5. Serverless means no OS to config. OS is provisioned automatically

    Patches are installed by vendor Built-in best practices OS frameworks code your duty
  6. Serverless means no schedulers. Code is invoked by platform Language

    support is packed within runtime Analytics are provided out of the box frameworks code your duty
  7. Serverless means Servicefull. Patrick Debois - 2016 Server VM OS

    frameworks code your duty some one else duty
  8. Script your cloud infrastructure Infrastructure as Code (IaC) AWS CloudFormation

    is the scripting language for AWS Cloud Describe your cloud infrastructure in a JSON or YML template file and let CloudFormation build resources you need Templates can be versioned ensuring immutability Deployments can be parametrized Built-in helpers
  9. --- Resources: MyServiceStoreEE9BC9A0: Type: AWS::S3::Bucket UpdateReplacePolicy: Retain DeletionPolicy: Retain Metadata:

    aws:cdk:path: RestStack/MyServiceStore/Resource LambdaHandlerServiceRole8F7B4955: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::Join: - '' - - 'arn:' - Ref: AWS::Partition - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" Metadata: aws:cdk:path: RestStack/LambdaHandler/ServiceRole/Resource LambdaHandlerServiceRoleDefaultPolicy52DB1F25: Type: AWS::IAM::Policy Properties: PolicyDocument: Statement: - Action: - s3:GetObject* - s3:GetBucket* - s3:List* - s3:DeleteObject* - s3:PutObject* - s3:Abort* Effect: Allow Resource: - Fn::GetAtt: - MyServiceStoreEE9BC9A0 - Arn - Fn::Join: - '' - - Fn::GetAtt: - MyServiceStoreEE9BC9A0 - Arn - "/*" Version: '2012-10-17' PolicyName: LambdaHandlerServiceRoleDefaultPolicy52DB1F25 Roles: - Ref: LambdaHandlerServiceRole8F7B4955 Metadata: aws:cdk:path: RestStack/LambdaHandler/ServiceRole/DefaultPolicy/Resource LambdaHandlerApiPermissionTestRestStackmyserviceapiD3EA4862GET17E42E15: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: Fn::GetAtt: - LambdaHandler212865DC - Arn Principal: apigateway.amazonaws.com SourceArn: Fn::Join: - '' - - 'arn:' - Ref: AWS::Partition - ":execute-api:" - Ref: AWS::Region - ":" - Ref: AWS::AccountId - ":" - Ref: myserviceapi226E6B58 - "/test-invoke-stage/GET/" Metadata: aws:cdk:path: RestStack/LambdaHandler/ ApiPermission.Test.RestStackmyserviceapiD3EA4862.GET.. myserviceapi226E6B58: Type: AWS::ApiGateway::RestApi Properties: Description: This is my service. Name: MyService Metadata: aws:cdk:path: RestStack/myservice-api/Resource myserviceapiDeployment64624B21f95e073b8b06b61d3c084e7dd1be6a99: Type: AWS::ApiGateway::Deployment Properties: RestApiId: Ref: myserviceapi226E6B58 Description: Automatically created by the RestApi construct DependsOn: - myserviceapiGET805C988C Metadata: aws:cdk:path: RestStack/myservice-api/Deployment/Resource myserviceapiDeploymentStageprodB550FDE9: Type: AWS::ApiGateway::Stage Properties: RestApiId: Ref: myserviceapi226E6B58 DeploymentId: Ref: myserviceapiDeployment64624B21f95e073b8b06b61d3c084e7dd1be6a99 StageName: prod Metadata: aws:cdk:path: RestStack/myservice-api/DeploymentStage.prod/Resource myserviceapiCloudWatchRole2422BDFA: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: apigateway.amazonaws.com Version: '2012-10-17' ManagedPolicyArns: - Fn::Join: - '' - - 'arn:' - Ref: AWS::Partition - ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" Metadata: LambdaHandler212865DC: Type: AWS::Lambda::Function Properties: Code: S3Bucket: Ref: LambdaHandlerCodeS3Bucket29322DA5 S3Key: Fn::Join: - '' - - Fn::Select: - 0 - Fn::Split: - "||" - Ref: LambdaHandlerCodeS3VersionKey948E7B0F - Fn::Select: - 1 - Fn::Split: - "||" - Ref: LambdaHandlerCodeS3VersionKey948E7B0F Handler: index.main Role: Fn::GetAtt: - LambdaHandlerServiceRole8F7B4955 - Arn Runtime: nodejs8.10 Environment: Variables: BUCKET: Ref: MyServiceStoreEE9BC9A0 DependsOn: - LambdaHandlerServiceRoleDefaultPolicy52DB1F25 - LambdaHandlerServiceRole8F7B4955 Metadata: aws:cdk:path: RestStack/LambdaHandler/Resource aws:asset:path: asset. 10b682bad89f14de23059d787528e0fd16df9824892a35b89e9352a338df8d20 aws:asset:property: Code LambdaHandlerApiPermissionRestStackmyserviceapiD3EA4862GET15582A73: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: Fn::GetAtt: - LambdaHandler212865DC - Arn Principal: apigateway.amazonaws.com SourceArn: Fn::Join: - '' - - 'arn:' - Ref: AWS::Partition - ":execute-api:" - Ref: AWS::Region - ":" - Ref: AWS::AccountId - ":" - Ref: myserviceapi226E6B58 - "/" - Ref: myserviceapiDeploymentStageprodB550FDE9 - "/GET/" Metadata: aws:cdk:path: RestStack/LambdaHandler/ ApiPermission.RestStackmyserviceapiD3EA4862.GET.. aws:cdk:path: RestStack/myservice-api/CloudWatchRole/Resource myserviceapiAccountCADB8ED1: Type: AWS::ApiGateway::Account Properties: CloudWatchRoleArn: Fn::GetAtt: - myserviceapiCloudWatchRole2422BDFA - Arn DependsOn: - myserviceapi226E6B58 Metadata: aws:cdk:path: RestStack/myservice-api/Account myserviceapiGET805C988C: Type: AWS::ApiGateway::Method Properties: HttpMethod: GET ResourceId: Fn::GetAtt: - myserviceapi226E6B58 - RootResourceId RestApiId: Ref: myserviceapi226E6B58 AuthorizationType: NONE Integration: IntegrationHttpMethod: POST RequestTemplates: application/json: '{ "statusCode": "200" }' Type: AWS_PROXY Uri: Fn::Join: - '' - - 'arn:' - Ref: AWS::Partition - ":apigateway:" - Ref: AWS::Region - ":lambda:path/2015-03-31/functions/" - Fn::GetAtt: - LambdaHandler212865DC - Arn - "/invocations" Metadata: aws:cdk:path: RestStack/myservice-api/Default/GET/Resource Parameters: LambdaHandlerCodeS3Bucket29322DA5: Type: String Description: S3 bucket for asset "RestStack/LambdaHandler/Code" LambdaHandlerCodeS3VersionKey948E7B0F: Type: String Description: S3 key for asset version "RestStack/LambdaHandler/Code" LambdaHandlerCodeArtifactHash5827C2D8: Type: String Description: Artifact hash for asset "RestStack/LambdaHandler/Code" Outputs: myserviceapiEndpointBB6FABDA: Value: Fn::Join: - '' - - https:// - Ref: myserviceapi226E6B58 - ".execute-api." - Ref: AWS::Region - "." - Ref: AWS::URLSuffix - "/" - Ref: myserviceapiDeploymentStageprodB550FDE9 - "/" A simple Rest endpoint with API Gateway, Lambda, S3 Infrastructure as Code (IaC) Powerful, but really too verbose
  10. CloudFormation exclude dependencies 280+ plugins Provides support for a number

    of integrations and helpers to ease development and project management, from minification to dependency check, to support for web sockets or third party technologies. Support for dev dependencies exclusion, thus reducing package size and improving function load time, then minimizing cold start issue Resources are created as CloudFormation template embedded in serverless.yml serverless.yml
  11. CloudFormation Everything is a CloudFormation primitive within a template. This

    means every new CF functionality is natively supported by SAM cloud formation template and SAM CLI Custom Transform AWS SAM is a custom transform applied to CloudFormation Templates (a macro that processes our template and expands into a CF stack CLI handles packaging AWS SAM CLI handles code packaging and upload to S3, minimizing overhead from code to cloud
  12. All these solutions have in common some issues related to

    CloudFormation direct usage Writing CloudFormation code is uncomfortable • It’s error prone! • Debugging is hard and there is no strong validation • No support for conditional stack creation • No support for multiple creation of the same resource • Extremely verbose
  13. Defining a Serverless app with CDK (nodeJS) rest-stack.js rest-app.js Define

    a REST API with helpers Helpers to support fast resources definition Lambda code is packaged by asset Helpers to support fast resources definition Supports multiple nested stacks Stacks as constructs can be versioned and released as NPM libraries, then composed into an app
  14. Templates are composed using constructs Constructs First level constructs -

    generated directly from CloudFormation primitives - map directly from CloudFormation - Ensure support for any feature CloudFormation provides - start with Cfn<something> AWS Construct Library - provide constructs representing AWS Resources (such as Bucket, Topic or Table) with default configurations - provide helpers to simplify common operations - auto-configuration for required resources - enforce best practices - start with aws<something> Customer Constructs - can be heavily customised, extend cdk.Construct - used to wrap architecture components - used to standardize common patterns - can be released as NPM package
  15. but could be improved on some aspects AWS CDK is

    a game changer technology Simplifies serverless development ✓less boilerplate ✓compilers / interpreters validate stack ✓stack splitting encourages reusability ✓conditional resource creation ✓resource parametrization ✓complex deployment logics ✓construct libraries (https://github.com/eladb/awesome-cdk) #cdkwishlist ✓plugin support ✓lambda code dependency pruning ✓documentation ✓resource preset (what is already available in your account?)
  16. “in the past were bigger companies that outcompeted smaller companies

    now are faster companies 
 to outcompete slower companies” — Marc Benioff