A new AWS CloudFormation linter – cfn-python-lint
Introduction
Have you ever been using any linters for AWS CloudFormation templates? I have been using linters in my project because our team manages many templates every day.
But, you might think it's not necessary that you use those tools for templates which aren't as expressive as programming codes - It's too much.
In some cases, it can be correct. For example, because your project is small, you manage a few templates and you are the one who manages templates. But if your project and templates have grown, templates will be developed with others so that templates will be managed with Git, and developed through Pull Request based development flows like GitHub Flow. In this case, without linters, if your teammates ask you to review his/her templates, you will point out nitpicks over there (e.g., typos, value type definitions, project-specific conventions). It's not productive. Let the tool point out these issues so people should focus on more interesting problems.
From these kinds of reasons, I have tried many linters for months. But I haven't found the best suited for our project. For example, some tools don't support new resources recently introduced by AWS; the runtime is not Python so that installation on CI environment is a bit complicated.
Recently I found new one made by AWS, its name is cfn-python-lint. It seems good to me! Its runtime is Python and it's made by AWS!
So, I try to introduce this tool in this post.
Test Environment
- Python: 3.6.5
- cfn-python-lint: 0.3.2
What can cfn-python-lint do?
The README describe its functionality briefly so that I cite the sentence:
Validate CloudFormation yaml/json templates against the CloudFormation spec and additional checks. Includes checking valid values for resource properties and best practices.
It's worth noting that it has flexible functionalities:
But there is the note that you should be careful. This tool is still in its active developing stage so be careful when using it in your project. I quote the sentence about it:
This is an attempt to provide validation for CloudFormation templates properties and their values. For values things can get pretty complicated (mappings, joins, splits, conditions, and nesting those functions inside each other) so its a best effort to validate those values but the promise is to not fail if we can't understand or translate all the things that could be going on.
What is the difference between ValidateTemplate API?
AWS CloudFormation has ValidateTemplate API, which validates templates, as you can see. It can be used with aws cloudformation validate-template
command in AWS CLI; however, its design is, at least currently, so simple that it can detect syntax errors only. This is the most prominent difference with cfn-python-lint
.
I use both in our project for now to expect stricter checking (but it might be too much).
How to use
Anyway, let's get started. I introduce its basic usage, so if you want more advanced uses, please follow documents.
Installation is very easy with pip
.
# install $ pip install cfn-lint # verify $ cfn-lint --version cfn-lint 0.3.2
Because it supports AWS Serverless Application Model, I use the below template to demonstrate its basic usage.
--- AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: Test Template Resources: TestFunc: Type: AWS::Serverless::Function Properties: FunctionName: test-func CodeUri: src/handlers/test_func Handler: index.handler Runtime: python3.6
At first, let's use it against the above template normally.
$ cfn-lint sam.yml
Nothing happened, that proves the template is correct. Next, change the template like below (typo), then use it again.
--- sam.yml 2018-06-30 16:45:17.000000000 +0900 +++ sam-invalid.yml 2018-06-30 16:45:15.000000000 +0900 @@ -10,4 +10,4 @@ test-func CodeUri: src/handlers/test_func Handler: index.handler - Runtime: python3.6 + runtime: python3.6
$ cfn-lint sam-invalid.yml E0001 Resource with id [TestFunc] is invalid. property runtime not defined for resource of type AWS::Serverless::Function sam-invalid.yml:1:1
Yes! It warned me about the error there is no such a property in AWS::Serverless::Function
resource. By the way, ValidateTemplate
API doesn't warn any error.
$ aws cloudformation validate-template --template-body file://sam-invalid.yml { "Parameters": [], "Description": "Test Template" }
Conclusion
I introduced cfn-python-lint
to lint AWS CloudFormation templates. Its quality and flexibility, it's the best for the linter ever! I will continue to use it.
I hope this post is useful to you.