Writing CloudFormation Templates in YAML – A First Look

AWS recently released a new “game changing” feature for CloudFormation Templates – support for YAML. I’d like to give a first look at utilizing YAML for CloudFormation Templates (CFTs) and discuss how this feature might be incorporated in the architect and engineer’s toolbox for AWS. If you’re not familiar with YAML you’ll want to take a look at the guides here.

YAML Support

This is something the AWS community has been begging for, for quite a while. One of the easiest ways to tell that JSON is not sufficient is the numerous projects that exist to support JSON based templates (Troposphere, Sparkleformation, Terraform, etc). Now with YAML support we’re getting that much closer to that Infrastructure-as-Code feeling we’ve been missing. Let’s walk through some sample YAML CFT code and highlight where it has a major impact. The code samples below are borrowed almost entirely from the AWS UserGuide for CloudFormation.

AWSTemplateFormatVersion: "2010-09-09" Description: A sample template Parameters: FilePath: Description: The path of the file. Type: String Default: /home/ec2-user/userdata Resources: MyEC2Instance: Type: "AWS::EC2::Instance" # 1 Quotes are unnecessary here - will they always be? Properties: ImageId: ami-c481fad3 # 2 Quotes removed from the example - still works InstanceType: t2.nano KeyName: 2ndwatch-sample-keypair Tags: # 3 Here I switch to using single spaces - Key: Role # 4 Tag list item is inline Value: Test Instance - # 5 Next list item is block Key: Owner Value: 2ndWatch BlockDeviceMappings: # 6 Switch back to double spaces - DeviceName: /dev/sdm Ebs: VolumeType: gp2 VolumeSize: 10 UserData: Fn::Base64: !Sub | # No more Fn::Join needed #!/bin/bash echo "Testing Userdata" > ${FilePath} chown ec2-user.ec2-user ${FilePath}

A couple of things you notice in this example are how clean the code looks and the comments. These are both necessary to make code descriptive and clear. In the comments I call out a few considerations with the YAML format. First, in many of the examples AWS provides there are quotes around values that don’t need them. When I removed them (comment 1 and 2), the CFT still worked. That said, you may want to codify on quotes/no quotes at the start of your project or for your entire department/company for consistency. Additionally, as you will notice in my second set of comments, I switch from 2-space to 1-space YAML formatting (comments #3 and #6). This is “legal” but annoying. Just as with JSON, you’ll need to set some of your own rules for how the formatting is done to ensure consistency.

Taking a look at the Tags section you’ll see that lists are supported using a hyphen notation. In the Tags property I’ve displayed two different formats for how a list item may be denoted. 1. There can be a hyphen alone on a line with a “block” underneath (comment #5) or 2. Inline with the hyphen and the rest following after with the same spacing (comment #4). As before, you’ll want to decide how you want to format lists. Multiple AWS examples do it in different ways.

Following on to the userdata property, the next thing you’ll notice is the lack of the Fn::Join function. This makes the creation of userdata scripts very close to the actual script you would run on the server. In a previous article I gave Terraform high marks for having similar functionality, and now AWS has brought CFT up to par. The new !Sub notation helps clean up the substitution a bit, too (it’s also available in JSON). Of course if you miss it, the Fn::Join can still be used like this:

Tags: - Key: Name Value: Fn::Join: - "-" - - !Ref AWS::StackName - PrivateRouteTable1

This would produce a tag of Name = StackName-PrivateRouteTable1 just like it did previously in JSON, but we would advise against doing this because the old notation is much less flexible and more prone to error than the new “joinless” formatting. Notice that nested lists are created using two hyphens.

Conversion Tools

In another bit of good news, you can utilize online conversion tools to update your JSON CFTs to YAML. As you might guess, it will take a bit of cleanup to bring it in line with whatever formatting decisions you’ve made, but it gets you most of the way there without a complete rewrite. Initial s on simple CFTs ran with no updates required (using http://www.json2yaml.com/). A second on a 3000-line CFT converted down to 2300 lines of YAML and also ran without needing any updates (YMMV). This is a big advantage over tools like Terraform where all new templates would have to be built from scratch, particularly since a conversion tool could probably be whipped together in short order.

All in all, this is a great update to the CloudFormation service and demonstrates AWS‘s commitment to pushing the service forward.

If you have questions or need help getting started, please Contact Us at 2nd Watch.

-Coin Graham, Sr Cloud Consultant, 2nd Watch