Serverless Stack, a Terraform alternative for developers

Serverless Stack, a Terraform alternative for developers

Bridging the gap between Development and IaC in AWS

Picture yourself being able to confidently deploy your application, whether it's full-stack or partially serverless, without having to rely on your DevOps or Platform team. Envision yourself seamlessly hosting your Infrastructure as Code (IaC) configurations in the same repository as your application code for maximum feasibility. Most importantly, consider the possibilities if you were able to eliminate the development feedback loop that necessitates the local mocking of services and redeployment for testing. There’s a solution to this.

Introducing Serverless Stack

Serverless Stack, also known as SST, is a powerful framework that enables you to effortlessly create serverless applications with backend stores on AWS. Since 2021, the SST framework has evolved into a comprehensive platform that empowers you to develop and deploy a cutting-edge full-stack application with robust backend features, including databases, GraphQL APIs, authentication, cron jobs, and various other AWS services such as ECS, S3, and CloudWatch. SST provides an array of features that efficiently address common developer challenges and concerns when building serverless applications, such as seamless integration with other backend tools and services in AWS.

What type of solutions can I build with it?

  • APIs

  • Web Apps

  • Mobile Apps (not literally, but tight coupling with serverless architecture)

  • GraphQL

  • Databases

  • Authentication

  • Asynchronous Tasks / Event-Driven Systems

  • Monitoring

  • Lambda Layers

  • All other AWS services

SST is an excellent framework for building various solutions. However, for microservices that require loosely coupled services like account, identity, and payment services, it may not be the best choice. These solutions require a complex software design and cloud architecture, which are better suited for Kubernetes or other containerization solutions.

Overall, SST empowers you to confidently build a full-stack application comprising a front-end application, back-end application, database, and multiple integration systems or services. Thanks to the underlying architecture of SST, you can seamlessly incorporate other AWS services and third-party tools and libraries that are closely intertwined with your application. These can cover various areas such as authentication, monitoring, cron jobs, asynchronous operations, and more.

How does it all work and come together?

SST framework is built on top of the notable AWS Cloud Development Kit. SST follows monorepo architecture because it combines your application code with the IaC. By default, SST uses TypeScript to define your architecture, however, you can still use JavaScript.

The project folder structure is as follows:

my-sst-app
├─ package.json
├─ sst.config.ts
├─ packages
│  ├─ core
│  │  └─ migrations
│  ├─ functions
│  ├─ graphql
│  └─ web
└─ stacks

The stacks/ folder contains all of your Infrastructure as Code. SST typically recommends grouping related resources into stacks. For example, you can have a Database.ts file that contains the IaC to provision an RDS instance or a DynamoDB resource. Api.ts file could contain configuration to provision a API Gateway. You could then bind your database to the API for your functions that power your API to have access to it. Your front-end application, Web.ts could host a static website powered by Vuejs on S3 and serve content through a CDN, such as CloudFront. In conclusion, it’s all about building up the stacks and binding them together using properties that are returned from the individual resources you provision.

packages/ contains all the components that power your backend systems, including systems like your GraphQL API, Lambda functions, front-end application, business logic, and any other programming you require. SST recommends maintaining a Domain Driven Design pattern within the packages/core folder to isolate your business logic from your API and Lambda functions. This ensures simple and maintainable code within your project. The folder contains all the implementation necessary for your application to function, which is then called by external-facing services, similar to an API. Within the packages/core/migrations folder, houses all of your SQL migrations. The packages/web folder houses your front-end application, whether it’s React, Vue, Next, Gatsby. packages/functions houses all of your code for your Lambda functions. They should be designed with simple functionality while being invoked by services code defined in the packages/core . Finally, packages/graphql houses outputs generated by the GraphQL. Ideally, you would not alter this folder as it’s shared between your frontend and backend, therefore should be committed into Git.

One great feature of SST is its use of Workspaces from npm. This provides support for managing multiple packages, or in this case, a monorepo, from within a single top-level, root package. Workspaces help manage dependencies for separate packages in your repository that have their own package.json file. This is especially useful if you want to keep several projects in a single monorepo that are related in some way.

SST includes its own set of npm scripts that handle various tasks for your application, such as starting it up, building it, deploying it, removing it, and testing it.

export default {
  config(_input) {
    return {
      name: "my-sst-app",
      region: "us-west-2",
    };
  },
  stacks(app) {
    app.stack(Database).stack(Api).stack(Web);
  },
} satisfies SSTConfig;

Finally, SST provides a configuration file that specifies your project configuration and the stacks that follow in your application. This configuration file is crucial in initializing your entire project, both on your local machine and when you deploy your application.

What features does it provide?

Live Lambda Development

SST offers a local development environment that enables you to debug and test your Lambda functions locally while being invoked remotely from AWS. This is a significant advantage of SST as it allows developers to test their changes locally without the need to mock the servers and redeploy them to test them using conventional methods. Behind the scenes, SST employs AWS IoT over Websocket to communicate and forward requests between your local machine and the remote Lambda function (sort of like a proxy). This feature enables SST to execute a function locally using the same event, context, and credentials as the remote Lambda function. Changes are automatically detected, built, and reloaded live in just a few milliseconds. You can take full advantage of breakpoints to debug your code live with an IDE of your choice.

SST Console

SST Console is a web-based dashboard used to manage your SST applications. You can view real-time logs, invoke functions, replay invocations, view your deployed stacks, run migrations, make queries, view uploaded files in S3, query your GraphQL APIs, and more. For multitasking, you can use separate tabs or explorers to manage different parts of your application, providing a seamless monitoring experience.

Editor Integration

SST is designed to seamlessly integrate with your preferred IDEs. It comes with a range of built-in features including autocomplete, inline documentation, the ability to set breakpoints in your Lambda functions, and type checking (if you're building your application in TypeScript). Currently, SST provides support for Visual Studio Code, WebStorm, and IntelliJ IDEA.

Migration from AWS CDK and Serverless Framework

SST offers assistance in migrating your resources and applications from both AWS CDK and Serverless Framework with a comprehensive guide. The transfer process from AWS CDK should be relatively simple as SST was constructed on the AWS CDK. However, when dealing with the Serverless Framework, it is recommended to adopt an incremental update approach, which results in a hybrid Serverless Framework and an SST application.

How do I set up a project?

It ultimately depends on the type of application you are looking to create. There are a few different approaches you can take:

  • Standalone application - this involves building your application from the ground up using the CDK API reference.

  • SST application - this approach involves using the SST API construct to build a variety of elements and/or resources such as frontend applications, backend applications, databases, APIs, and more.

To get started, follow these steps:

  1. Have an AWS account ready to deploy your application.

  2. Set up AWS CLI on your local machine and configure IAM user credentials for it. For now, you may provide full administrative access. You may change this later on to meet your project requirements based on the AWS resources you will be utilising for SST to deploy your application

  3. Run npx create-next-app@latest to create a new Next.js application.

  4. Then, initialise SST in your project root directory with npx create-sst@latest.

  5. Start your local development environment by running npx sst dev to start SST and npm run dev to start Next.js.

Once you've completed these steps, you can start building your application.

How do I deploy it to my AWS environment?

CLI

The most convenient deployment method is likely through the CLI. By running npx sst deploy --stage prod at the root level of your project, you can deploy your application to an environment with a prod identifier. SST utilizes CloudFormation stacks to carry out deployments, which is why you may notice your AWS account accruing CloudFormation stacks. To deploy your application to various environments, simply reference the -stage option in the CLI. This will allow you to design your application to be adaptable when it comes to switching between resources and environments.

CI/CD

To automate your deployments, push your code to a Git provider such as GitHub and then connect it to a CI/CD service to deploy your application. There are several CI/CD providers available, including GitHub Actions, Azure DevOps, Gitlab, Bitbucket Pipelines, Buildkite, and more. As with setting up an IAM user on your local machine, it is important to store the access credentials securely in your CI/CD tool. You can add additional steps in your pipeline that prompt the pipeline agent to log in securely to your AWS account, and SST will use the credentials to deploy your application.

How much customisation can I do with SST?

It depends on the application architecture and design patterns you employ. If your architecture is event-driven, then you can take full advantage of the SST framework. If your architecture is centered around building a mid-level API system using something like Express.js, you can still make use of the SST framework by installing Node package libraries in your project. This will help you leverage the capabilities of SST, while also designing a simple API system that uses REST design.

For example:

  • You can build an AWS API Gateway using SST

  • Build a Lambda function that utilises the Express.js REST API and binds the function to the API Gateway

  • You can extend from SST by using the AWS CDK constructs such as, S3, Cloudwatch Logs, and Secrets Manager to store artifacts, send/stream your application logs, access sensitive information from the vault and bind them to your Lambda function

Summary

SST is a fantastic choice for developers seeking to build robust and scalable serverless applications that operate on AWS. SST offers a broad spectrum of features, such as a local development environment, and effortless integration with other backend tools and services in AWS. This provides developers with the flexibility and simplicity they require to create and deploy modern applications. Furthermore, SST is expanding its internal tooling to encompass additional constructs from AWS CDK, thereby providing an increasingly comprehensive yet user-friendly framework for building a modern, full-stack application.

Resources