Supply Chain

Assess AWS CloudFormation Template Security with cnspec

Scan AWS CloudFormation templates for security misconfigurations using 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, letting you enforce security policies in pull requests and CI pipelines.

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, full, json, junit, 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)

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 }
cloudformation.template: {
  version: "2010-09-09"
  description: "Production infrastructure stack"
}

List all resources

cnspec> cloudformation.template.resources
cloudformation.template.resources: [
  0: cloudformation.resource type="AWS::EC2::Instance"
  1: cloudformation.resource type="AWS::S3::Bucket"
  ...
]

Retrieve resource details

cnspec> cloudformation.template.resources { name type properties }
cloudformation.template.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 }
cloudformation.template.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
cloudformation.template.types: [
  0: "AWS::EC2::Instance"
  1: "AWS::S3::Bucket"
  2: "AWS::IAM::Role"
  ...
]

Inspect template parameters

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

List template outputs

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

Retrieve conditions

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

Retrieve mappings

cnspec> cloudformation.template.mappings
cloudformation.template.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