Listening to the Engineers & Coffee podcast the other day, Donnie mentioned the joys of the new CloudFormation changes. Being someone who’s worked on two different YAML-driven orchestration/config management tools (Heat and Ansible) I don’t need to be sold on YAML.
The Bad Old Days
Before YAML support, I’ve been using little scripts like this to use YAML for CloudFormation templates.
python -c 'import sys,yaml,json; json.dump(yaml.load(sys.stdin), sys.stdout)' \
< template.yaml \
> template.json
In any pipeline that needed CloudFormation, it’s easy to fine a spot that will
run the transformation. The Ansible’s CloudFormation module even
had YAML-to-JSON translation built in as template_yaml
.
So why go to all the trouble to write templates in YAML, it’s just a different way to specify the same stuff right? There’s a lot to be said for making templates easier to read later.
The New Hotness
As part of a fall cleanup of my AWS account, I rebuilt all my static sites with new CloudFormation templates to support HTTP/2, IPv6, and use the new support for Amazon Certificate Manager. Previously, I built my own Lambda custom resource to provide ACM certs to my sites.
SSLCert:
# Replace Lambda custom resource with official CloudFormation
Type: "AWS::CertificateManager::Certificate"
Properties:
DomainName: !Ref SiteDomain
DomainValidationOptions:
- DomainName: !Ref SiteDomain
ValidationDomain: !Ref DomainRoot
All that amounted a full rewrite, and I was able to take advantage of the new
syntax for intrinsic functions. !Ref MyVar
is so much cleaner than {"Ref": "MyVar"}
.
The full template is available on Github as part of my personal blog repo and it’s ready to use as long as you have:
- an AWS account
- Route53 for domain hosting
- static content to put in the S3 bucket
It’s especially nice to be able to use comments to explain different bits of the template, like what the Magic CloudFront Hosted Zone is:
- Name: !Ref SiteDomain
Type: A
AliasTarget:
DNSName: !GetAtt CDN.DomainName
# magic cloudfront hosted zone id
# see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
HostedZoneId: Z2FDTNDATAQYW2
The new !Ref
and !GetAttr
clean up the references to the CloudFront CDN,
and with a comment I can see where that alias target came from. Same thing
later in a mapping function to map regions to S3 website endpoints.
Special thanks to ServerlessCode sponsor Trek10, experts in supporting high-scale serverless and event-driven applications.
Mappings:
RegionMap:
# This is a map of the S3 website endpoints as of Jan 7 2016
# http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
# Don't edit this
sa-east-1:
websiteendpoint: "s3-website-sa-east-1.amazonaws.com"
ZoneId: "Z31GFT0UA1I2HV"
ap-northeast-1:
websiteendpoint: "s3-website-ap-northeast-1.amazonaws.com"
ZoneId: "Z2M4EHUR26P7ZW"
This template probably looks about like the one the Engineers & Coffee hosts had to write for their own site, minus the Lambda/API Gateway backend. Check it out, and remember to take advantage of comments and new cleaner syntax with the CloudFormation YAML templates.
Make Your Own
My site, rsb.io is on this template now and if you have improvements to the template pull requests are welcome. As always, the stack is launchable in one click: