Automatically updated docker image for cfn-lint

April 18, 2024 by Paulina BudzoƄ

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 weider 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, it’s 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:

  1. The image is automatically updated by using GitHub Actions scheduled to check daily if a new cfn-lint release is available. So you can be sure that using :latest tag, actually gives you the latest version.
  2. The repository is 100% transparent and public - you can see all the steps that are used to build the image. We do not make any changes to the Dockerfile provided by the cfn-lint team, do not modify any code or software within the image and do not add anything. So you can be sure it’s safe, as intended by the creators.
  3. The repository will not become abandoned or broken - thanks to the automation, there’s nothing to abandon. As long as the Dockerfile within cfn-lint repository works, our build process will work and continue producing images for your use.

You can find the “building repository” on GitHub:

The images are pushed to:


To get the image from Docker Hub:

docker pull mysteriouscode/cfn-lint

To get the image from ECR Public:

docker pull

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

You can easily use it within your existing pipelines or code building processes, however please notice that you’ll need to overwrite the entrypoint, as the cfn-lint’s Dockerfile does not follow the official docker image consistency guidelines:

If you try to use it as-is in Jenkins, it will complain with an error similar to this:

ERROR: The container started but didn't run the expected command. Please double check your ENTRYPOINT 
does execute the command passed as docker run argument, as required by official docker images (see for entrypoint consistency requirements).
Alternatively you can force image entrypoint to be disabled by adding option `--entrypoint=''`.

So, to use within CI, see the following examples:

Jenkins Pipelines

docker.image('mysteriouscode/cfn-lint:latest').inside("--entrypoint=''") {
    sh "cfn-lint --info"

GitLab CI

    name: mysteriouscode/cfn-lint:latest
    entrypoint: [""]
    - cfn-lint --info

Hopefully, this will make our lives linting CloudFormation templates a little easier.

Posted in: CloudFormation AWS