cfn-lint is a command-line tool that helps you find common errors and stylistic issues in your AWS CloudFormation templates before you deploy them.

Here’s a CloudFormation template that defines a simple EC2 instance:

AWSTemplateFormatVersion: '2010-09-09'
Description: A simple EC2 instance

Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0abcdef1234567890
      InstanceType: t2.micro
      Tags:
        - Key: Name
          Value: MyTestInstance

Let’s imagine we’ve made a mistake in this template. Perhaps we’ve used an incorrect InstanceType. If we run cfn-lint on this file (let’s say it’s named template.yaml), we might see output like this:

template.yaml:31:0: E0001 Instance type 't2.microX' is not valid

This output tells us the file (template.yaml), the line number (31), the column number (0), the error code (E0001), and a description of the problem. cfn-lint caught that t2.microX is not a valid instance type.

cfn-lint works by applying a set of rules to your CloudFormation template. These rules can check for a wide range of issues, from syntax errors and invalid property values to security best practices and stylistic inconsistencies. The rules are organized into categories, such as E for errors, W for warnings, and I for informational messages.

You can customize cfn-lint’s behavior using a .cfnlintrc configuration file. This allows you to enable or disable specific rules, set severity levels, and even define custom rules. For example, a .cfnlintrc file might look like this:

{
  "rulesdir": [],
  "exclude_rules": [],
  "configure_rules": {
    "E0001": "enabled",
    "W2002": "disabled"
  }
}

This configuration explicitly enables rule E0001 (which we saw earlier for invalid instance types) and disables rule W2002 (which might be a warning about unused resources that you want to ignore for now).

The primary benefit of using cfn-lint is to catch errors early in the development lifecycle, which saves time and reduces the cost associated with failed deployments. It integrates seamlessly into CI/CD pipelines, acting as a gatekeeper to prevent invalid templates from being deployed to your AWS environment.

One of the most powerful aspects of cfn-lint is its extensibility. While it comes with a comprehensive set of built-in rules, you can also write and load your own custom rules. This is invaluable for enforcing organizational standards or checking for specific security configurations that are unique to your environment. For instance, you could create a rule that flags any EC2 instance being launched without a specific security group attached, or one that ensures all S3 buckets have versioning enabled. You can specify directories containing these custom rules in the rulesdir option within your .cfnlintrc file.

Beyond basic validation, cfn-lint can also help enforce best practices. For example, it can warn you if you’re using hardcoded credentials, if security group rules are too permissive, or if you’re not specifying appropriate lifecycle policies for S3 buckets. These checks are crucial for maintaining a secure and cost-effective cloud infrastructure.

When cfn-lint finds an issue, it provides a clear, actionable message. For example, if you try to deploy a template with a Parameter that is never used in any Resource property, cfn-lint might report:

template.yaml:10:0: W0001 Parameter 'MyUnusedParameter' is not used

This warning (W0001) is helpful because unused parameters can lead to confusion and clutter in your templates. The fix is straightforward: either remove the parameter if it’s truly unnecessary or ensure it’s being referenced in a resource definition.

The next step after successfully linting your CloudFormation templates is to ensure you’re also managing the drift of your deployed resources.

Want structured learning?

Take the full Cloudformation course →