AWS Serverless Application Model YAML Templates: An Introduction
If you’ve never worked with YAML before, you’ll probably find the basic template format daunting. YAML — which somehow doesn’t stand for Yet Another Markdown Language, but instead YAML Ain’t Markdown Language — is a simplified way of storing data structures. YAML is popular with Rails users and sees some popularity with all higher order language programmers (JS, Python, etc…).
Clean, Simple Formatting
YAML is popular with languages that tend to see only three types of data:
- Scalars: numbers and strings, the ‘text’ of your data
- Heaps: e.g. objects, dictionaries, or any other term for a mapping of key-value pairs
- Lists: i.e. arrays or an ordered sequence of the other two data types
YAML primarily tries to produce configuration documents that are readable without any special interpretation and formatting. If you look at even a short snippet of YAML from the middle of a SAM configuration file the key-value pairs are pretty readable, and you can even guess how lists might be used:
DynamoDBTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: id AttributeType: S
Indentation is used for structure, colons separate key-value pairs, and dashes are used to create “bullet” lists.
This simple, clean formatting also brings us to the most common complaint about YAML, it is whitespace-dependent, and missing a single tab can mess up the interpretation of the whole document.
Always remember that YAML Lint is your friend. I still use yamllint.com every time I write YAML, turning on a display for invisible characters and purpose built linters for your IDE are all well and good, but that final check of YAML is still crucial.
YAML vs. XML
If you’re familiar with XML you may well have already interacted with systems that use either YAML or XML for configuration, or noticed that they are used by competing data storage systems. YAML is instantly readable, XML is not. On the other hand, the X in XML stands for “extensible” and while YAML really only has three ways to store data, the markup available in XML is limitless.
YAML vs. JSON
The official specifications for YAML are well written and have some general guidance on best practices, implementation differences, and the design goals of YAML.
AWS Serverless Application Model
AWS CloudFormation templates are a standardized specification for describing, documenting, and deploying components of a serverless application Let’s look at one of the shortest possible SAM files:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: MyFirstFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs4.3 CodeUri: s3://bucketName/codepackage.zip
With the Handler property set to index.handler, the code package at the CodeUri will be opened, CloudFormation will look for a file (“index”) and a function or module (“handler”). Both the AWSTemplateFormatVersion and Transform should be the same for all your Sam files, and the Type and Runtime properties are self-explanatory.
While the template above will create a Lambda, it’ll be fundamentally incomplete since it needs something to trigger a Lambda in order to run. The Events property defines these triggers.
In general you’d use SAM files when you want to define multiple interlinked pieces of your application. This example (leaving off the top three lines that will be the same in every SAM file) grabs events from a DynamoDB table:
TableAlerter: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs6.10 Events: Stream: Type: DynamoDB Properties: Stream: !GetAtt DynamoDBTable.StreamArn BatchSize: 100 StartingPosition: TRIM_HORIZON
Bringing it All Together
Most of the time SAM is the best choice because SAM can stand up an interlinked set of resources. So our SAM file will have more than one key under Resources.
Let’s stand up a table for the lambda above to read from:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: TableAlerter: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs6.10 Events: Stream: Type: DynamoDB Properties: Stream: !GetAtt DynamoDBTable.StreamArn BatchSize: 100 StartingPosition: TRIM_HORIZON Alerts: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: id AttributeType: S KeySchema: - AttributeName: id KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 5
The official AWS documentation on SAM isn’t particularly instructive, with just a few examples and some tutorial references. However the full specification is laid out in the AWSLabs GitHub project documentation.
Once you’ve mastered the basics, or if you’re feeling overwhelmed by the tool, you may want to use a service to create and deploy your stack via CloudFormation. Stackery does just that, and recently announced that Stackery now builds SAM templates natively.