Introduction
This guide is an example on how to utilize Sentinel policies to enforce the use of a list of allowed providers. This is example code on how to access the provider details from your Terraform config in Sentinel. Use it to get familiar with Sentinel policies but do not use it as is on a production environment.
What will you do?
- Clone a Hashicorp repository with example Sentinel policies and functions.
- Create a Sentinel policy that allows the use only of specific providers.
- Get the Sentinel mock files from your workspace on Terraform Enterprise/Cloud
- Test your policy locally using the Sentinel mock files.
Prerequisites
- This guide created and tested on MacOS, it should work with Linux also.
- Git installed and configured.
- Access to a Terraform Enterprise/Cloud workspace.
- Sentinel cli installed. See here how to install it.
Clone the Hashicorp Github repository with Sentinel policy examples
Clone the Hashicorp Github repository with Sentinel policy examples to use it as base for your own sentinel policies repository:
$ cd ~
$ git clone https://github.com/hashicorp/terraform-sentinel-policies
Change directory:
$ cd terraform-sentinel-policies
Create a new directory for your policies:
$ mkdir my-test-policies
Copy the allowed providers policy in your directory to start creating your policy:
$ cp cloud-agnostic/allowed-providers.sentinel my-test-policies/my-allowed-providers.sentinel
Get Sentinel mock files
When you run terraform code on a Terraform Enterprise/Cloud workspace sentinel mock files are created. You can use them to test your Sentinel policies.
Visit your Terraform Enterprise/Cloud, go to your workspace that you have the code you want to test and start a run.
When the terraform plan finishes:
- Click Download Sentinel mocks.
Then you can discard the run.
- Click Discard run.
The sentinel mocks file has a name similar to this:
run-2LrpdkN5Zz5c8ZFJ-sentinel-mocks.tar.gz
Unzip the sentinel mock files in the same directory as your sentinel policies. The guide assumes that the sentinel mock file was downloaded in your Downloads folder and that you cloned the Sentinel policies git repository in your home folder.
tar -zxvf ~/Downloads/run-2LrpdkN5Zz5c8ZFJ-sentinel-mocks.tar.gz -C ~/terraform-sentinel-policies/my-test-policies
output:
x mock-tfconfig-v2.sentinel
x mock-tfconfig.sentinel
x mock-tfplan-v2.sentinel
x mock-tfplan.sentinel
x mock-tfstate-v2.sentinel
x mock-tfstate.sentinel
x sentinel.hcl
x mock-tfrun.sentinel
Check the files in your my-test-policies directory
ls -l1 ~/terraform-sentinel-policies/my-test-policies
output:
my-allowed-providers.sentinel
mock-tfconfig-v2.sentinel
mock-tfconfig.sentinel
mock-tfplan-v2.sentinel
mock-tfplan.sentinel
mock-tfrun.sentinel
mock-tfstate-v2.sentinel
mock-tfstate.sentinel
sentinel.hcl
Edit the sentinel.hcl file:
vim ~/terraform-sentinel-policies/my-test-policies/sentinel.hcl
Append in the bottom the following code:
#The repository you cloned contains some ready to use sentinel functions.
#The code block below allows you to use the tfconfig functions
# which exist in the common-functions directory
module "tfconfig-functions" {
source = "../common-functions/tfconfig-functions/tfconfig-functions.sentinel"
}
#The code block below sets your policy for allowed providers as hard mandatory
policy "my-allowed-providers" {
source = "./my-allowed-providers.sentinel"
enforcement_level = "hard-mandatory"
}
Save your sentinel.hcl file.
Test your policy against your code (sentinel mocks)
A brief explanation of the files that the my-test-policies directory contains.
- my-allowed-providers.sentinel: The file that contains your policy.
- mock-tfconfig-v2.sentinel: This is the file sentinel will use on this current example and is actually a representation of your terraform code (configuration) in the json format. You can use this file when you policy rules apply on the terraform code files.
- mock-tfconfig.sentinel: older version of mock-tfconfig-v2.sentinel file.
- mock-tfplan-v2.sentinel: you can use this file when your policy contains rules that check on values generated during a terraform plan.
- mock-tfplan.sentinel: older version of mock-tfplan-v2.sentinel file.
- mock-tfstate-v2.sentinel: you can use this file when your policy rules check on values based on the terraform state file.
- mock-tfstate.sentinel: older version of the mock-tfstate-v2.sentinel file.
- sentinel.hcl: this is a configuration file used to define and manage Sentinel policies. It allows you to configure the enforcement of Sentinel policies, determining how they are applied, and what behavior should be enforced when policies succeed or fail.
The example's my-allowed-providers.sentinel policy file contains a list of allowed providers as shown below:
...
# List of allowed providers
allowed_list = ["aws", "local", "null", "random", "terraform", "tfe"]
...
The example's mock-tfconfig-v2.sentinel file, in the providers block (which derives from the terraform code) contains the following terraform providers aws, azurerm, null and random. Notice that the azurerm provider is not in the allowed list. Let's test our policy locally.
Go to the directory with your terraform policy file and the mock files:
$ cd ~/terraform-sentinel-policies/my-test-policies
Use sentinel cli to test your policy:
$ sentinel apply my-allowed-providers.sentinel
output:
Configuration warnings detected.
Sentinel detected issues with your configuration that may be deprecated or
cause other issues when using the runtime. Please review the warnings above
and make any corrections if need be.
Execution trace. The information below will show the values of all
the rules evaluated. Note that some rules may be missing if
short-circuit logic was taken.
Note that for collection types and long strings, output may be
truncated; re-run "sentinel apply" with the -json flag to see the
full contents of these values.
The trace is displayed due to a failed policy.
Fail - my-allowed-providers.sentinel
Description:
This policy uses the tfconfig/v2 import to restrict providers to those
in an allowed list.
Print messages:
Provider azurerm has name with value azurerm that is not in the allowed list: [aws, local, null, random, terraform, tfe]
my-allowed-providers.sentinel:78:1 - Rule "main"
Value:
false
In the output we can see the policy failing and mentioning the issue, which is the azurerm provider and its absence of the allowed providers list.
Edit your my-allowed-providers.sentinel file and add azurerm in the allowed list. The new list should look like this:
...
# List of allowed providers
allowed_list = ["aws", "local", "null", "random", "terraform", "tfe", "azurerm"]
...
Save your changes.
Now test your policy again:
$ sentinel apply my-allowed-providers.sentinel
output:
Pass - my-allowed-providers.sentinel
Success, your terraform code used only allowed providers.
Review the links below to learn more about sentinel policies and how to use them on Terraform Enterprise/Cloud.
Additional information about Sentinel policies
- https://developer.hashicorp.com/terraform/cloud-docs/policy-enforcement/sentinel
- https://developer.hashicorp.com/terraform/tutorials/policy/sentinel-policy
- https://www.hashicorp.com/resources/writing-and-testing-sentinel-policies-for-terraform
- https://github.com/hashicorp/terraform-sentinel-policies
- https://developer.hashicorp.com/terraform/enterprise/policy-enforcement/sentinel/vcs