cfn-lint

Learn how the starter kit uses cfn-lint to validate CloudFormation templates and enforce AWS best practices.


What is cfn-lint?

cfn-lint is an open-source tool from AWS that validates CloudFormation templates against the CloudFormation resource specification. It catches errors before deployment and enforces best practices for template authoring.

How the starter kit uses cfn-lint

  • Local validation: Run ./scripts/validate-templates.sh to validate all templates before committing changes
  • CI enforcement: The deploy workflow runs cfn-lint before any Rain deployment. Failing checks block the pipeline
  • VS Code integration: Pair with the CloudFormation Linter extension for real-time validation while editing

Running cfn-lint manually

The starter kit validation script includes cfn-lint:

./scripts/validate-templates.sh

Or run cfn-lint directly on specific templates:

# Validate a single template
cfn-lint templates/oidc-provider.yml

# Validate all templates
cfn-lint templates/*.yml

# Validate with specific configuration
cfn-lint --config .cfnlintrc templates/*.yml

Common issues detected

cfn-lint catches a wide range of template issues:

Missing required properties

# Bad: Missing required properties
Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      # BucketName is optional, but let's say we want encryption
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          # Missing required Rules property

Error: E3002: Invalid property for resource

Invalid property values

# Bad: Invalid property value
Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.invalid  # Invalid instance type

Error: E3030: Value must be one of the allowed values

Incorrect intrinsic functions

# Bad: Using Ref instead of GetAtt
Resources:
  Bucket:
    Type: AWS::S3::Bucket

  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument:
        Statement:
          - Effect: Allow
            Principal: "*"
            Action: s3:GetObject
            Resource: !Ref Bucket  # Should use !GetAtt Bucket.Arn

Error: E1012: Ref is not valid for resource type

AWS service limits

# Bad: Exceeds parameter limit
Parameters:
  Param1:
    Type: String
  # ... 200+ parameters (limit is 200)

Error: E2500: Template contains more than 200 parameters

Region-specific resources

# Bad: Resource not available in specified region
Resources:
  Cluster:
    Type: AWS::ECS::Cluster
    # Some older regions don't support certain features

Warning: W3045: Resource not available in all regions

Configuration

The starter kit includes a .cfnlintrc file. For details on the default configuration and how to customize it, see the cfn-lint configuration section.

Configuration file format

Create a .cfnlintrc file in YAML or JSON format:

# .cfnlintrc
templates:
  - templates/*.yml
  - templates/*.yaml

ignore_templates:
  - templates/experimental/*.yml

regions:
  - us-east-1
  - eu-west-1

ignore_checks:
  - E3001  # Skip specific rule
  - W*     # Skip all warnings

include_checks:
  - I      # Include informational checks

configure_rules:
  E3012:
    strict: false

Configuration options explained

templates

Glob patterns for templates to validate:

templates:
  - templates/*.yml
  - stacks/**/*.yaml

ignore_templates

Exclude specific templates:

ignore_templates:
  - templates/experimental/*.yml
  - templates/deprecated/*.yaml

regions

Validate against specific regions:

regions:
  - us-east-1
  - eu-west-1

Templates are checked for region-specific resource availability.

ignore_checks

Skip specific rules by ID:

ignore_checks:
  - E3001  # Specific error
  - W*     # All warnings
  - I*     # All info messages

include_checks

Include additional check types:

include_checks:
  - I  # Informational
  - W  # Warnings

configure_rules

Fine-tune specific rules:

configure_rules:
  E3012:
    strict: false
  W2001:
    strict: true

Rule categories

cfn-lint organizes rules into categories:

  • E1xxx — Basic CloudFormation errors (syntax, schema)
  • E2xxx — Template structure errors (limits, formatting)
  • E3xxx — Resource specification errors (properties, values)
  • E4xxx — Function errors (Ref, GetAtt, Sub, etc.)
  • W1xxx — Basic warnings
  • W2xxx — Template structure warnings
  • W3xxx — Resource specification warnings
  • I1xxx — Informational messages

Suppressing specific rules

Inline metadata suppression

Suppress rules for specific resources:

Resources:
  LegacyBucket:
    Type: AWS::S3::Bucket
    Metadata:
      cfn-lint:
        config:
          ignore_checks:
            - E3001
            - W3045
    Properties:
      BucketName: legacy-bucket

Template-level suppression

Suppress rules for the entire template:

Metadata:
  cfn-lint:
    config:
      ignore_checks:
        - W3045

Output formats

Default format

cfn-lint templates/example.yml

Output:

E3001: Invalid Property Resources/Bucket/Properties/InvalidProperty
templates/example.yml:10:7

JSON format

cfn-lint --format json templates/*.yml

Useful for parsing results in scripts or CI/CD.

JUnit format

cfn-lint --format junit templates/*.yml > results.xml

Useful for test reporting systems.

Parseable format

cfn-lint --format parseable templates/*.yml

Easier for tools to parse.

Custom format

cfn-lint --format '{filename}:{location}:{rule_id}:{message}' templates/*.yml

Integration with CI/CD

The GitHub Actions workflow includes cfn-lint as part of the validation stage:

- name: Validate templates
  run: ./scripts/validate-templates.sh

This runs cfn-lint on all templates, ensuring validation checks pass before deployment. Failed checks block the pipeline, preventing invalid templates from reaching production.

For complete details on how cfn-lint integrates into the automated workflow, see the CI/CD Workflow documentation.

Integration with VS Code

Install the CloudFormation Linter extension for real-time validation:

  1. Install the CloudFormation Linter extension
  2. Install cfn-lint: pip install cfn-lint
  3. Open any CloudFormation template
  4. See errors and warnings inline as you type

For more tips on VS Code integration, read our guide on leveling up CloudFormation authoring in VS Code.

Best practices

  • Run locally first: Use ./scripts/validate-templates.sh before committing to catch issues early
  • Keep cfn-lint updated: Run pip install --upgrade cfn-lint regularly to get new rules and resource specs
  • Review all errors: Don't ignore errors—they usually indicate real problems
  • Use VS Code integration: Get real-time feedback while editing templates
  • Combine with Checkov: Use both tools together—cfn-lint focuses on correctness while Checkov focuses on security
  • Configure for your regions: Set the regions option to validate against your target regions

Troubleshooting

Template not found

# Error: Template file not found

Solution: Check file paths in .cfnlintrc or command line arguments.

Python version issues

cfn-lint requires Python 3.8+:

# Check Python version
python --version

# Upgrade if needed
brew upgrade python  # macOS

Outdated resource specs

If cfn-lint doesn't recognize new AWS resources:

# Update cfn-lint
pip install --upgrade cfn-lint

Too many false positives

If specific rules are too strict for your use case:

# Add to .cfnlintrc
ignore_checks:
  - W3045  # Skip specific warning

Next steps

Pair cfn-lint with Checkov for comprehensive validation coverage, and review the Scripts reference to see all available validation commands.