AWS just released a new feature for CloudFormation, “CloudFormation Modules“. Of course, we immediately had to try it out. In this blog post, you can follow along with our exploration.
To use this new feature, you need the latest version of the CloudFormation cli. You can install this with
pip install cloudformation-cli (tip: you can use pipx to keep your python environment clean). If you already had an older version installed, run
pip install --upgrade cloudformation-cli
Starting a new project
To create a new module, we follow a similar process as with Resource Providers. For this post, we’re going to create a module to set up an S3 Bucket and a CloudFront Distribution for static website hosting.
We first create a new directory, after that we run
cfn init. This will ask us for input, and we can specify that we want to create a module for our generic static website
~$ cfn init Initializing new project Do you want to develop a new resource(r) or a module(m)?. >> m What is the name of your module type? (<Organization>::<Service>::<Name>::MODULE) >> Cloudar::Generic::StaticWebsite::MODULE Directory /cloudar_generic_staticwebsite/fragments Created Initialized a new project in /cloudar_generic_staticwebsite
Writing our module
We already had a generic CloudFormation template that was doing a similar thing. So we deleted
sample.json and replaced it with our own
website.yaml. Officially, only json is supported, but in our test yaml worked fine. Since this is a test, we’re okay with taking the unsupported path. For use in a production environment, we can use cfn-flip to convert our template to json.
Depending on your template, you might not have to change anything. Going over the resources to make sure they have clear names and running cfn-lint isn’t a bad idea though. You can see the template we created on GitHub.
Deploying our module
We already had our AWS credentials configured for the AWS cli. Which meant that the only thing we had to do for our deployment was running
cfn submit --region us-east-1. If you are submitting multiple times, you can add
--set-default to change the default version after submitting it.
You can see the deployed version, with all its properties in the CloudFormation console. This is also a great place to see all the resources our module will create
Using our module
This is where it gets really interesting, we are going to use the module we created. We made a template with one resource (see Github for the full template):
Resources: StaticWebsite: Type: "Cloudar::Generic::StaticWebsite::MODULE" Properties: DomainName: !Ref DomainName HostedZoneId: !Ref HostedZoneId
CloudFormation will expand that for us, and put every resource that we defined in our module in our processed template.
After waiting for our deployment to finish, we can see all created resources and both our original and the processed template in the CloudFormation console.
We’re very excited about this new release and are looking forward to seeing where this might lead. We also have a list of things we think might improve this even more (like an AWS::ModuleName pseudo-parameter), and will probably start conversations about that on the roadmap or issue tracker soon.