Home

Awesome

AWS CloudFormation Linter

<img alt="[cfn-lint logo]" src="https://github.com/aws-cloudformation/cfn-python-lint/blob/main/logo.png?raw=true" width="150" align="right">

Testing PyPI version PyPI downloads PyPI downloads codecov Discord Shield

Validate AWS CloudFormation yaml/json templates against the AWS CloudFormation resource provider schemas and additional checks. Includes checking valid values for resource properties and best practices.

Warning

This is an attempt to provide validation for AWS 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 it's 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.

Contribute

We encourage you to contribute to cfn-lint! Please check out the Contributing Guidelines for more information on how to proceed.

Community

Join us on Discord! Connect & interact with CloudFormation developers & experts, find channels to discuss and get help for cfn-lint, CloudFormation registry, StackSets, Guard and more:

Join our Discord

Serverless Application Model

The Serverless Application Model (SAM) is supported by the linter. The template is transformed using AWS SAM before the linter processes the template.

To get information about the SAM Transformation, run the linter with --info

Install

Python 3.8+ is supported.

Pip

pip install cfn-lint. If pip is not available, run python setup.py clean --all then python setup.py install.

Optional dependencies

cfn-lint has optional dependencies based on certain features you may need.

Homebrew (macOS)

brew install cfn-lint

Docker

In cfn-lint source tree:

docker build --tag cfn-lint:latest .

In repository to be linted:

docker run --rm -v `pwd`:/data cfn-lint:latest /data/template.yaml

Editor Plugins

There are IDE plugins available to get direct linter feedback from you favorite editor:

GitHub Action

Online demo

Basic Usage

Multiple files can be linted by either specifying multiple specific files:

or by using wildcards (globbing):

Lint all yaml files in path:

Lint all yaml files in path and all subdirectories (recursive):

Note: If using sh/bash/zsh, you must enable globbing. (shopt -s globstar for sh/bash, setopt extended_glob for zsh).

Exit Codes

cfn-lint will return a non zero exit if there are any issues with your template. The value is dependent on the severity of the issues found. For each level of discovered error cfn-lint will use bitwise OR to determine the final exit code. This will result in these possibilities.

Configuring Exit Codes

cfn-lint allows you to configure exit codes. You can provide the parameter --non-zero-exit-code with a value of informational, warning, error, or none. cfn-lint will determine the exit code based on the match severity being the value of the parameter --non-zero-exit-code and higher. The exit codes will remain the same as above.

The order of severity is as follows:

  1. informational default
  2. warning
  3. error
  4. none Exit code will always be 0 unless there is a syntax error
Specifying the template as an input stream

The template to be linted can also be passed using standard input:

Specifying the template with other parameters

Configuration

Command Line

From a command prompt run cfn-lint <path to template> to run standard linting of the template.

Config File

It will look for a configuration file in the following locations (by order of preference):

In that file you can specify settings from the parameter section below.

Example:

templates:
  - test/fixtures/templates/good/**/*.yaml
ignore_templates:
  - codebuild.yaml
include_checks:
  - I
custom_rules: custom_rules.txt

Parameters

Optional parameters:

Command LineMetadataOptionsDescription
-h, --helpGet description of cfn-lint
-z, --custom-rulesfilenameText file containing user-defined custom rules. See here for more information
-t, --templatefilenameAlternative way to specify Template file path to the file that needs to be tested by cfn-lint
-f, --formatformatquiet, parseable, json, junit, pretty, sarifOutput format
-l, --list-rulesList all the rules
-r, --regionsregions[REGIONS [REGIONS ...]], ALL_REGIONSTest the template against many regions. Supported regions
-b, --ignore-bad-templateignore_bad_templateIgnores bad template errors
--ignore-templatesIGNORE_TEMPLATES [IGNORE_TEMPLATES ...]Ignore templates from being scanned
-a, --append-rulesappend_rules[RULESPATH [RULESPATH ...]]Specify one or more rules paths using one or more --append-rules arguments. Each path can be either a directory containing python files, or an import path to a module.
-i, --ignore-checksignore_checks[IGNORE_CHECKS [IGNORE_CHECKS ...]]Only check rules whose ID do not match or prefix these values. Examples: <br />- A value of W will disable all warnings<br />- W2 disables all Warnings for Parameter rules.<br />- W2001 will disable rule W2001
-e, --include-experimentalinclude_experimentalWhether rules that still in an experimental state should be included in the checks
-c, --include-checksINCLUDE_CHECKS [INCLUDE_CHECKS ...]Include rules whose id match these values
-m, --mandatory-checksRules to check regardless of ignore configuration
--non-zero-exit-codeinformational (default), warning, error, none]Exit code will be non zero from the specified rule class and higher
-x, --configure-ruleCONFIGURE_RULES [CONFIGURE_RULES ...]Provide configuration for a rule. Format RuleId:key=value. Example: E3012:strict=true
-D, --debugSpecify to enable debug logging. Debug logging outputs detailed information about rules processing, useful for debugging rules.
-I, --infoSpecify to enable logging. Outputs additional information about the template processing.
-u, --update-specsUpdate the CloudFormation resource provider schemas. You may need sudo to run this. You will need internet access when running this command
-o, --override-specfilenameSpec-style file containing custom definitions. Can be used to override CloudFormation specifications. More info here
-g, --build-graphCreates a file in the same directory as the template that models the template's resources in DOT format
-s, --registry-schemasone or more directories of CloudFormation Registry Resource Schemas
-v, --versionVersion of cfn-lint

Info Rules

To maintain backwards compatibility info rules are not included by default. To include these rules you will need to include -c I or --include-checks I

Metadata

Template Based Metadata

Inside the root level Metadata key you can configure cfn-lint using the supported parameters.

Metadata:
  cfn-lint:
    config:
      regions:
        - us-east-1
        - us-east-2
      ignore_checks:
        - E2530

Resource Based Metadata

Inside a resources Metadata key you can configure cfn-lint to ignore checks. This will filter out failures for the resource in which the Metadata belongs. Keep in mind that AWS::Serverless resources may lose metadata during the Serverless transform

Resources:
  myInstance:
    Type: AWS::EC2::Instance
    Metadata:
      cfn-lint:
        config:
          ignore_checks:
            - E3030
    Properties:
      InstanceType: nt.x4superlarge
      ImageId: ami-abc1234

Precedence

cfn-lint applies configurations from several sources. The rules at lower levels are overridden by those at higher levels.

  1. cfnlintrc configurations
  2. Template Metadata configurations
  3. CLI parameters

Configure Rules

Certain rules support configuration properties. You can configure these rules by using configure_rules parameter.

From the command line the format is RuleId:key=value, for example: E3012:strict=true. From the cfnlintrc or Metadata section the format is

Metadata:
  cfn-lint:
    config:
      configure_rules:
        RuleId:
          key: value

The configurable rules have a non-empty Config entry in the table here.

Getting Started Guides

There are getting started guides available in the documentation section to help with integrating cfn-lint or creating rules.

Rules

This linter checks the AWS CloudFormation template by processing a collection of Rules, where every rule handles a specific function check or validation of the template.

This collection of rules can be extended with custom rules using the --append-rules argument.

More information describing how rules are set up and an overview of all the Rules that are applied by this linter are documented here.

Custom Rules

The linter supports the creation of custom one-line rules which compare any resource with a property using pre-defined operators. These custom rules take the following format:

<Resource Type> <Property[*]> <Operator> <Value> [Error Level] [Custom Error Message]

Example

A separate custom rule text file must be created.

The example below validates example_template.yml does not use any EC2 instances of size m4.16xlarge

custom_rule.txt

AWS::EC2::Instance InstanceType NOT_EQUALS "m4.16xlarge" WARN "This is an expensive instance type, don't use it"

example_template.yml

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  myInstance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: m4.16xlarge
      ImageId: ami-asdfef

The custom rule can be added to the configuration file or ran as a command line argument

The linter will produce the following output, running cfn-lint example_template.yml -z custom_rules.txt:

W9001  This is an expensive instance type, don't use it
mqtemplate.yml:6:17

More information describing how custom rules are setup and an overview of all operators available is documented here.

Customize specifications

The linter follows the AWS CloudFormation resource provider schemas by default. However, for your use case specific requirements might exist. For example, within your organisation it might be mandatory to use Tagging.

The linter provides the possibility to implement these customized specifications using the --override-spec argument.

More information about how this feature works is documented here

pre-commit

If you'd like cfn-lint to be run automatically when making changes to files in your Git repository, you can install pre-commit and add the following text to your repositories' .pre-commit-config.yaml:

repos:
  - repo: https://github.com/aws-cloudformation/cfn-lint
    rev: v1.20.0 # The version of cfn-lint to use
    hooks:
      - id: cfn-lint
        files: path/to/cfn/dir/.*\.(json|yml|yaml)$

If you are using a .cfnlintrc and specifying the templates or ignore_templates we would recommend using the .cfnlintrc exlusively to determine which files should be scanned and then using:

repos:
  - repo: https://github.com/aws-cloudformation/cfn-lint
    rev: v1.20.0 # The version of cfn-lint to use
    hooks:
      - id: cfn-lint-rc

Note: When mixing .cfnlintrc ignore_templates and files option in your .pre-commit-config.yaml cfn-lint may return a file not found error