

# 使用 `cloudformation-validate` 验证模板
<a name="cloudformation-validate"></a>

Amazon CloudFormation 验证（`cloudformation-validate`）可帮助您在部署之前发现模板问题。它会在本地检查 JSON 和 YAML 模板，识别无效的模板结构、损坏的引用、安全问题以及最佳实践问题。每项调查发现都包括稳定的规则 ID、严重性、模板中的行和列、受影响的资源，以及建议的修复（如果有）。

该工具包括所需的规则和 CloudFormation 资源架构。因此，在安装完成后，它无需网络访问或 Amazon 凭证即可运行。验证一个典型模板所需的时间不到一秒。您既可以通过命令行运行验证，也可以将其嵌入到 Rust、Node.js、Python、Go 或 JVM 应用程序中。您也可以让 Amazon CDK 在合成之后运行它。所有这些方法产生的结果都相同。

有关发布说明和内置规则的完整列表，请参阅 GitHub 上的 [`cloudformation-validate`](https://github.com/aws-cloudformation/cloudformation-validate)。

有关本地验证的限制以及部署前需采取的步骤，请参阅[了解验证范围](template-guide.md#template-validation-scope)。

**Topics**
+ [验证的工作原理](#cloudformation-validate-how-it-works)
+ [选择验证方法](#cloudformation-validate-ways-to-use)
+ [安装命令行工具](#cloudformation-validate-install)
+ [运行验证](#cloudformation-validate-run)
+ [了解结果](#cloudformation-validate-results)
+ [筛选结果](#cloudformation-validate-filter)
+ [添加自定义规则](#cloudformation-validate-custom-rules)
+ [验证新的资源类型和属性](#cloudformation-validate-additional-schemas)
+ [嵌入验证库](#cloudformation-validate-library)
+ [将 与 结合使用Amazon CDK](#cloudformation-validate-cdk)

## 验证的工作原理
<a name="cloudformation-validate-how-it-works"></a>

验证模板时，`cloudformation-validate` 会解析内置函数（例如 `Ref`、`Fn::GetAtt`、`Fn::Sub` 和 `Fn::If`），然后运行以下检查：
+ **架构检查**：将每个资源与 [CloudFormation 资源提供程序架构](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/resource-type-schemas.html)进行比较，并报告类型不匹配、缺失必需属性、枚举值无效以及模式或约束失败。
+ **规则**：运行内置规则和您提供的任何自定义规则。这些规则可以发现语义错误、损坏的跨资源引用、安全风险和最佳实践问题。
+ **状态机检查**：验证 `AWS::StepFunctions::StateMachine` 资源的定义，包括状态类型、`StartAt` 和 `Next` 引用以及必填字段。

## 选择验证方法
<a name="cloudformation-validate-ways-to-use"></a>
+ **命令行**：运行 `cfn-validate` 以从终端或自动构建检查一个模板或目录中的每个模板。请参阅[安装命令行工具](#cloudformation-validate-install)。
+ **库**：向 Rust、Node.js、Python、Go 或 JVM 应用程序添加验证器，然后在代码中处理结果。请参阅[嵌入验证库](#cloudformation-validate-library)。
+ **Amazon CDK**：在 Amazon CDK 合成模板后自动验证模板。请参阅[将 与 结合使用Amazon CDK](#cloudformation-validate-cdk)。

无论采用哪种方法，您都可以添加使用公共表达式语言（CEL）、Rego 或 Guard 规则语言编写的自定义规则。请参阅[添加自定义规则](#cloudformation-validate-custom-rules)。

## 安装命令行工具
<a name="cloudformation-validate-install"></a>

`cfn-validate` 命令是一个没有依赖项的单个文件。请在 GitHub 上打开[最新版本](https://github.com/aws-cloudformation/cloudformation-validate/releases/latest)，然后下载适用于您的操作系统和处理器的文件。文件适用于 Linux（x86-64 和 ARM64）、macOS（Apple silicon 和 Intel）以及 Windows（x86-64 和 ARM64）。

在 Linux 或 macOS 上，将文件设为可执行文件，将其重命名为 `cfn-validate`，然后将其移动到您的 `PATH` 中的目录。以下示例使用 Linux x86-64 文件。请将 {{VERSION}} 替换为您下载的版本。

```
chmod +x cfn-validate-{{VERSION}}-linux-x64
sudo mv cfn-validate-{{VERSION}}-linux-x64 /usr/local/bin/cfn-validate
```

在 Windows 上，将文件重命名为 `cfn-validate.exe`，然后将其移动到您的 `PATH` 中的目录。

每个版本还包括每次下载的签名文件以及用于对其进行签名的公有密钥。要在使用下载之前对其进行验证，请参阅 GitHub 上的 [Verify a downloaded release asset](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/INSTALLATION.md#verify-a-downloaded-release-asset)。

## 运行验证
<a name="cloudformation-validate-run"></a>

该命令使用以下语法：

```
cfn-validate {{TEMPLATE_OR_DIRECTORY}} [OPTIONS]
```

检查一个模板：

```
cfn-validate template.yaml
```

传递一个目录，以递归方式检查每个 `.yaml`、`.yml` 和 `.json` 文件：

```
cfn-validate ./templates/
```

某些检查取决于 Amazon Web Services 区域 或参数值。请使用 `--region` 设置 `AWS::Region` 伪参数，使用 `--parameter` 设置模板参数，使用 `--pseudo-parameter` 设置其他伪参数（例如 `AWS::AccountId` 或 `AWS::Partition`）。您可以重复 `--parameter` 和 `--pseudo-parameter`：

```
cfn-validate template.yaml --region us-west-2 --parameter Environment=prod --parameter InstanceType=t3.micro
```

要将警告视为错误（例如在自动化构建中），请添加`--strict`。要列出所有内置规则，请运行 `cfn-validate --list-rules`。

## 了解结果
<a name="cloudformation-validate-results"></a>

该命令将 JSON 报告写入标准输出。报告中的每项调查发现都包括规则 ID、严重性、消息、源位置（行和列）、资源或其他模板实体以及建议的修复（如果有）。默认 `--format detailed` 报告还包括规则描述和相关上下文。请使用 `--format standard` 生成省略这些字段的精简报告。

要将报告限制为更严重的调查发现，请使用 `--level` 并设置最低严重性以包括：

```
cfn-validate template.yaml --level error
```

该命令在未发现错误时会返回退出代码 `0`，在发现错误时会返回 `1`，在出现使用或初始化错误（例如无效选项或文件不存在）时会返回 `2`。使用 `--strict`，警告也会导致退出代码 `1`。

## 筛选结果
<a name="cloudformation-validate-filter"></a>

您可以按规则 ID、规则 ID 范围、类别、资源类型、服务前缀或模板实体的逻辑 ID 来包含或排除调查发现。每个筛选条件都有一个 `--include-` 和一个 `--exclude-` 形式。以下示例展示了常见的筛选条件：

```
# Suppress specific rules everywhere
cfn-validate template.yaml --exclude-ids {{RULE_ID}},{{RULE_ID}}

# Report only security findings
cfn-validate template.yaml --include-categories Security

# Suppress one rule for one resource only
cfn-validate template.yaml --exclude-logical-id MyBucket={{RULE_ID}}

# Suppress every rule for a resource type
cfn-validate template.yaml --exclude-resource-type AWS::EC2::Instance

# Suppress every rule for a service
cfn-validate template.yaml --exclude-service AWS::AutoScaling
```

以资源类型、服务或逻辑 ID 为目标的筛选条件接受可选 `={{RULE_ID}}` 后缀，将筛选条件限制为一条规则。如果没有后缀，则筛选条件将应用于该目标的每条规则。有关所有筛选条件选项，请参阅 GitHub 上的 [`cfn-validate` CLI 参考](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/src/cfn-validate/README.md)。

## 添加自定义规则
<a name="cloudformation-validate-custom-rules"></a>

您可以采用以下任一格式添加您自己的检查。每种格式都假设用户已基本了解其规则语言。默认情况下，除了内置规则外，还会运行自定义规则。要仅运行自定义规则，请添加 `--disable-builtin-rules`。
+ **CEL**（`.json`）：JSON 文件中以 [CEL](https://cel.dev/) 表达式编写的属性和数据驱动的检查。通过 `--rule-source` 加载。
+ **Rego**（`.rego`）：以 [Rego](https://www.openpolicyagent.org/docs/policy-language) 策略语言编写的复杂跨资源逻辑。通过 `--rule-source` 加载。
+ **Guard**（`.guard`）：Guard 规则语言中的声明式合规性规则。使用 `--guard-rule-source` 加载文件或目录。验证器支持部分 Guard 语言。如果规则使用了不受支持的构造，验证器会在加载该规则时将其拒绝，而不是忽略这些构造。有关规则语法，请参阅[使用 Guard 验证模板](cloudformation-guard.md)。

您可以重复任一选项以加载多个规则源：

```
cfn-validate template.yaml --rule-source ./rules/checks.json --rule-source ./rules/network.rego
cfn-validate template.yaml --guard-rule-source ./guard-rules/
```

`checks.json` 中的以下 CEL 示例会针对每个未加密的 Amazon S3 存储桶报告一项调查发现。`resource_type` 字段会使规则针对该类型的每个资源各运行一次，而消息中的 `{name}` 会被替换为资源的逻辑 ID。

```
{
  "rules": [
    {
      "rule_id": "CUSTOM001",
      "severity": "ERROR",
      "resource_type": "AWS::S3::Bucket",
      "expression": "!has(properties.BucketEncryption)",
      "message": "S3 bucket {name} must have encryption configured",
      "prop_path": "Properties.BucketEncryption",
      "suggested_fix": "Add BucketEncryption with SSEAlgorithm: aws:kms"
    }
  ]
}
```

有关规则可用数据、支持的 CEL 函数以及编写 Rego 规则的更多信息，请参阅 GitHub 上的[使用 Guard 验证模板](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/src/CUSTOM_RULES.md)。

## 验证新的资源类型和属性
<a name="cloudformation-validate-additional-schemas"></a>

捆绑的架构与发布时的 CloudFormation 注册表相匹配。如果某模板使用 CloudFormation 在该版本之后发布的资源类型、属性或允许的值，或者使用您自己的注册表中的私有资源类型，请使用 `--additional-schema` 传递资源提供程序架构。验证器使用它来扩展现有类型的捆绑架构，或对新类型进行验证。您可以传递一个 `.json` 文件或架构文件目录，然后重复以下选项：

```
cfn-validate template.yaml --additional-schema ./schemas/
```

附加架构永远不会移除捆绑的架构中的约束。如果无法读取或应用架构，则命令将退出并显示代码 `2`，而不是忽略它。

## 嵌入验证库
<a name="cloudformation-validate-library"></a>

安装适用于所用编程语言的程序包，以便从您的应用程序运行相同的离线检查。创建一次验证引擎，将其重复用于多个模板，然后处理针对每个模板返回的结构化诊断。您还可以通过库 API 配置自定义 CEL、Rego 或 Guard 规则以及其他架构。


| 语言 | 程序包 | 安装 | 文档 | 
| --- | --- | --- | --- | 
| Rust | [`cloudformation-validate`](https://crates.io/crates/cloudformation-validate)crates.io 上的 | cargo add cloudformation-validate | [API 和示例](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/src/bindings-rust/README.md) | 
| Node.js | [`@aws/cloudformation-validate`](https://www.npmjs.com/package/@aws/cloudformation-validate)npm 上的 | npm install @aws/cloudformation-validate | [API 和示例](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/src/bindings-wasm/README.md) | 
| Python | [`cloudformation-validate`](https://pypi.org/project/cloudformation-validate/)PyPI 上的 | python3 -m pip install cloudformation-validate | [API 和示例](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/src/bindings-python/README.md) | 
| Go | pkg.go.dev 上的 [`cloudformation-validate/src/bindings-go/go`](https://pkg.go.dev/github.com/aws-cloudformation/cloudformation-validate/src/bindings-go/go) | go get github.com/aws-cloudformation/cloudformation-validate/src/bindings-go/go@latest | [API 和示例](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/src/bindings-go/README.md) | 
| JVM（Java 或 Kotlin） | [`software.amazon.cloudformation:cloudformation-validate`](https://central.sonatype.com/artifact/software.amazon.cloudformation/cloudformation-validate)Maven Central 上的 | implementation("software.amazon.cloudformation:cloudformation-validate:{{VERSION}}")（Gradle）或等效的 Maven 依赖项 | [API 和示例](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/src/bindings-jvm/README.md) | 

每个库都公开了一种方法来验证模板并返回具有与命令行工具相同的诊断结果的报告。以下示例使用默认引擎 `CompositeEngine`，它运行内置规则和您配置的任何自定义 CEL、Rego 或 Guard 规则。每个示例都会验证一个模板并输出每个调查发现。

Python：

```
from cloudformation_validate import CompositeEngine

engine = CompositeEngine()
report = engine.validate_template("template.yaml")
for d in report.diagnostics:
    print(f"[{d.severity.name}] {d.rule_id}: {d.message}")
```

Kotlin：

```
import software.amazon.cloudformation.validate.CompositeEngine
import java.io.File

fun main() {
    val engine = CompositeEngine()
    val report = engine.validateTemplate(File("template.yaml"))
    for (d in report.diagnostics) {
        println("[${d.severity}] ${d.ruleId}: ${d.message}")
    }
}
```

有关支持的语言运行时、版本固定、预发布渠道以及 Maven 和 Gradle 语法，请参阅 GitHub 上的[语言绑定安装指南](https://github.com/aws-cloudformation/cloudformation-validate/blob/main/INSTALLATION.md#language-bindings)。有关每种语言的 API 参考和完整示例，请参阅 GitHub 上的 [Embedding as a library](https://github.com/aws-cloudformation/cloudformation-validate#embedding-as-a-library)。

## 将 与 结合使用Amazon CDK
<a name="cloudformation-validate-cdk"></a>

如果您使用 Amazon CDK，则无需单独安装验证器。Amazon CDK 构造库包含一个默认 `CloudFormationValidatePlugin`，其会在合成 CloudFormation 模板后自动运行相同的检查。

```
cdk synth
```

Amazon CDK 会在其验证结果中报告可能的部署失败和最佳实践调查发现。当您想要添加自定义 Rego 或 Guard 规则时，可以显式配置 `CloudFormationValidatePlugin`。

有关插件配置、确认和验证报告，请参阅《Amazon CDK API 参考》**中的 [Template and Policy Validation](https://docs.amazonaws.cn/cdk/api/v2/docs/aws-cdk-lib-readme.html#template-and-policy-validation)。