Terraform
Test Sentinel policies
You can test your Sentinel policies using the built-in testing suite to check your policies against all scenarios and edge cases. Testing gives you confidence in your policy and ensures predictable run outcomes when HCP Terraform enforces your policies during Terraform operations.
Prerequisites
For this tutorial, you will need:
Clone example Terraform configuration
In your terminal, clone the example code repository. This repository contains an example Sentinel policy and mock data.
$ git clone https://github.com/hashicorp-education/learn-sentinel-write-policy
Navigate to the directory.
$ cd learn-sentinel-write-policy
Review Sentinel policy
Open the restrict-aws-instances-type-and-tag.sentinel file, which contains
the Sentinel policy.
This Sentinel policy defines a main rule that consists of two other rules defining infrastructure requirements:
- The
mandatory_instance_tagsrule checks that all EC2 instances have aNametag. - The
instance_types_allowedrule checks that EC2 instances are of typet2.micro,t2.small, ort2.medium.
If your new or modified EC2 instances do not meet all of these criteria, Sentinel will flag the
run with a FAIL.
Create passing mock data
The configuration in this repository contains pre-generated Sentinel mock data from a Terraform plan run that satisfies the policy defined. You will use this data as the base for your passing and failing Sentinel test cases.
Copy your known passing mock data to a new file with pass in the filename.
$ cp mock-tfplan-v2.sentinel mock-tfplan-pass-v2.sentinel
Write a passing test case
Sentinel requires that your folder structure
match test/<policy>/*.json, where <policy> is the name of your policy file
without the file extension.
Create a new folder named test with a subdirectory named
restrict-aws-instances-type-and-tag.
$ mkdir -p test/restrict-aws-instances-type-and-tag
Navigate to the subdirectory.
$ cd test/restrict-aws-instances-type-and-tag
Create a new file named pass.hcl, then add the following configuration to the
file.
pass.hcl
mock "tfplan/v2" {
module {
source = "../../mock-tfplan-pass-v2.sentinel"
}
}
test {
rules = {
main = true
}
}
This passing test case uses the passing mock data and expects both the
instance_type_allowed and mandatory_instance_tags rules to pass.
Create failing mock data
To write a failing test case, you need to create a mock import data file with values outside your criteria, to simulate infrastructure that does not comply with the policy.
Change into your root learn-sentinel-write-policy directory.
$ cd ../..
Copy the mock-tfplan-v2.sentinel file to a new file with "fail" in the filename.
$ cp mock-tfplan-v2.sentinel mock-tfplan-fail-v2.sentinel
Open the failing mock data file in your text editor and look for the
resource_changes collection.
In the resource_changes.aws_instance.ubuntu.change.after block, change:
instance_typetot2.large, andtagsfromNametoNumber.
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",
},
## ...
},
}
}
}
Write a failing test case
Change back into your test/restrict-aws-instances-type-and-tag directory.
$ cd test/restrict-aws-instances-type-and-tag
Create a new file named fail.hcl, then add the following configuration to the file.
This configuration references the failing mock data and asserts that it should fail the policy.
fail.hcl
mock "tfplan/v2" {
module {
source = "../../mock-tfplan-fail-v2.sentinel"
}
}
test {
rules = {
main = false
}
}
Test your policy in the Sentinel CLI
Change into your root learn-sentinel-policies directory.
$ cd ../..
Now use the test command to run the test cases you defined for your policy.
Sentinel automatically loads the test cases in the /test directory and passes the
subdirectory that matches the policy name to the test command.
$ 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
Both your passing and failing tests return PASS because both test
cases evaluated to their expected values — the passing scenario evaluated to
true and the failing scenario evaluated to false.
Run the test with the -verbose flag to get more information about the test.
$ 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
The -verbose flag returns the steps at which each test passes or fails your criteria.
Next steps
You created test policies and ran test cases using the Sentinel CLI. To learn more about Sentinel, review the following resources:
- Learn how to Generate Mock Policy Data
- Review how to Write a Sentinel Policy
- Learn how to Upload a Sentinel Policy Set to HCP Terraform