Policy Enforcement with Open Policy Agent
Terrateam integrates with Open Policy Agent (OPA) and Conftest to provide powerful policy enforcement capabilities for your Terraform plans. By defining custom policies using the Rego query language, you can ensure that your Terraform configurations adhere to your organization’s standards, best practices, and compliance requirements.
What is Open Policy Agent (OPA)?
Section titled “What is Open Policy Agent (OPA)?”Open Policy Agent (OPA) is an open-source, general-purpose policy engine that enables unified policy enforcement across the stack. OPA provides a declarative language called Rego for defining policies and a runtime for evaluating those policies against structured data, such as JSON or YAML.
What is Conftest?
Section titled “What is Conftest?”Conftest is a utility that helps you write tests against structured configuration data, such as Terraform plans, Kubernetes manifests, or Serverless configurations. Conftest uses OPA’s Rego language to define policies and provides a command-line interface for testing your configurations against those policies.
Configuring Policy Enforcement
Section titled “Configuring Policy Enforcement”To enable policy enforcement with OPA and Conftest in Terrateam, you need to configure a workflow in your Terrateam configuration file (.terrateam/config.yml).
Here’s an example configuration that runs Conftest against the generated Terraform plan:
workflows: - tag_query: '' plan: - type: init - type: plan - type: conftestIn this configuration:
- The
initandplansteps generate the Terraform plan as usual. - The
confteststep automatically runs Conftest against the generated Terraform plan file using any policies found in the policy directory. - The Conftest output is automatically captured and included in the Terrateam plan results.
Defining Policies with Rego
Section titled “Defining Policies with Rego”Conftest policies are written using the Rego query language. Rego allows you to define rules and constraints that your Terraform configurations must satisfy.
Here’s an example Rego policy that denies the creation of any resources using the null_resource provider:
package mainresource_types = {"null_resource"}resources[resource_type] = all { some resource_type resource_types[resource_type] all := [name | name:= input.resource_changes[_] name.type == resource_type ]}num_creates[resource_type] = num { some resource_type resource_types[resource_type] all := resources[resource_type] creates := [res | res:= all[_]; res.change.actions[_] == "create"] num := count(creates)}deny[msg] { num_resources := num_creates["null_resource"] num_resources > 0 msg := "Resource 'null_resource' detected in Terraform plan file. Denied."}This policy defines a deny rule that generates an error message if the Terraform plan contains any null_resource creations.
Policy Directory Structure
Section titled “Policy Directory Structure”By default, Conftest looks for Rego policy files in the policy directory relative to the directory being processed by Terrateam.
For example, if a pull request contains a change for the file foo/bar/main.tf, Conftest will look for Rego policy files in the foo/bar/policy/ directory.
foo└── bar ├── main.tf └── policy└── main.regoYou can customize the policy directory by setting the CONFTEST_POLICY environment variable in your Terrateam workflow configuration.
Customizing Conftest Options
Section titled “Customizing Conftest Options”Conftest provides various configuration options that can be set using environment variables. You can find the full list of options here.
Specifying Conftest Version
Section titled “Specifying Conftest Version”You can specify a particular version of Conftest to use by setting the CONFTEST_VERSION environment variable. This is useful for ensuring consistent behavior across your team or for testing new Conftest features before upgrading globally.
workflows: - tag_query: '' plan: - type: env name: CONFTEST_VERSION cmd: ['echo', '0.40.0'] - type: init - type: plan - type: conftestIn this configuration:
- The
envstep sets theCONFTEST_VERSIONenvironment variable to0.40.0, ensuring that specific version of Conftest is used. - If
CONFTEST_VERSIONis not specified, Terrateam will use the default version installed in the environment.
Specifying a Custom Policy Directory
Section titled “Specifying a Custom Policy Directory”Here’s an example of how to specify a different policy directory using the CONFTEST_POLICY environment variable in your Terrateam workflow:
workflows: - tag_query: 'dir:aws/us-east-1/production/iam' plan: - type: init - type: plan - type: env name: CONFTEST_POLICY cmd: ['echo', '$TERRATEAM_ROOT/aws/policies/iam/'] - type: conftestIn this configuration:
- The
envstep sets theCONFTEST_POLICYenvironment variable to theaws/policies/iam/directory relative to the repository root ($TERRATEAM_ROOT). - The
confteststep automatically uses the specified policy directory when running Conftest. With this setup, when a pull request is created against theaws/us-east-1/production/iam/main.tffile, Terrateam will execute Conftest using the Rego policy files located in theaws/policies/iam/directory.
Policy Testing Workflow
Section titled “Policy Testing Workflow”When a Terrateam plan operation runs with policy enforcement enabled, the following workflow takes place:
-
Terrateam generates the Terraform plan file.
-
Conftest is executed against the generated plan file using the specified Rego policies.
-
If the plan violates any of the defined policies, Conftest returns a non-zero exit status, causing the Terrateam plan operation to fail.
-
The Conftest output, including any policy violations, is captured and included in the Terrateam plan results.
-
If the plan passes all policy checks, the Terrateam plan operation succeeds, and the plan can be reviewed and applied as usual.

Best Practices
Section titled “Best Practices”When implementing policy enforcement with OPA and Conftest in Terrateam, consider the following best practices:
- Define clear and concise policies that align with your organization’s standards, best practices, and compliance requirements.
- Use meaningful error messages in your Rego policies to help users understand why a plan failed and how to remediate the issues.
- Organize your policies in a logical directory structure that reflects your infrastructure and makes it easy to manage and maintain the policies.