For the rest of this article, let’s use CloudFormation as reference. And, if you are new to IaC, check how to create a new S3 bucket on AWS as code:
Pretty simple, right? And you can easily create as many buckets as you need using the above template (if you plan to do so, remove the BucketName line, since names are globally unique on S3!). For sure, way simpler and less prone to human error than clicking a bunch of buttons on AWS console or running commands on CLI.
Although this is a functional and useful CloudFormation template, following correctly all its rules, it doesn’t follow the rules of something bigger and more important: The AWS Well-Architected Framework. This amazing tool is a set of whitepapers describing how to architect on top of AWS, from 5 different views, called Pillars: Security, Cost Optimization, Operational Excellence, Reliability and Performance Efficiency. As you can see from the pillar names, an architecture that follows it will be more secure, cheaper, easier to operate, more reliable and with better performance.
Among others, this template will generate a S3 bucket that doesn’t have encryption enabled, doesn’t enforce said encryption and doesn’t log any kind of access to it–all recommended by the Well-Architected Framework. Even worse, these misconfigurations are really hard to catch in production and not visibly alerted by AWS. Even the great security tools provided by them such as Trusted Advisor or Security Hub won’t give an easy-to-spot list of buckets with those misconfigurations. Not for nothing Gartner states that 95% of cloud security failures will be the customer’s fault¹.
The DevOps movement brought to the masses a methodology of failing fast, which is not exactly compatible with the above scenario where a failure many times is just found out whenever unencrypted data is leaked or the access log is required. The question is, then, how to improve it? Spoiler alert: the answer lies on the IaC itself 🙂
Even before making sure a CloudFormation template is following AWS’ own best practices, the first obvious requirement is to make sure that the template is valid. A fantastic open-source tool called cfn-lint is made available by AWS on GitHub² and can be easily adopted on any CI/CD pipeline, failing the build if the template is not valid, saving precious time. To shorten the feedback loop even further and fail even faster, the same tool can be adopted on the developer IDE³ as an extension so the template can be validated as it is coded. Pretty cool, right? But it still doesn’t help us with the misconfiguration problem that we created with that really simple template in the beginning of this post.
Conformity⁴ provides, among other capabilities, an API endpoint to scan CloudFormation templates against the Well-Architected Framework, and that’s exactly how I know that template is not adhering to its best practices. This API can be implemented on your pipeline, just like the cfn-lint. However, I wanted to move this check further left, just like the cfn-lint extension I mentioned before.
With that challenge in mind, but also with the need for scanning my templates for misconfigurations fast myself, I came up with a Visual Studio Code extension that, leveraging Conformity’s API, allows the developer to scan the template as it is coded. The Extension can be found here⁵ or searching for “Conformity” on your IDE.
After installing it, scanning a template is as easy as running a command on VS Code. Below it is running for our template example:
This tool allows anyone to shift misconfiguration and compliance checking as left as possible, right on developers’ hands. To use the extension, you’ll need a Conformity API key. If you don’t have one and want to try it out, Conformity provides a 14-day free trial, no credit card required. If you like it but feels that this time period is not enough for you, let me know and I’ll try to make it available to you.
Oh, by the way, if you are wondering how a S3 bucket CloudFormation template looks like when following the best practices, take a look: