If you’re using CloudFormation, you probably know about cfn-lint - a
linting tool created by the CloudFormation team to validate templates against the schema and best practices. Validating
each template before deployment is in itself actually
considered a best practice by AWS.
However, simply using validate-template in the Console or CLI only validates the basic syntax of the template, not the
actual contents and resource specification. That’s where using a linter like cfn-lint
can be helpful to make sure you’re not making any obvious mistakes or going against best practices in your resources.
You can use cfn-lint in a number of ways during development, including simply within command-line, using git pre-commit
hooks or as a plugin to your IDE. All those options, while helpful in day-to-day work, do not establish code quality
standards for your overall codebase. To do that, it’s ideal to include linting as part of CI/CD pipeline and/or
pull/merge-requests approval process.
That is where you can come across a hurdle: cfn-lint does not have an official, up-to-date docker image
The issue
Most automated build processes use docker to provide variety of tools and services for validation and testing. Lack of a
reliable, up-to-date docker image for cfn-lint definitely inhibits wider adoption of the tool.
This specific issue
has been open on GitHub since 2019, and unfortunately there has been no indication from the CloudFormation team that
there is a will to resolve it. While cfn-lint repository does contain a
Dockerfile - you’d need to maintain
your own copy of the image and update it regularly when the releases become available. That’s obviously going to be too
much of a hassle for most companies just for a simple linting tool. You can find a number of images on Docker Hub that claim
to provide this software, but vast majority seems to have been abandoned (published once by an eager person who stumbled
upon this exact issue) or contain very little information about usage or transparency (and so, its safety).
The solution
To help with this predicament, we have created (yet another)
repository with a Docker image for cfn-lint - but this one
is different.
Here’s how:
- The image is automatically updated by using GitHub Actions
scheduled to check daily if a new
cfn-lintrelease is available. So you can be sure that using:latesttag, actually gives you the latest version. - The repository is 100% transparent and public - you can see all the steps that are used to build the image. The Dockerfile used by the build is part of the repo, so you can see how it’s built - we do not modify any code and the only software installed. is cfn-lint. So you can be sure it’s safe, as intended by the creators.
- The repository will not become abandoned or broken - thanks to the automation, there’s nothing to abandon. As long as
the Dockerfile within
cfn-lintrepository works, our build process will work and continue producing images for your use.
You can find the “building repository” on GitHub: https://github.com/MysteriousCode/cfn-lint-docker
The images are pushed to:
- Docker Hub: https://hub.docker.com/r/mysteriouscode/cfn-lint
- Public ECR: https://gallery.ecr.aws/mysteriouscode/cfn-lint
Why not use the Dockerfile from `cfn-lint` repo?
The Dockerfile shipped within cfn-lint’s repository installs a specific hard-coded version of cfn-lint from pip.
Since both major versions 0.x and 1.x are available, this meant we could not use that file to build the v0.x images.
Additionally, cfn-lint’s Dockerfile does not follow the official docker image consistency guidelines which means it forces a specific entrypoint. This means, that apart from limited use-cases, you’d need to overwrite the entrypoint every time in order to use it.
Examples
To get the image from Docker Hub:
docker pull mysteriouscode/cfn-lint
To get the image from ECR Public:
docker pull public.ecr.aws/mysteriouscode/cfn-lint:latest
Release versions retain with the same tag as the
cfn-lint release on Github, for example:
docker pull mysteriouscode/cfn-lint:v0.86.3
Examples in CI
To use within CI, see the following examples:
Jenkins Pipelines
| |
GitLab CI
| |
Hopefully, this will make our lives linting CloudFormation templates a little easier.