AWS CloudFormation – step away from the json, here comes yaml
Anyone using Amazon Web Services will hopefully start using the CloudFormation service early on to start templating and automating the creation of their infrastructure. Until recently, these templates had to use the .json file format; however, this week (Sept. 2016), AWS announced that the templates could use .yaml.
Our project
We've been working on a project to move a website away from a monolithic app to a more loosely coupled set of services. As part of this, I created a CloudFormation template that created an SQS message queue, gave the queue permission to accept messages from S3 buckets, and then created an S3 bucket configured to send notifications to SQS when an upload occurs.
Moving CloudFormation from JSON to YAML
I'd initially written the CloudFormation template in json with a fairly standard layout including parameters, resources and some outputs. For example, the parameter section looked like this:
1"Parameters" : {
2 "BucketName" : {
3 "Type": "String",
4 "Default" : "s3bucket20160920",
5 "Description" : "Enter the name for the S3 bucket - this must be global unique"
6 },
7 "EventQueueName" : {
8 "Type": "String",
9 "Default" : "EventSQS",
10 "Description" : "Enter the name for the SQS queue to receive events from the S3 Bucket"
11 }
12 },
But as I was finishing testing, the announcement about using YAML was made, and I translated the JSON to YAML as below:
1Parameters:
2 BucketName:
3 Type: String
4 Description: Enter the name for the S3 bucket - this must be globally unique
5 Default: s3bucket20160920
6
7 EventQueueName:
8 Type: String
9 Description: Enter the name for the SQS queue to receive events from the S3 Bucket
10 Default: EventSQS
The resource section had a number of entries such as
1"UploadS3" : {
2 "Type": "AWS::S3::Bucket",
3 "DependsOn" : [ "S3EventQueue", "S3EventQueuePolicy" ],
4 "Properties" : {
5 "BucketName" : { "Ref" : "BucketName"},
6 "NotificationConfiguration" : {
7 "QueueConfigurations" : [
8 {
9 "Event" : "s3:ObjectCreated:*",
10 "Queue" : {
11 "Fn::GetAtt" : [ "S3EventQueue", "Arn" ]
12 }
13 }
14 ]
15 }
16 }
This code will create an S3 bucket and gives permissions to send events to the SQS we created earlier.
Rewriting this in YAML leads to
1UploadS3:
2 Type: AWS::S3::Bucket
3 DependsOn:
4 - S3EventQueue
5 - S3EventQueuePolicy
6 Properties:
7 BucketName:
8 Ref: BucketName
9 NotificationConfiguration:
10 QueueConfigurations:
11 - Event: s3:ObjectCreated:*
12 Queue: !GetAtt S3EventQueue.Arn
Personally (and I understand that this probably comes down to formatting you're used to working with), the YAML looks much cleaner to me -; the lack of braces and quotes means the template is much easier to follow (at least to me 🙂).
The big winner for me is that the YAML syntax allows for comments. There have been several posts in the AWS forums asking for some method of allowing comments; the only suggestions until now were to use the clunky metadata sections to pass information -; in YAML, the top of my resources looks like:
1# ------------------------------
2# And now, define the resources
3# 1. S3EventQueue SQS to receive notifucation from S3 on upload
4# 2. S3EventQueuePolicy Give permission for S3s to add message to S3EventQueue
5# 3. UploadS3 S3 Bucket - send notification events to S3EventQueue
6Resources:
If you'd like to see the full versions of the templates, click on the links to see the json version or the yaml one.
Be careful.
If you're not used to YAML, you do need to be careful with the indentation; I'd suggest if you have a JSON template already and are having problems, look at one of the online JSON->YAML converters (for example, http://www.json2yaml.com/)