Fast, offline, embeddable validation for AWS CloudFormation templates.
cloudformation-validate parses a CloudFormation template (JSON or YAML) and returns structured diagnostics - schema
violations, semantic errors, security concerns, and best-practice suggestions - before you deploy. It runs entirely
offline: every rule and resource schema is compiled into the binary, so there is no network access, no credentials, and
no runtime fetching.
It ships as a Rust CLI, an embeddable Rust library, a Node.js package (WASM), a Python package, a Go module, and a JVM library (Kotlin/Java) - all backed by the same validation core.
- Offline-first. Rules and AWS resource schemas are baked into the binary. Nothing is fetched at runtime.
- Structured diagnostics. Every finding carries a stable rule ID, severity, precise source span (line/column), resource path, and an optional suggested fix - designed for IDEs, CI, and agents, not just humans.
- Two interchangeable engines. A Rego engine and a CEL engine evaluate the same rule set and produce identical results.
- Additional schemas. Merge your own CloudFormation resource provider schemas on top of the bundled ones, so
templates using properties or values CloudFormation has not published yet validate cleanly
(
--additional-schema, orEngineConfig.schema_validator_config.additional_schemaswhen embedding). - Custom rules. Extend validation with your own rules in CEL (JSON), Rego, or CloudFormation Guard DSL.
- Embeddable everywhere. Use it from the CLI, Rust, Node.js, Python, Go, or the JVM.
- Sub-second validation for typical templates.
When a template is submitted, cloudformation-validate runs a fixed pipeline:
- Parse - read JSON/YAML, resolve intrinsic functions (
Ref,Fn::GetAtt,Fn::Sub,Fn::If, …), build a reference graph with cycle detection, and model conditions with a SAT solver, producing a semantic model. - Schema validate - check each resource against the compiled CloudFormation provider schemas, producing Fatal-severity diagnostics for structural violations (type mismatches, missing required properties, invalid enums, pattern and constraint failures).
- Evaluate rules - the selected engine (Rego or CEL) evaluates lint rules against the semantic model, producing Error/Warning/Info diagnostics for semantic issues, cross-resource references, security risks, and best practices.
- Validate Step Functions - check
AWS::StepFunctions::StateMachinedefinitions (state types,StartAt/Nextreferences, required fields). - Enrich, filter, report - attach rule descriptions and context, apply include/exclude filters and severity gating, sort by source location, deduplicate, and assemble a structured JSON report.
Use a prebuilt CLI or install a published language binding; Rust and this source repository are not required.
| Interface | Published artifact | Install |
|---|---|---|
| CLI | GitHub Releases | Download the newest binary for Linux, macOS, or Windows |
| Node.js | npm: @aws/cloudformation-validate |
npm install @aws/cloudformation-validate |
| Python | PyPI / TestPyPI beta | python3 -m pip install cloudformation-validate |
| Go | Go module | go get github.com/aws-cloudformation/cloudformation-validate/src/bindings-go/go@latest |
| JVM | Maven Central: software.amazon.cloudformation:cloudformation-validate |
implementation("software.amazon.cloudformation:cloudformation-validate:latest.release") |
See INSTALLATION.md for platform-specific CLI download instructions, runtime requirements, prerelease channels, version pinning, Maven syntax, and release signature verification.
# Validate a single template
cargo run -p cfn-validate -- template.yaml
# Validate every template in a directory (recurses, picks up .yaml/.yml/.json)
cargo run -p cfn-validate -- ./templates/
# Use the CEL engine instead of the default Rego engine
cargo run -p cfn-validate -- template.yaml --engine cel
# Compact output for IDEs/CI
cargo run -p cfn-validate -- template.yaml --format standard
# Only report errors and above
cargo run -p cfn-validate -- template.yaml --level error
# List every available rule and exit
cargo run -p cfn-validate -- --list-rules
# Load custom Guard rules
cargo run -p cfn-validate -- template.yaml --guard-rule-source ./my-rules/Construct an engine and a schema validator once, then validate many templates:
use rego_engine::RegoEngine;
use schema_validator::SchemaValidator;
use validation_engine::{validate_bytes_with_path, EngineConfig, ValidateConfig};
let schema_validator = SchemaValidator::default();
let engine = RegoEngine::new(EngineConfig::default())?;
let bytes = std::fs::read("template.yaml") ?;
let report = validate_bytes_with_path(
& engine,
& schema_validator,
& bytes,
ValidateConfig::default (),
"template.yaml".to_string(),
) ?;
for d in & report.diagnostics {
println!("[{}] {} - {}", d.severity, d.rule_id, d.message);
}See validation-engine/API.md for the full embedding API.
Node.js (bindings-wasm)
import {RegoEngine, TemplateFile} from "@aws/cloudformation-validate";
const engine = new RegoEngine();
const report = engine.validateStandard(new TemplateFile("template.yaml"));
for (const d of report.diagnostics) {
console.log(`[${d.severity}] ${d.ruleId}: ${d.message}`);
}
engine.free();Python (bindings-python)
from cloudformation_validate import RegoEngine
engine = RegoEngine()
report = engine.validate_standard("template.yaml")
for d in report.diagnostics:
print(f"[{d.severity.name}] {d.rule_id}: {d.message}")import cfnvalidate "github.com/aws-cloudformation/cloudformation-validate/src/bindings-go/go"
engine, err := cfnvalidate.NewRegoEngine(nil)
if err != nil {
log.Fatal(err)
}
defer engine.Destroy()
report, err := engine.ValidateStandardFile("template.yaml", nil)
for _, d := range report.Diagnostics {
fmt.Printf("[%s] %s: %s\n", d.Severity, d.RuleID, d.Message)
}JVM Java/Kotlin (bindings-jvm)
import software.amazon.cloudformation.validate.*
import java.io.File
val engine = RegoEngine()
val report = engine.validateStandard(File("template.yaml"))
for (d in report.diagnostics) {
println("[${d.severity}] ${d.ruleId}: ${d.message}")
}Bring your own rules in any of three formats - all loadable from the CLI and the library:
- CEL (
.json) - property and data-driven checks, evaluated by the CEL engine. - Rego (
.rego) - complex cross-resource logic, evaluated by the Rego engine. - Guard DSL (
.guard) - declarative compliance rules, translated automatically and usable with either engine.
See RULES and CUSTOM_RULES.md for the formats, available context, and examples.
This is a Cargo workspace. The main crates:
| Crate | Role |
|---|---|
| cfn-validate | cfn-validate CLI |
| validation-engine | ValidationEngine trait, orchestration pipeline, Step Functions validation |
| template-model | Template parser, intrinsic resolver, condition SAT solver, reference graph |
| rules | Rule registry, severity model, categories, and diagnostic filtering |
| diagnostics | Shared reporting types: Diagnostic, ValidationReport, metrics |
| schema-validator | JSON Schema validation against compiled CloudFormation provider schemas |
| rego-engine | Rego-based rule evaluation with custom builtins |
| cel-engine | Native Rust rules plus a CEL interpreter for custom rules |
| guard-translator | Parses Guard DSL into an engine-agnostic intermediate representation |
| data-source | Build-time pipeline: downloads and processes CloudFormation schemas, generates the validation artifacts baked into the binary |
If you discover a potential security issue, please do not open a public GitHub issue. Report it privately through AWS Vulnerability Reporting instead.
Licensed under the Apache License 2.0. See NOTICE for attributions and THIRD-PARTY-LICENSES.txt for third-party license details.