Supply Chain

Secure AWS CloudFormation Templates with cnspec

Scan AWS CloudFormation templates for security misconfigurations with cnspec.

Catch insecure AWS resource configurations before they reach a stack. cnspec parses both YAML and JSON CloudFormation templates and exposes resources, parameters, outputs, and other template sections as queryable MQL resources. The Mondoo AWS Security policy ships CloudFormation variants of every check, so the same controls that evaluate your live AWS account also evaluate your CloudFormation templates in pull requests and CI pipelines. You can also use the CloudFormation provider inside your own policies to enforce additional standards.

This page is part of scanning your supply chain with cnspec. If you're new to cnspec, start with the Quickstart to install cnspec and run your first scan.

Prerequisites

To scan CloudFormation templates with cnspec, you must have:

Scan a CloudFormation template

Scan a single template file:

cnspec scan cloudformation template.yaml

cnspec automatically detects whether the template is YAML or JSON.

Scan options

OptionDescription
--asset-nameOverride the asset name
--annotationAdd an annotation to the asset (key=value)
--incognitoRun in incognito mode (do not report results to Mondoo Platform)
-o, --outputSet the output format (compact, csv, full, hdf, json, junit, ocsf-json, ocsf-parquet, report, sarif, summary, yaml)
-f, --policy-bundlePath to a policy file (local path, s3:// URI, or http(s):// URL)
--policySpecify policies to execute (requires --policy-bundle)
--risk-thresholdExit with status 1 if any risk meets or exceeds this value (0-100)

To gate a CI/CD pipeline, combine --risk-threshold with a report file, for example --risk-threshold 90 --output junit --output-target cnspec-junit.xml. 90 fails the job only on critical risks, 70 also fails on high risks, and 40 also fails on medium risks. To scan every infrastructure as code entry point in a repository in one step, use cnspec scan iac. For complete pipeline examples, read Integrate Mondoo with CI/CD Platforms.

Explore CloudFormation templates

Run cnspec shell cloudformation template.yaml to open the interactive shell and explore your templates.

Retrieve template info

cnspec> cloudformation.template { version description }
{
  description: "Production infrastructure stack"
  version: "2010-09-09"
}

List all resources

cnspec> cloudformation.template.resources
resources: [
  0: name="WebServer"
     in template.yaml:18-22
     18:    WebServer:
     19:      Type: AWS::EC2::Instance
     20:      Properties:
     21:        InstanceType: t3.micro
     22:        ImageId: ami-0abcdef1234567890

  1: name="DataBucket"
     in template.yaml:23-28
     23:    DataBucket:
     24:      Type: AWS::S3::Bucket
     25:      Properties:
     26:        BucketName: my-data-bucket
     27:        VersioningConfiguration:
     28:          Status: Enabled

  ...
]

Retrieve resource details

cnspec> cloudformation.template.resources { name type properties }
resources: [
  0: {
    name: "WebServer"
    type: "AWS::EC2::Instance"
    properties: {
      InstanceType: "t3.micro"
      ImageId: "ami-0abcdef1234567890"
    }
  }
  ...
]

Filter resources by type

Find all S3 bucket resources:

cnspec> cloudformation.template.resources.where(type == "AWS::S3::Bucket") { name properties }
resources.where: [
  0: {
    name: "DataBucket"
    properties: {
      BucketName: "my-data-bucket"
      VersioningConfiguration: {
        Status: "Enabled"
      }
    }
  }
]

List all resource types used in the template:

cnspec> cloudformation.template.types
types: [
  0: "AWS::EC2::Instance"
  1: "AWS::S3::Bucket"
  2: "AWS::IAM::Role"
  ...
]

Inspect template parameters

cnspec> cloudformation.template.parameters
parameters: {
  InstanceType: {
    Type: "String"
    Default: "t3.micro"
    AllowedValues: [
      0: "t3.micro"
      1: "t3.small"
      2: "t3.medium"
    ]
  }
  Environment: {
    Type: "String"
    Default: "production"
  }
  ...
}

List template outputs

cnspec> cloudformation.template.outputs { name properties }
outputs: [
  0: {
    name: "InstanceId"
    properties: {
      Description: "The instance ID"
      Value: {
        Ref: "WebServer"
      }
    }
  }
  ...
]

Retrieve conditions

cnspec> cloudformation.template.conditions
conditions: {
  IsProduction: {
    Fn::Equals: [
      0: {
        Ref: "Environment"
      }
      1: "production"
    ]
  }
  ...
}

Retrieve mappings

cnspec> cloudformation.template.mappings
mappings: {
  RegionMap: {
    us-east-1: {
      AMI: "ami-0abcdef1234567890"
    }
    us-west-2: {
      AMI: "ami-0fedcba9876543210"
    }
  }
  ...
}

Get full template details

cnspec> cloudformation.template { * }

Example security checks

Ensure EC2 instances don't use a hardcoded AMI

cloudformation.template.resources.where(type == "AWS::EC2::Instance").all(
  properties["ImageId"] != /^ami-/
)

Check that no security groups allow unrestricted SSH

cloudformation.template.resources.where(type == "AWS::EC2::SecurityGroup") {
  name
  properties["SecurityGroupIngress"]
}

Learn more

On this page