If you have been building on AWS, you are probably familiar with CloudFormation. It can be an extensive service to learn thoroughly, so even when you’re familiar with writing templates, there might still be some features you didn’t use yet.
This blog post will highlight something you might not know yet in four different domains: writing templates, securing deployments, usability, and extensibility. Hopefully, this allows you to do even more with CloudFormation
One of the best ways to increase your CloudFormation productivity is to minimize the time you’re waiting on a stack that failed to deploy. A great way to do that is to use cfn-lint to make sure you don’t start the deploy if there are errors in your template.
Other tools like cfn-nag, cfn-guard, or taskcat will help you write secure, compliant, and region-independent templates, respectively. Cfn-lint is the one that will save you the most time when authoring templates by flagging misconfigurations, invalid properties, and misformatted templates. It also is easy to integrate into your IDE, pre-commit, or a CI/CD pipeline.
If you’re already using it, I don’t need to convince you of its value. I do, however, have some tips for getting the most out of it.
- You can include experimental rules with
- You can add your own checks (written in python) with
- You can enable more built-in rules with
--include-checks I. The I stands for info. One of these informational checks that I find very useful is a warning if a resource that might contain state has no
Another cool feature is that the linter can create a resource graph from your template. This is used by the tool to indicate when you write a circular dependency. It’s just as useful to resolve those circles or create a visual representation of your template.
There are also some features of CloudFormation itself that I want to highlight. The first is how you can leverage its integration with IAM to prevent people from skipping the infrastructure-as-code step without completely locking down the account.
One way to accomplish that is to use a CloudFormation Service Role tied to your stack. This way, you can give minimal permission to your users and more broad permissions to CloudFormation. If you’re using ServiceCatalog to deploy infrastructure, you’re probably doing something very similar. This solution comes with some IAM complexity. The person creating the stack needs the
iam:PassRole permission, but once set up, everyone who can update the stack will do so with that Role assumed by CloudFormation (whether you want that depends on your use case).
If you do not want to think about the effects of
iam:PassRole, you can use the
aws:CalledVia IAM condition in the IAM policy of the person using CloudFormation. Being an IAM condition comes with its own set of challenges, but you might be more familiar with those.
You use this method by specifying that certain actions are only allowed if the
aws:CalledVia key is present and set to CloudFormation, and IAM will deny every request going directly to the service. The documentation has a helpful diagram.
When using CloudFormation to deploy infrastructure, you can make it easier to put in the right parameters by using
AllowedValues. Both of these only consider one parameter at a time. There is a way to validate Parameters that have a relationship with other parameters, though. Because you might want to validate that two parameters are mutually exclusive or that if one parameter is set, another parameter also has to have a value.
This is probably the most hidden CloudFormation feature because it’s documented in the Service Catalog documentation. And even though the Rules section seems to be a Service Catalog feature, you can use it directly in CloudFormation too. I wrote more about that in a previous blog post.
And this blogpost would not be complete without mentioning resource providers. Giving a full example of writing one would be its own post. Still, I’d like to show how this successor to custom resources has a lot of potential.
Resource Providers work similar to Custom Resources, and you will not see a big difference in your templates. They should be easier to manage, though (once they can be deployed with CloudFormation – the CloudFormation team is actively working on that). When you write your own Resource Provider, you also implement and expose a Read and List handler. This new approach gives you almost the same capabilities as a native CloudFormation resource.
There is also an integration with AWS Config for your Resource Providers, and AWS is developing more and more resource providers in the open.
We looked at 4 different ways to improve your CloudFormation experience, and I’m looking forward to hearing your favorite tips and tricks. Good luck making things!