Dealing with aliased providers in Hashicorp Sentinel

In my line of work, I frequently end up helping customers who are running into issues with implementing Hashicorp Sentinel policies.

It's a “policy as code” product that ties in nicely with the Infrastructure as Code nature of Terraform. For additional information around the philosophical approach behind Sentinel and the advantages it confers, I recommend seeing this post from one of Hashicorp's founders, Armon Dadgar:

https://www.hashicorp.com/resources/introduction-sentinel-compliance-policy-as-code

Sentinel is being revised very rapidly and is a paid product, so finding code examples that both actually work and are current can be very tricky. One of the best places to start is this repository of example Sentinel policies(and helper functions) for various cloud providers:

https://github.com/hashicorp/terraform-guides/tree/master/governance/third-generation

Though Hashicorp literature states “Sentinel is meant to be a very high-level easy to learn programming language”, it isn't easy, particularly if you aren't familiar with the general syntax of go. The difficulty extends outside the realm of the syntax to the actual way that troubleshooting is implemented, and the lack of IDE tooling (outside of a VSCode syntax highlighter). Debugging is chiefly a matter of using print and then running the sentinel binary with the trace flag, as error messages are often quite opaque.

For example, say you're creating a policy that is meant to check for tags, and you unexpectedly run into a situation where undefined is being returned where it's not being expected. This is typically the result of unexpected provider configuration, such as the addition of aliases.

Analyzing this can require a mixture of tfplan, tfconfig, and even tfstate if data sources therein don't contain computed values. Understanding computed values is critical to effectively writing Sentinel code- a lot of resources have values that aren't known until after an apply is performed. Because Sentinel runs occur between the plan and apply phases, it's not possible for a policy to effectively operate against such values. If your Sentinel mocks contain unknown for 'after' the value is likely computed.

If you're using the helper functions from the linked Hashicorp repository, these will often require some combination of all three imports.

At present, the only way to iterate over provider aliases is to use tfconfig.providers, which returns a JSON object containing specified providers.