This article is the second of a series around SST. I will try to let you discover some amazing aspects of this particular solution in the serverless world. You can find the first article here.

So you start building using serverless principles, and you discover the Serverless framework. Great ! You will discover here another option, that I consider superior in multiple area, the Serverless Stack (SST). In this second article, I will focus on some available constructs after introducing the concept. It can help you to build faster!

Introducing some concepts

What is CDK?

The Serverless Stack (SST) is based on the AWS Cloud Development Kit (CDK). This solution has been introduced by AWS a few years ago, it allow to build infrastructure as code (IaC) by using a real programming language. If you already know Terraform, it is an equivalent product.

Terraform allow you to declare cloud resources via the HashiCorp Configuration Language (HCL):

resource "aws_instance" "iac_in_action" {
  ami               = var.ami_id
  instance_type     = var.instance_type
  availability_zone = var.availability_zone

  // dynamically retrieve SSH Key Name
  key_name = aws_key_pair.iac_in_action.key_name

  // dynamically set Security Group ID (firewall)
  vpc_security_group_ids = [aws_security_group.iac_in_action.id]

  tags = {
    Name = "Terraform-managed EC2 Instance for IaC in Action"
  }
}

On the opposite CDK allow you to declare cloud resources via TypeScriptPythonJava or .Net (maybe more now?)!

import * as ec2 from '@aws-cdk/aws-ec2';
import * as iam from '@aws-cdk/aws-iam';
import * as cdk from '@aws-cdk/core';

export class CdkStarterStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // ... rest

    // 👇 create the EC2 Instance
    const ec2Instance = new ec2.Instance(this, 'ec2-instance', {
      vpc,
      vpcSubnets: {
        subnetType: ec2.SubnetType.PUBLIC,
      },
      role: webserverRole,
      securityGroup: webserverSG,
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.T2,
        ec2.InstanceSize.MICRO,
      ),
      machineImage: new ec2.AmazonLinuxImage({
        generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
      }),
      keyName: 'ec2-key-pair',
    });
  }
}

(this is a TypeScript example from here).

A few more differences exists between the solutions:

This will be enough to introduce you the next important concept: constructs!

What are constructs?

From AWS Documentation:

Constructs are the basic building blocks of AWS CDK apps. A construct represents a "cloud component" and encapsulates everything AWS CloudFormation needs to create the component.

You can think about a set of basic cloud resources are managed behind a construct, and it help you to handle the complexity more easily with a few low number of lines.

For example here we can see how it's possible to use the construct ApplicationLoadBalancedFargateService in a few lines of codes:

const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'Service', {
  cluster,
  memoryLimitMiB: 1024,
  cpu: 512,
  taskImageOptions: {
    image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
  },
});