DEV Community

quixoticmonk
quixoticmonk

Posted on

Simplifying Policy Management in HCP Terraform with the Policysets Module

As organizations scale their infrastructure with Terraform, policy management becomes increasingly important. Whether you're enforcing security standards, compliance requirements, or operational best practices, having a streamlined way to manage and deploy policies is essential.

HashiCorp and AWS have worked on publishing some pre-built sentinel policies for AWS provider which you can find below:

I recently faced a challenge: I needed to import locally available Sentinel and OPA policies to HCP Terraform, as well as policies available in public GitHub repositories. After exploring various approaches, I decided to create a reusable Terraform module to solve this problem once and for all. As with most of these modules or utilities, I start off with something I have come across and post them out as public if I think others might benefit. I understand you can do this via a VCS connection with your repository ( requires a GitHub app connection) or a forked repository of a public policyset. And I do remember some sentinel based ones available across the HashiCorp repositories, but they didn't cover the OPA ones.

Introducing the Policysets Module

The result of this effort is a Terraform module that makes it easy to import and manage policy sets in HCP Terraform. The module is now available in the Terraform Registry at quixoticmonk/policysets.

Key Features

  • Multiple Policy Sources: Import policies from local directories or public Git repositories
  • Framework Support: Works with both Sentinel and OPA policy frameworks
  • Flexible Targeting: Apply policies globally or to specific workspaces
  • Configurable Settings: Customize policy evaluation settings to match your requirements

How to Use the Module

Let's walk through some common scenarios for using this module.

Scenario 1: Importing Local Sentinel Policies

If you have Sentinel policies in a local directory that you want to apply to all workspaces in your organization:

module "sentinel_policy_set" {
  source  = "quixoticmonk/policysets/tfe"

  name         = "my-sentinel-policies"
  description  = "Sentinel policies for cost control"
  organization = "my-organization"
  policy_kind  = "sentinel"

  policy_source      = "local"
  local_policies_path = "${path.module}/policies"

  # Apply globally to all workspaces
  global = true
}
Enter fullscreen mode Exit fullscreen mode

Make sure your local policies directory has the proper structure, including a sentinel.hcl file that defines the policy sets.

Scenario 2: Importing Local OPA Policies

For OPA policies stored locally that you want to apply to specific workspaces:

module "opa_policy_set" {
  source  = "quixoticmonk/policysets/tfe"

  name         = "my-opa-policies"
  description  = "OPA policies for compliance"
  organization = "my-organization"
  policy_kind  = "opa"

  policy_source       = "local"
  local_policies_path = "${path.module}/policies"

  workspace_ids = ["ws-v93RUQTMfJxoX18s"]
}
Enter fullscreen mode Exit fullscreen mode

Your OPA policies directory should include a policies.hcl file that defines the policy configuration.

Scenario 3: Importing Policies from a Public GitHub Repository

If you want to use policies from a public GitHub repository:

module "policy_set" {
  source  = "quixoticmonk/policysets/tfe"
  version = "latest"

  name              = "cis-policies"
  description       = "Sentinel policies supporting CIS framework"
  organization      = "my-organization"
  policy_kind       = "sentinel"
  policy_source     = "git"
  git_url           = "https://github.com/quixoticmonk/policy-library-CIS-Policy-Set-for-AWS-Terraform.git"
  git_branch        = "main"
  git_policies_path = "./"

  # Apply globally to all workspaces
  global = true
}
Enter fullscreen mode Exit fullscreen mode

Notes

  • When using the git source option, the module will clone the repository to a temporary directory within the module. Make sure the Git command-line tool is available in your environment.
  • For the local source option, the specified directory must exist and contain valid policy files.
  • The global and workspace_ids options are mutually exclusive - you can either apply policies globally or to specific workspaces. This forced me to have two different policysets based on the scope of the policies.
  • When using policy_kind = "opa":
    • The agent_enabled parameter is always set to true, regardless of the input value
    • The overridable parameter is only valid for OPA policies and ignored for Sentinel policies
  • policy_tool_version was another input which had to be reviewed since the only common default which could be used was latest. I preferred a single input than two different inputs for opa or sentinel and then enforcing rules on top of it.

Module Requirements

  • Terraform >= 1.0.0
  • TFE Provider >= 0.40.0

Getting Started

To get started with this module:

  1. Add the module to your Terraform configuration as shown in the examples above
  2. Configure your HCP Terraform provider with appropriate credentials
    • TFE_TOKEN as an environment variable with permissions to create policysets
  3. Run terraform init to download the module
  4. Run terraform plan to see what changes will be made
  5. Run terraform apply to create the policy set in your HCP Terraform organization

What's Next

For the git based path, I want to consider if a curl or wget equivalent is better than expecting git being available in every machine this module is run on.

Conclusion

Managing policies at scale doesn't have to be complicated. With this module, you can easily import and manage policies from various sources, ensuring consistent governance across your Terraform deployments.

The module is open source and available on the Terraform Registry. I welcome feedback, issues, and contributions to make it even better!

Check out the full documentation and source code at quixoticmonk/policysets/tfe to get started.

Top comments (0)