home

What to use for a serverless backend

2022-9-14

Cloudformation, Serverless Framework, AWS CDK, SST, Terraform?

API resources visualized in AWS CloudFormation Designer

API resources visualized in AWS CloudFormation Designer

CloudFormation

Using CloudFormation is like using binary instead of a programming language.

All the other frameworks generate CloudFormation files (JSON/YML) for AWS to use to generate resources.

Here is an example CloudFormation generated from SST:

apiCloudformation.json

Serverless Framework

As well as generating Cloudformation files, the Serverless Framework comes with tools for development and deployment

With this framework you create serverless.yml files, these serve as stacks. Here you'll import function files, mapping templates, and even other resources generated by separate serverless.yml files, like Cognito and Dynamodb.

Here is an API in a serverless.yml converted to json for viewing:

serverlessYmlAs.json

Pros:

  • CLI ease of use - deploy functions and resources independently or deploy/remove the whole stack.
  • Easy deployment - with SEED you can update your backend with git.
  • Documentation is great, lots of good examples.

Cons:

  • Can be wordy.
  • Importing other resources, using fn gett att not very intuitive.
  • YML files error with improper spacing

CDK

AWS's own serverless framework - it's a multi-language cloud development kit. While for AWS, it can be used with other providers with Terraform (CDKTF). cdk watch!!!

Pros:

  • TypeScript support, no need to use YML files. This allows IDE intellisense / autocomplete.

    Dynamic variables in YML files can be confusing, when using a language like TypeScript, you can use the variable in-line.

    Have a lot of similar IAM roles? No need to write them all out (YML), iterate over them (JS).

Cons:

  • Documentation sucks
  • New - still doesn't have all functionality, improving fast though. (couldn't use SES couldn't be used in cognito before)
    • Some errors I found initially difficult to resolve:

      Property does not exist on type 'StackProps'

      Type "AWS_IAM" is not assignable to type 'ApiAuthorizationType | undefined'

      'table' does not exist in type 'StackProps'

      Property 'table' does not exist on type 'StackProps'

      Argument of type { table: any; } is not assignable to parameter of type 'StackProps'.

      Property 'table' does not exist on type 'DynamoDbStack'

SST

Why use SST over CDK?

Example SST file:

apiSST.json

Typescript file in JSON for in browser viewing

  • Example ApiStack

    import * as sst from "@serverless-stack/resources";
    import { CorsHttpMethod } from "@aws-cdk/aws-apigatewayv2"
    
    export default class ApiStack extends sst.Stack {
      api
      constructor(scope: sst.App, id: string, props: any) {
        super(scope, id, props);
        const { 
          usersTable, 
          receiversTable,
          privateUsers,
          sessionData
         }  = props;
        // const domain = (scope.stage === "prod") ? "api.talktree.me" : "dev-api.talktree.me"
    
        this.api = new sst.Api(this, "Api", {
          cors: true,
          defaultAuthorizationType: sst.ApiAuthorizationType.AWS_IAM,
          defaultFunctionProps: {
            environment: {
              UsersTable: usersTable.tableName,
              ReceiversTable: receiversTable.tableName,
              PrivateUser: privateUsers.tableName,
              SessionData: sessionData.tableName,
            },
          },
          routes: {
            "GET /getUsers": "src/getUsers.handler",
            "POST /createUnpaidSession": "src/createUnpaidSession.handler",
            "POST /getUser": "src/getUser.handler",
            "POST /saveNotionId": "src/saveNotionId.handler" 
          },
        });
        this.api.attachPermissions([usersTable, receiversTable, privateUsers, sessionData, "ses"]);
    
        // Show the endpoint in the output
        this.addOutputs({
          "ApiEndpoint": this.api.url,
          "Routes": JSON.stringify(this.api.routes),
        });
      }
    }

Pros:

  • Constructs like SST.api greatly simplifies CDK
  • CDK CLI support with npx sst cdk ; very useful resolving deployment issues.

Cons:

  • These names are complicated af - can I simplify them just the tiniest bit.. (dynamodb tables)
  • AWS only
  • Uses 3 environments which doesn't work seamlessly with Next.js.

Terraform

Terraform by HashiCorp is like a platform-agnostic version of SST. You aren't locked into AWS, but it uses its own language. Can still use CDK (CDKTF).