Cloud Compliance & Management with Terraform - Creating Simple Sentinel Policies

See Sentinel policy as code enforcement levels and policy sets in action with this Terraform Enterprise demo.


  • Corrigan Neralich
    Corrigan NeralichSolutions Engineer, HashiCorp


Hi. I'm Corrigan Neralich, a solutions engineer at HashiCorp. I'm here today to talk to you about policy enforcement within the Terraform Enterprise solution.

As we spoke about previously, the trend internally when adopting Terraform is to modularize. And we spoke to some of the challenges that arise when doing so, specifically, discoverability and consumption.

How do your users discover modules, and how do they then start to consume them as you look to move toward a self-service type of approach to infrastructure?

We spoke about the private module registry and your ability to present to your users a unified module catalog to take care of the challenge of discoverability.

We also talked about the built-in design configuration tool to aid with adoption and consumption by giving users a baked-in tool within the GUI to modify these modules so that they can consume them easily within their projects.

Invariably, the next question that gets asked is, How do we set up guardrails around this?

Within this new framework of self-serve infrastructure where many more individuals are potentially deploying resources to your various environments, how do we make sure that they're following proper protocols, they're doing this securely, they're doing this cost-consciously?

Security with Sentinel and policy as code

HashiCorp has developed a tool called Sentinel to help achieve this. Sentinel represents our policy-as-code tool, which sits atop all of our tools, including Terraform.

To walk you through what this might look like, let's hypothetically say you have created many modules for your users to consume. You start opening this up to more and more users, more and more business units internally.

But you want to make sure that they're only using pre-approved modules, modules that you have. as a team, collectively produced that incorporate best practice and that you've surfaced in your private module registry.

One example of how you might do this, just to quickly jump into version control, let's say you create a policy, and you define it to say, "I'm going to require that any module within any configuration requires the source of that module to be the private module registry," your specific registry.

There are a number of different components to the Sentinel code, pulling in all resources, combing through those resources to extract all module sources. And in the case on the screen, I've set my organization as my demo org.

What this means is, when this policy is evaluated, it's evaluating all of the code within a given workspace to determine whether or not all modules in that code came from a pre-approved module in your specific registry.

This is tremendously powerful, as it gives you the ability now to socialize this, to roll it out to more teams, but at the same time ensure that these team members are only using pre-approved code.

Levels of enforcement

You will probably develop policy sets, as we call them, because oftentimes you'll want to group policies together for different use cases—say, to apply to dev environments versus prod.

The way that you manage this is, you define each of these policies within its own specific file. You also have a corresponding file that we call a sentinel.hcl file. In this you can define a level of enforcement.

Is it just advisory? Is it more for awareness? Is it a soft mandatory policy, in which case you can allow administrators the ability to override policy failures if there is a legitimate reason for doing so? Or are you defining it as hard mandatory, meaning you want this enforced 100% of the time, in which case there is no override?

In my case, as you can see, I've defined a hard mandatory policy requiring all modules to be sourced from our own private module registry.

Let me jump into another example Terraform configuration file.

In this case, I am calling the module from my registry, but I've also included another module that has a different source, a separate GitHub repository.

In this case, within my Terraform Enterprise organization, I've created this policy set to require private modules pulled in from version control from those policies that I showed you earlier. And in this case, I've selected the workspaces that I want this policy to be applied to.

You can apply these globally, if you want these to be enforced 100% of the time across all workspaces, or selectively, so that you can pick and choose in which instances a given set of policies is applied and evaluated.

Sentinel's policy check will prevent unapproved modules being applied

In my case, coming back to this workspace that's tied to the repository that has that unapproved module, if I as a user attempt to deploy that underlying infrastructure, here's what I’m going to see.

As usual, I'll see the plan, providing the outputs of what Terraform intends to build, based on what's defined in those configuration files. This is when it might surface any syntax issues, dependency issues, issues with the code.

But the next component, once this is finished running, is going to be a policy check phase. In this case, because I have created a repository and I'm attempting to deploy code that has an unapproved module, this policy is going to be evaluated and will fail.

So the plan successfully finished, but the policy check results in a failure. This lets you know that all non-root modules must come from the private module registry. There's an informative error message letting the user know exactly what failed and why.

Again, this all happened proactively. Before anything was ever deployed, this check occurred to make sure that no unapproved code was ever being used to go manage infrastructure in your environments. And that's tremendously powerful.

More resources like this one