Sentinel and Terraform Enterprise: Applying policy as code to infrastructure provisioning

Infrastructure as code with HashiCorp Terraform enables operators to automate provisioning at scale. This comes with risks, as every action can have larger effects. Sentinel policy as code places guardrails to protect users from creating infrastructure changes that fall outside of business and/or regulatory policies. Example constraints might include:

  • Not allowing resources to be provisioned without tags
  • Not allowing “development” resources to be provisioned in “us-east-1”
  • Restricting AWS security group ingress and egress settings by CIDR block
  • Not allowing resources to be provisioned outside of business hours

Manual enforcement of these constraints becomes increasingly difficult as the demand for infrastructure provisioning grows. Providing policy as code allows these types of constraints to be codified and automated with Sentinel in Terraform Enterprise.

»Sentinel

Sentinel is HashiCorp's language and framework for embedding policy as code into existing software, enabling fine-grained, logic-based policy decisions. A policy describes under what circumstances certain behaviors are allowed. Sentinel is embedded into the Enterprise version of each of HashiCorp's products including Terraform, Vault, Consul, and Nomad. More details are in the Announcing Sentinel, HashiCorp’s Policy as Code Framework blog.

»Terraform Enterprise and policy as code management

Terraform Enterprise provides a safe workflow for modifying infrastructure by first planning the changes to be made and then applying them if confirmed. Sentinel adds a new step to this process between the plan and apply, where any configured policies will be enforced. Terraform’s plan, configuration, and state data is made available to Sentinel through the tfplan plugin, enabling policy enforcements based on proposed changes to the infrastructure.

»Configuring a policy

Sentinel policies are configured on an organization and are applied to all runs on all workspaces within that organization. This is useful for defining organization-wide policies, such as “Disallow wide-open AWS Security Group Ingress”. Policies will also be configurable directly on workspaces in the future, which is a more suitable place to configure environment-specific policies such as “Development environments cannot have more than two app instances”. Policy code is entered into Terraform Enterprise using the API or the web UI, and will soon support VCS integration. The screenshot below shows entering an organization policy in the web UI:

Organization policy

All policies in Terraform Enterprise have a few configurable attributes:

Policy Name is a simple string used to identify Sentinel policies in Sentinel’s output. This is a detail required for entering policies in the UI or API.

Enforcement mode determines what happens in policy failure scenarios. There are 3 levels to choose from:

  • Advisory mode logs warnings, but does not prevent runs from being applied. This is useful for teaching users good habits without preventing actions.
  • Soft mandatory mode requires an operator with appropriate permissions to override any policy failures prior to an apply. This is useful for policies like "Users cannot provision outside of business hours", which require a failsafe.
  • Hard mandatory mode does not allow any override, and policies must pass prior to an apply. This is useful for policies that enforce regulatory requirements like "All database volumes must be encrypted."

Policy code is where the Sentinel policy is entered. Detailed syntax documentation and examples are available at https://docs.hashicorp.com/sentinel.

»Writing policies in Terraform Enterprise

Sentinel has a pluggable architecture which allows the core language to be extended for each product it is embedded into. The following policy uses the tfplan plugin to check that all AWS security groups do not allow wide-open ingress:

import "tfplan"

disallowed_cidr_blocks = [
  "0.0.0.0/0",
]

main = rule {
  all tfplan.resources.aws_security_group as _, instances {
    all instances as _, sg {
      all sg.applied.ingress as ingress {
        all disallowed_cidr_blocks as block {
          ingress.cidr_blocks not contains block
        }
      }
    }
  }
}

As you can see, the “tfplan” plugin is imported, and then used to access the set of Terraform resources we are interested in (in this case, AWS security groups). The found resources are then iterated upon and each resource’s applied value is tested against the disallowed_cidr_blocks. The applied resource represents what the value would be, if the plan were applied. This is useful for checking proposed changes to the infrastructure.

All Terraform resource and module attributes are available for use within policies. Terraform plans also contain the full state and config data, which are both also available through the “tfplan” plugin.

»Policy Enforcement

Sentinel policies in Terraform Enterprise are enforced immediately after a plan completes. This is reflected on the Runs view page. The “Policy Check” section will appear when the plan completes, if policies are present:

Policy Enforcement

The “cidr-blocks” policy has failed in the above example. The plan output above shows that the Terraform configuration contains a security group with ingress allowed from “0.0.0.0/0”, which is expressly denied in our Sentinel policy. In this case, the enforcement mode for the policy was set to soft-mandatory, which allows an organization owner to bypass the policy failure for exceptional circumstances. Overriding the policy puts the run into position to be confirmed and applied, which can be done by a workspace owner or an organization owner. A comment box allows the organization owner to comment on why the policy is being overridden. After overriding a policy, the prompt on the run page will look like this:

Enforce Policy

In advisory enforcement mode, the failure would look very similar, only no intervention by the organization owner would be necessary to confirm and apply the plan. The “Confirm & Apply” button would appear normally, as shown below:

Advisory Enforce Policy

In hard-mandatory enforcement mode, the policy check would not have any override option for any user. Modifications to the Terraform configuration or Sentinel policy would be required prior to being able to apply changes in this scenario, as shown below:

Hard Fail Enforce Policy

After adjusting the Terraform configuration to satisfy the policy requirements, the policy check should pass, as shown below:

Policy Check Pass

The workspace owner is able to confirm and apply a run that passes policy checks freely.

»Terraform Enterprise Demo

A demo of Terraform Enterprise Workspace management and Sentinel policy as code is shown below.

»Conclusion

Policy as code management is available as part of Terraform Enterprise. For more information on Terraform Enterprise or to get started with your free trial, visit the Terraform product page.

Sign up for the latest HashiCorp news

By submitting this form, you acknowledge and agree that HashiCorp will process your personal information in accordance with the Privacy Policy.