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:
- cnspec installed on your workstation
- CloudFormation template files (
.yamlor.json) to scan
Scan a CloudFormation template
Scan a single template file:
cnspec scan cloudformation template.yamlcnspec automatically detects whether the template is YAML or JSON.
Scan options
| Option | Description |
|---|---|
--asset-name | Override the asset name |
--annotation | Add an annotation to the asset (key=value) |
--incognito | Run in incognito mode (do not report results to Mondoo Platform) |
-o, --output | Set the output format (compact, full, json, junit, summary, yaml) |
-f, --policy-bundle | Path to a policy file (local path, s3:// URI, or http(s):// URL) |
--policy | Specify policies to execute (requires --policy-bundle) |
--risk-threshold | Exit 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
-
For the full MQL resource reference, see the MQL CloudFormation provider documentation.
-
To learn more about how the MQL query language works, read Write Effective MQL.