Terraform
测试 Sentinel 策略
您可以使用内置的测试套件来测试您的 Sentinel 策略,以检查您的策略是否适用于所有场景和边缘情况。测试让您对策略充满信心,并确保在 HCP Terraform 在 Terraform 操作期间执行您的策略时,结果可预测。
先决条件
对于本教程,您需要
- Sentinel CLI
- 一个 GitHub 帐户
克隆示例 Terraform 配置
在您的终端中,克隆 示例代码仓库。此仓库包含一个示例 Sentinel 策略和模拟数据。
$ git clone https://github.com/hashicorp-education/learn-sentinel-write-policy
导航到目录。
$ cd learn-sentinel-write-policy
查看 Sentinel 策略
打开 restrict-aws-instances-type-and-tag.sentinel 文件,其中包含 Sentinel 策略。
此 Sentinel 策略定义了一个 main 规则,该规则由两个其他规则组成,用于定义基础设施要求
mandatory_instance_tags规则检查所有 EC2 实例是否具有Name标签。instance_types_allowed规则检查 EC2 实例的类型是否为t2.micro、t2.small或t2.medium。
如果您的新的或修改后的 EC2 实例不满足所有这些条件,Sentinel 将用 FAIL 标记运行。
创建通过的模拟数据
此仓库中的配置包含从 Terraform 计划运行生成的预生成 Sentinel 模拟数据,这些数据满足定义的策略。您将使用此数据作为通过和失败的 Sentinel 测试用例的基础。
将您已知的通过的模拟数据复制到包含 pass 的文件名的新文件中。
$ cp mock-tfplan-v2.sentinel mock-tfplan-pass-v2.sentinel
编写通过的测试用例
Sentinel 要求您的文件夹结构与 test/<policy>/*.json 匹配,其中 <policy> 是您的策略文件名,不带文件扩展名。
创建一个名为 test 的新文件夹,并创建一个名为 restrict-aws-instances-type-and-tag 的子目录。
$ mkdir -p test/restrict-aws-instances-type-and-tag
导航到子目录。
$ cd test/restrict-aws-instances-type-and-tag
创建一个名为 pass.hcl 的新文件,然后将以下配置添加到该文件中。
pass.hcl
mock "tfplan/v2" {
module {
source = "../../mock-tfplan-pass-v2.sentinel"
}
}
test {
rules = {
main = true
}
}
此通过的测试用例使用通过的模拟数据,并期望 instance_type_allowed 和 mandatory_instance_tags 规则都通过。
创建失败的模拟数据
要编写失败的测试用例,您需要创建一个模拟导入数据文件,其中包含超出您标准的数值,以模拟不符合策略的 инфраструктура。
切换回您的根 learn-sentinel-write-policy 目录。
$ cd ../..
将 mock-tfplan-v2.sentinel 文件复制到包含“fail”的文件名的新文件中。
$ cp mock-tfplan-v2.sentinel mock-tfplan-fail-v2.sentinel
在文本编辑器中打开失败的模拟数据文件,并查找 resource_changes 集合。
在 resource_changes.aws_instance.ubuntu.change.after 块中,将
instance_type更改为t2.large,并且tags从Name更改为Number。
resource_changes = {
"aws_instance.ubuntu": {
"address": "aws_instance.ubuntu",
"change": {
"actions": [
"create",
],
"after": {
## ...
- "instance_type": "t2.micro",
+ "instance_type": "t2.large",
## ...
"tags": {
- "Name": "Provisioned by Terraform",
+ "Number": "Provisioned by Terraform",
},
## ...
},
}
}
}
编写失败的测试用例
切换回您的 test/restrict-aws-instances-type-and-tag 目录。
$ cd test/restrict-aws-instances-type-and-tag
创建一个名为 fail.hcl 的新文件,然后将以下配置添加到文件中。此配置引用了失败的模拟数据,并断言它应该使策略失败。
fail.hcl
mock "tfplan/v2" {
module {
source = "../../mock-tfplan-fail-v2.sentinel"
}
}
test {
rules = {
main = false
}
}
在 Sentinel CLI 中测试你的策略
切换到你的根 learn-sentinel-policies 目录。
$ cd ../..
现在使用 test 命令来运行你为策略定义的测试用例。Sentinel 会自动加载 /test 目录中的测试用例,并将与策略名称匹配的子目录传递给 test 命令。
$ sentinel test restrict-aws-instances-type-and-tag.sentinel
PASS - restrict-aws-instances-type-and-tag.sentinel
PASS - test/restrict-aws-instances-type-and-tag/fail.hcl
PASS - test/restrict-aws-instances-type-and-tag/pass.hcl
你的通过和失败的测试都返回 PASS,因为两个测试用例都评估为它们期望的值——通过场景评估为 true,而失败场景评估为 false。
使用 -verbose 标志运行测试,以获取有关测试的更多信息。
$ sentinel test -verbose restrict-aws-instances-type-and-tag.sentinel
Installing test modules for test/restrict-aws-instances-type-and-tag/fail.hcl
Installing test modules for test/restrict-aws-instances-type-and-tag/pass.hcl
PASS - restrict-aws-instances-type-and-tag.sentinel
PASS - test/restrict-aws-instances-type-and-tag/fail.hcl
trace:
restrict-aws-instances-type-and-tag.sentinel:39:1 - Rule "main"
Description:
Main rule that requires other rules to be true
Value:
false
restrict-aws-instances-type-and-tag.sentinel:32:1 - Rule "instance_type_allowed"
Description:
Rule to restrict instance types
Value:
false
PASS - test/restrict-aws-instances-type-and-tag/pass.hcl
trace:
restrict-aws-instances-type-and-tag.sentinel:39:1 - Rule "main"
Description:
Main rule that requires other rules to be true
Value:
true
restrict-aws-instances-type-and-tag.sentinel:32:1 - Rule "instance_type_allowed"
Description:
Rule to restrict instance types
Value:
true
restrict-aws-instances-type-and-tag.sentinel:23:1 - Rule "mandatory_instance_tags"
Description:
Rule to enforce "Name" tag on all instances
Value:
true
-verbose 标志会返回每个测试通过或失败标准的步骤。
下一步
你创建了测试策略并使用 Sentinel CLI 运行了测试用例。要了解有关 Sentinel 的更多信息,请查阅以下资源
- 了解如何 生成模拟策略数据
- 了解如何 编写 Sentinel 策略
- 了解如何 将 Sentinel 策略集上传到 HCP Terraform