Serverless Stack Toolkit (SST) is an extension of AWS CDK that:
- Allows you to use CDK with Serverless Framework
- And speeds up your deployments by deploying all your stacks concurrently!
Create and deploy your first SST app.
$ npx create-serverless-stack resources my-sst-app
$ cd my-sst-app
$ npx sst deploy
- Background
- Usage
- Example Project
- Migrating From CDK
- Known Issues
- Future Roadmap
- Contributing
- Running Locally
- References
- Community
Serverless Framework is great for deploying your Lambda functions. But deploying any other AWS resources requires you to write CloudFormation templates in YAML. CloudFormation templates are incredibly verbose and even creating simple resources can take hundreds of lines of YAML. AWS CDK solves this by allowing you to generate CloudFormation templates using modern programming languages. Making it truly, infrastructure as code.
However, to use AWS CDK (to define your non-Lambda resources) alongside your Serverless Framework services, requires you to follow certain conventions.
-
Deploying all the stacks to the same region and AWS account
Serverless Framework apps are deployed multiple times to each environment. Where each deployment uses the same region and AWS account. This is done using the
--region
andAWS_PROFILE=profile
options as a part of the deploy command. CDK apps on the other hand, contains CloudFormation stacks that are deployed to multiple regions and AWS accounts simultaneously. -
Prefixing stage and resource names
Since the same app is deployed to multiple environments, the AWS resource names might thrash if you are using the same AWS account across environments. To avoid this, Serverless Framework adopts the practice of prefixing the stack (and other resource) names with the stage name. On the other hand, to deploy a CDK app to the multiple stages, you'd need to manually ensure that the stack names and resource names don't thrash.
SST provides the above out-of-the-box. So you can deploy your Lambda functions using:
$ AWS_PROFILE=production serverless deploy --stage prod --region us-east-1
And use CDK for the rest of your AWS infrastructure:
$ AWS_PROFILE=production npx sst deploy --stage prod --region us-east-1
Making it really easy for you to start using CDK to create your AWS infrastructure. While still continuing to use Serverless Framework for your Lambda functions. You can read more about this here.
Finally, AWS CDK deployments are currently very slow. CDK deploys your CloudFormation stacks in sequence. It'll submit a CloudFormation template for deployment and wait till it completes before starting the next one. This means that CDK deployments for large apps can easily take at least half an hour. SST fixes this by deploying your CloudFormation stacks concurrently. It uses a forked version of AWS CDK internally to do this.
As a bonus, SST also supports deploying your CloudFormation stacks asynchronously. So you don't have to waste CI build minutes waiting for CloudFormation to complete. Seed natively supports concurrent asynchronous deployments for your SST apps. Making it 5x faster than other CI services. And SST deployments on Seed are free!
SST also comes with a few other niceties:
- Supports ES6 (and TypeScript) out-of-the-box
- Automatically lints your CDK code using ESLint
- Runs your CDK unit tests using Jest
Create a new project using.
$ npx create-serverless-stack resources my-sst-app
Or alternatively, with a newer version of npm or Yarn.
# With npm 6+
$ npm init serverless-stack resources my-sst-app
# Or with Yarn 0.25+
$ yarn create serverless-stack resources my-sst-app
This by default creates a JavaScript/ES6 project. If you instead want to use TypeScript.
$ npm init serverless-stack resources my-sst-app --language typescript
By default your project is using npm as the package manager, if you'd like to use Yarn.
$ npm init serverless-stack resources my-sst-app --use-yarn
You can read more about the create-serverless-stack CLI here.
Your app starts with a simple project structure.
my-sst-app
├── README.md
├── node_modules
├── .gitignore
├── package.json
├── sst.json
├── test
│ └── MyStack.test.js
└── lib
├── MyStack.js
└── index.js
It includes a config file in sst.json
.
{
"name": "my-sst-app",
"type": "@serverless-stack/resources",
"stage": "dev",
"region": "us-east-1"
}
The stage and the region are defaults for your app and can be overridden using the --stage
and --region
options. The name is used while prefixing your stack and resource names. And the type just tells the CLI to know which type of SST app this is.
The lib/index.js
file is the entry point for your app. It has a default export function to add your stacks.
import MyStack from "./MyStack";
export default function main(app) {
new MyStack(app, "my-stack");
// Add more stacks
}
Here you'll be able to access the stage, region, and name of your app using.
app.stage; // "dev"
app.region; // "us-east-1"
app.name; // "my-sst-app"
In the sample lib/MyStack.js
you can add the resources to your stack.
import * as sst from "@serverless-stack/resources";
export default class MyStack extends sst.Stack {
constructor(scope, id, props) {
super(scope, id, props);
// Define your stack
}
}
Note that the stacks in SST use sst.Stack
as imported from @serverless-stack/resources
. As opposed to cdk.Stack
. This is what allows SST to make sure that your stack names are prefixed with the stage names and are deployed to the region and AWS account that's specified through the CLI.
You can access the stage, region, and name of your app using.
this.node.root.stage; // "dev"
this.node.root.region; // "us-east-1"
this.node.root.name; // "my-sst-app"
And if you need to prefix certain resource names so that they don't thrash when deployed to multiple stages, you can do the following in your stacks.
this.node.root.logicalPrefixedName("MyResource"); // "dev-my-sst-app-MyResource"
You can read more about @serverless-stack/resources here.
Once you are ready to build your app and convert your CDK code to CloudFormation, run the following from your project root.
# With npm
$ npx sst build
# Or with Yarn
$ yarn sst build
This will compile your ES6 (or TS) code to the build/
directory in your app. And the synthesized CloudFormation templates are outputted to build/cdk.out/
. Note that, you shouldn't commit the build/
directory to source control and it's ignored by default in your project's .gitignore
.
Once your app has been built and tested successfully. You are ready to deploy it to AWS.
# With npm
$ npx sst deploy
# Or with Yarn
$ yarn sst deploy
This uses your default AWS Profile. And the region and stage specified in your sst.json
. You can deploy using a specific AWS profile, stage, and region by running.
$ AWS_PROFILE=my-profile npx sst deploy --stage prod --region eu-west-1
Finally, you can remove all your stacks and their resources from AWS using.
# With npm
$ npx sst remove
# Or with Yarn
$ yarn sst remove
Note that, this permanently removes your resources from AWS.
The above commands (build
, deploy
, and remove
) are also available in your package.json
. So you can run them using.
# With npm
$ npm run <command>
# Or with Yarn
$ yarn run <command>
Just note that for npm run
, you'll need to use an extra --
for the options. For example:
$ npm run build -- --stage alpha
You can run your tests using.
# With npm
$ npm test
# Or with Yarn
$ yarn test
Your code is automatically linted when building or deploying. If you'd like to customize the lint rules, add a .eslintrc.json
in your project root. If you'd like to turn off linting, add *
to an .eslintignore
file in your project root.
We use SST as a part of the Serverless Stack guide. We build a simple notes app in the guide and the backend for it is created using Serverless Framework and CDK with SST. You can check out the repo here — serverless-stack-demo-api.
It's fairly simple to move a CDK app to SST. There are a couple of small differences between the two:
-
There is no
cdk.json
If you have a
context
block in yourcdk.json
, you can move it to acdk.context.json
. You can read more about this here. You'll also need to add asst.json
config file, as talked about above. Here is a sample config for reference.{ "name": "my-sst-app", "type": "@serverless-stack/resources", "stage": "dev", "region": "us-east-1" }
-
There is no
bin/*.js
Instead there is a
lib/index.js
that has a default export function where you can add your stacks. SST creates the App object for you. This is what allows SST to ensure that the stage, region, and AWS accounts are set uniformly across all the stacks. Here is a samplelib/index.js
for reference.import MyStack from "./MyStack"; export default function main(app) { new MyStack(app, "my-stack"); // Add more stacks }
-
Stacks extend
sst.Stack
Your stack classes extend
sst.Stack
instead ofcdk.Stack
. Here is what the JavaScript version looks like.import * as sst from "@serverless-stack/resources"; export default class MyStack extends sst.Stack { constructor(scope, id, props) {} }
And in TypeScript.
import * as sst from "@serverless-stack/resources"; export class MyStack extends sst.Stack { constructor(scope: sst.App, id: string, props?: sst.StackProps) {} }
-
Include the right packages
You don't need the
aws-cdk
package in yourpackage.json
. Instead you'll need@serverless-stack/cli
and@serverless-stack/resources
.
There is a known issue in AWS CDK when using mismatched versions of their NPM packages. This means that all your AWS CDK packages in your package.json
should use the same exact version. And since SST uses a forked version of AWS CDK internally, this means that your app needs to use the same versions as well.
To help with this, SST will show a message to let you know if you might potentially run into this issue. And help you fix it.
Mismatched versions of AWS CDK packages. Serverless Stack currently supports 1.55.0. Fix using:
npm install @aws-cdk/aws-cognito@1.55.0 --save-exact
We also created a convenience method to help install the CDK npm packages with the right version — sst add-cdk
.
So instead of:
$ npm install @aws-cdk/aws-s3 @aws-cdk/aws-iam
You can do:
$ npx sst add-cdk @aws-cdk/aws-s3 @aws-cdk/aws-iam
And it'll install those packages using the right CDK versions.
You can learn more about these issues here and here.
- Add support for other AWS CDK languages
- Open a new issue if you've found a bug or have some suggestions.
- Or submit a pull request!
To run this project locally, clone the repo and initialize the project.
$ git clone https://github.com/serverless-stack/serverless-stack.git
$ cd serverless-stack
$ yarn
Run all the tests.
$ yarn test
Follow us on Twitter, join our chatroom, or post on our forums.
This project extends AWS CDK and is based on the ideas from Create React App.
Brought to you by Anomaly Innovations; makers of Seed and the Serverless Stack Guide.