Conditionally deploying parts of your CloudFormation stack with the Serverless Framework

What do you do when you want to customize which resources are deployed via CloudFormation?

While working on putting the finishing touches on v1 of Hook Relay, we decided to try using AWS Timestream, AWS' recently-released time series database. This led to a problem with deploying our stack, since we are using the Serverless Framework to deploy the Lambda functions we are using to multiple AWS regions.

The problem was that Timestream isn't yet available in all the regions we are using, so the CloudFormation stack that is being generated by the framework isn't valid in those regions that don't have Timestream. There isn't a built-in way to exclude a portion of the resources block (the portion that creates the Timestream database and table) when deploying to specific regions, so we had to get a little creative. Here's our solution:

serverless.yml

service: hook-relay

provider:
  name: aws

custom:
  resources:
    us-east-1: ${file(./resources/timestream.yml)}

resources:
  - ${file(./resources/main.yml)}
  - ${self:custom.resources.${self:provider.region}, ''}

resources/timestream.yml

Resources:
  tsdb:
    Type: AWS::Timestream::Database
    Properties:
      DatabaseName: "hook-relay-${self:custom.stage}"

  tsdeliveries:
    Type: AWS::Timestream::Table
    Properties:
      DatabaseName: !Ref tsdb
      TableName: deliveries

As you can see, we use a combination of custom variables, file includes, default values, and the ability to define multiple Resources blocks to get what we want. First we define a custom variable resources.us-east-1 that yanks in the content of the timestream.yml file, which has the CloudFormation definition of the resources that should only be created in that one region. Then we include the contents of that variable in the resources block by interpolating the current region as part of the variable name, with an empty string as the default fallback when that custom variable doesn't exist (e.g., when deploying to eu-central-1 via a command line option to sls deploy). Finally, we include the contents of resources/main.yml in the resources block. This file has another CloudFormation configuration that defines the resources that should be present in each region, such as DynamoDB tables, SQS queues, etc.

With that, whenever you run sls deploy, regardless of the region you deploy to, you'll get the AWS resources you want, without the ones you don't. Thanks to Cameron Childress for providing essential tips that led to this solution.

What to do next:
  1. Try Honeybadger for FREE
    Honeybadger helps you find and fix errors before your users can even report them. Get set up in minutes and check monitoring off your to-do list.
    Start free trial
    Easy 5-minute setup — No credit card required
  2. Get the Honeybadger newsletter
    Each month we share news, best practices, and stories from the DevOps & monitoring community—exclusively for developers like you.
    author photo

    Benjamin Curtis

    Ben has been developing web apps and building startups since '99, and fell in love with Ruby and Rails in 2005. Before co-founding Honeybadger, he launched a couple of his own startups: Catch the Best, to help companies manage the hiring process, and RailsKits, to help Rails developers get a jump start on their projects. Ben's role at Honeybadger ranges from bare-metal to front-end... he keeps the server lights blinking happily, builds a lot of the back-end Rails code, and dips his toes into the front-end code from time to time. When he's not working, Ben likes to hang out with his wife and kids, ride his road bike, and of course hack on open source projects. :)

    More articles by Benjamin Curtis
    Stop wasting time manually checking logs for errors!

    Try the only application health monitoring tool that allows you to track application errors, uptime, and cron jobs in one simple platform.

    • Know when critical errors occur, and which customers are affected.
    • Respond instantly when your systems go down.
    • Improve the health of your systems over time.
    • Fix problems before your customers can report them!

    As developers ourselves, we hated wasting time tracking down errors—so we built the system we always wanted.

    Honeybadger tracks everything you need and nothing you don't, creating one simple solution to keep your application running and error free so you can do what you do best—release new code. Try it free and see for yourself.

    Start free trial
    Simple 5-minute setup — No credit card required

    Learn more

    "We've looked at a lot of error management systems. Honeybadger is head and shoulders above the rest and somehow gets better with every new release."
    — Michael Smith, Cofounder & CTO of YvesBlue

    Honeybadger is trusted by top companies like: