Accelerate your serverless development with sam-patterns-cli
Published: 2021-04-06 21:17:39

_This post targets users of the AWS Serverless Application Model (SAM)_

AWS recently released the [Serverless Patterns Collection](https://serverlessland.com/patterns) which serves as a central directory of common best practice serverless patterns that, when they are combined, can make up complex applications.

At Mathem we have a home built templating engine that contains patterns that are common to our SAM stacks which developers can inject directly into their templates. Many of these are specific to our use cases and not easy to open source.

Contributing to our solution is fairly easy, but is still enough of a learning curve and a context switching exercise for the collection to remain more basic than we’d desire.

Our initial thought when we saw the Serverless Patterns Collection announcement was to build a command line interface around it to make the patterns easily accessible and usable directly from the code editor. From experience we've learned that for such collection to be alive and grow there has to be minimal effort involved in contributing to it. The goal is that a pattern gets written once, then shared and reused.

## Introducing sam-patterns-cli

Installation:
`npm install -g sam-patterns-cli`

This is still a very young project under development - version 0.0.9 at the time of writing, but is nevertheless ready to use.

It’s by default linked to the Serverless Patterns Collection’s [GitHub repository](https://github.com/aws-samples/serverless-patterns), but more sources, public or private, can be added.

The tool comes with 4 commands;
* **source** - Lets the user add their own repositories. This could be a private and company specific repository or some other collection, like Jeremy Daly’s [Serverless Reference Architectures](https://www.jeremydaly.com/serverless-reference-architectures/). See the [readme](https://github.com/mhlabs/sam-patterns-cli#sam-patterns-source) for instructions on how to link it
* **explore** - Lets the user navigate available patterns and visualise then using the power of [cfn-diagram](https://github.com/mhlabs/cfn-diagram)
* **import** - Lets the user import a pattern straight into their CloudFormation/SAM template without manually copy/pasting
* **share** - When working on a template, a developer might identify some resources making up a serverless pattern. This lets them extract that pattern and share it with other users of the tool by pushing it to a patterns collection on GitHub

In the following example we'll build an application that receives order updates from EventBridge, processes the order in a Lambda function and stores it in an S3 bucket. There will be no focus on the function code itself - just the SAM template.

We launch `sam-patterns import` and get presented with a list of available patterns. Searching for ‘eventbridge lambda’ gives us a few options. These patterns are named according to the flow order of them. In our case the ideal pattern would be ‘eventbridge-lambda-s3’, but the closest one is ‘eventbridge-lambda’, so we’ll choose that.

{% youtube ziKIfdVS1J4 %}

At the time of writing there was no pattern where a Lambda function writes to an S3 bucket, so we’ll go ahead and create one. The template now looks like this:
```
AWSTemplateFormatVersion: 2010-09-09
Transform:
 - AWS::Serverless-2016-10-31
Resources:
 OrderConsumer:
   Type: AWS::Serverless::Function
   Properties:
     CodeUri: src/
     Handler: OrderConsumer.handler
     Runtime: nodejs14.x
     Timeout: 3
     Policies:
       - S3WritePolicy:
         BucketName: !Ref OrderBucket
     Environment:
       Variables:
         OrderBucket: !Ref OrderBucket
     Events:
       Trigger:
         Type: EventBridgeRule
         Properties:
           EventBusName: custom-bus
           Pattern:
             source:
               - order-service
             detail-type:
               - order-updated
 OrderBucket:
   Type: AWS::S3::Bucket
```
We have now made a modification to an existing pattern that makes up a new pattern; EventBridge->Lambda->S3.

To avoid having to write the same code again or to help someone else in your team or in the world to quickly create the same pattern you can now share it back to GitHub. If the pattern is of a generic nature we encourage you to submit a pull request to [aws-samples/serverless-patterns](https://github.com/aws-samples/serverless-patterns), but to quickly share it with your team you can submit it to a repository of your own.

To do this, we’ve created a repository, github.com/mhlabs/sam-patterns-collection that will serve as our patterns repository. Next we’ll add it as a source for sam-patterns-cli. For this we use `sam-patterns source`.

{% youtube LrBgq08tieU %}

We’ve now linked our repository and we’re ready to use `sam-patterns share` to share the pattern with the world.

It’s likely that the developer reusing this pattern will work on a stack that handles something else than orders, so in this step we’ll make the shared template dynamically editable by the end user.

{% youtube ridloYYuyoo %}

That’s it! The new pattern is ready to be used by ourselves or by someone else needing the same functionality.

Let’s say that someone is building a payment processor service that receives payments from EventBridge, processes them and stores the records in S3. They’ll be up and running in seconds:

{% youtube UAYLh4z5iog %}

The user gets prompted to fill in the dynamic values; item name, Lambda runtime, eventbus name, pattern source and detail-type and that’s all they need to do. Now, this was a simple example for the sake of brevity. More complex patterns can easily be created and shared.

## Summary
This example took us through how to import a serverless pattern, modify it into a new pattern, share it and, finally, reuse it.

To understand how the dynamic values work, please head over to the [pattern we created](https://github.com/mhlabs/sam-patterns-collection/blob/main/eventbridge-lambda-s3/template.yaml) in this example and study the Metadata section of the template.

At this point in time only SAM template code can be imported and shared. The aim is to support backing files, such as Lambda function code and OpenAPI definitions in the future.

This project is open source and can be found [here](https://github.com/mhlabs/sam-patterns-cli). Contributions, bug reports and feature requests make us happy :-)