Going to AWS re:Invent 2024?

➡️ Book a meeting with Spacelift

Terraform

How to Use Open Policy Agent (OPA) with Terraform [Examples]

How to Use Open Policy Agent (OPA) with Terraform

In this article, we will delve into the Open Policy Agent (OPA), first explaining what “policy as code” is and how to use it with Terraform. We will explain how OPA works, policy language Rego, the differences between Sentinel and OPA, OPA use cases, and some practical examples of how to use it in your Terraform configurations.

  1. What is policy as code?
  2. What is the Open Policy Agent?
  3. How does Open Policy Agent work?
  4. Open Policy Agent use cases
  5. How to write an OPA policy with Terraform – example

What is policy as code?

Policy as code (sometimes abbreviated to PaC) is a methodology that involves writing policies and regulations in the form of code and is closely related to Infrastructure as Code (IaC). Using PaC allows you to define governance rules, compliance standards, and security protocols in machine-readable formats, enabling you to automate the enforcement and monitoring of policies across your systems and infrastructure.

Instead of manually implementing and enforcing these policies, you can express them in code using JSON, YAML, or specialized domain-specific languages, depending on the tool you select. Implementation of PaC is usually integrated into deployment pipelines, configuration management tools, or IaC frameworks. As a result, policies become an inherent part of the system’s architecture, automatically applied and enforced as infrastructure is provisioned or modified.

Before you jump in, know that policy as code requires careful planning and ongoing maintenance. Policies must accurately reflect organizational requirements and keep pace with evolving compliance standards and security threats. Your teams must ensure that policy code is regularly reviewed, tested, and updated to mitigate risks and maintain effectiveness.

The benefits of implementing policy as code are as follows:

  1. Consistency and scalability: Ensure consistent adherence across infrastructure, regardless of scale or complexity. Policy enforcement can scale alongside without requiring additional manual effort.
  2. Traceability, documentation, and auditing: Policy code is version-controlled and auditable, providing a clear record of changes and facilitating compliance audits. Policy definitions can serve as documentation, providing clear and explicit guidelines on how the infrastructure and applications should be configured and managed.
  3. Rapid remediation: Automated enforcement enables swift detection and remediation of policy violations, reducing manual intervention and potential downtime.
  4. Collaboration and reusability: Teams can collaborate on policy code, share best practices, and reuse standardized policy templates across projects and environments.

What is Open Policy Agent?

Open Policy Agent (OPA, pronounced “oh-pa”) is a popular open-source policy engine that allows you to define, manage, and enforce policies across different parts of the stack. The major benefit of selecting OPA for your policy as code tool is that you can use a unified toolset and framework for policy across the cloud-native stack, including cloud infrastructure, Kubernetes, containers, APIs, service mesh, and CI/CD.

Similar to Terraform, OPA is defined using declarative configuration files, meaning you describe how you want the end state to look rather than providing step-by-step instructions (imperative). OPA lets you express policy in a high-level language promoting safe, performant, fine-grained controls.

What is Rego?

OPA policies are expressed in a high-level declarative language called Rego. Rego (pronounced “ray-go”). It is specifically designed to express policies concisely.

Rego provides a rich set of built-in functions that you can use to manipulate data and perform operations such as filtering, aggregation, and transformation. In addition, it supports pattern matching, which allows you to match complex data structures against specific patterns or conditions. This enables you to write expressive policies that can handle nested data and complex relationships. Like Terraform, it promotes modularization, allowing you to organize your policies into reusable modules and packages.

More on Rego over on the OPA official docs pages and our Rego tutorial.

What is the difference between Sentinel and OPA?

Sentinel is a policy as code framework developed by HashiCorp, primarily designed to integrate with their IaC tool, Terraform. It provides a policy engine that evaluates policies against Terraform configuration files during deployment. Sentinel policies are defined using the Sentinel policy language and have a strong integration with the Hashicorp ecosystem of products, including documentation and tutorials.

OPA is an open-source policy engine that can be used across a broader range of use cases and integrates with various systems and applications, not limited to Terraform. Because of this, OPA benefits from the contributions of a diverse community of users and contributors. OPA can evaluate policies against arbitrary data, making it suitable for use cases beyond infrastructure provisioning. OPA policies are defined using the Rego policy language, which is more general-purpose and flexible than the Sentinel policy language.

The choice between Sentinel and OPA depends on your organization’s specific requirements and use cases. Suppose you are only concerned with Terraform PaC where there is no additional scope and will not be in the future. In that case, Sentinel may be a good choice, whereas selecting OPA will enable you to apply policies to Terraform and other things across the cloud-native stack.

More on Sentinel over on the official Hashicorp pages.

How does Open Policy Agent work?

policy as code opa

Configuration starts with defining your policies using the Rego policy language. OPA evaluates policies against input data to determine whether the policies are satisfied or not. It does this by executing the rules defined in the Rego policies and applying them to the input data.

OPA uses a query-based evaluation model, where you can query the input data and get a boolean result indicating whether the policies are met. The input data can come from various sources, including HTTP requests, configuration files, API responses, etc. OPA treats the input data as a JSON document that can be queried and matched against the defined policies.

OPA can also make authorization decisions, for example, allowing or denying access based on the policies that are satisfied or violated. Once integrated, OPA enforces policies in real time as requests are made or data is accessed. It intercepts requests, evaluates policies against the input data, and makes authorization decisions accordingly.

Read more: What is Open Policy Agent, and how does it work?

Open Policy Agent use cases

OPA’s flexibility and extensibility make it suitable for various scenarios across different domains and environments.

1. Cloud security and compliance

The most obvious use case for using PaC with OPA is Cloud Security and Compliance and Terraform (IaC) Validation to validate infrastructure configurations before deployment. However, OPA goes way beyond this, integrating with multiple components across your technology stack.

For example, OPA can be integrated with API gateways to enforce access control policies for APIs. This allows you to define and enforce policies that control which clients or applications can access specific APIs and endpoints based on attributes of the incoming requests, such as headers, tokens, or metadata.

2. Enforcing data access control policies

Another use case for OPA is using it to enforce data access control policies for databases and data stores. By integrating OPA with your data access layer, you can define and implement policies that control who can access which data based on attributes of the request, such as user roles, permissions, or metadata associated with the data.

3. Authorization for Kubernetes, containers, and service mesh

OPA is particularly useful for several use cases around Kubernetes (K8s), containers, and service mesh, specifically authorization.

In K8s, it can be used to enforce admission control policies and similarly enforce fine-grained access control policies for microservices architectures.

It can also be integrated with service mesh technologies such as Istio or Linkerd to enforce fine-grained access control policies for service-to-service communication. This allows you to define and enforce policies that govern which services can communicate with each other and under what conditions, helping to prevent unauthorized access and data exfiltration.

How to write an OPA policy with Terraform — example

The following policy only allows resources can be used to enforce the provisioning of Infrastructure in Azure to the uksouth region only.

terraform_authz.rego

package terraform.authz

default allow = false

resource_allowed {
    input.request.resource.region == "uksouth"
}

In this Rego policy:

  • We define a package called terraform.authz.
  • The default allow = false statement sets the default decision to deny access unless explicitly allowed.
  • We define a rule resource_allowed that evaluates to true if the region attribute of the resource being requested is set to "uksouth".
  • If resource_allowed evaluates to true, the policy allows the request (allow = true); otherwise, the default deny decision (allow = false) remains in effect.

To integrate this Rego policy with OPA and Terraform:

  1. Save the Rego policy to a file with a .rego extension, for example, terraform_authz.rego.
  2. Start the OPA server with the policy file:
opa run -s terraform_authz.rego

3. Use the OPA integration with Terraform. The first way to do this is by utilizing the conftest utility that provides a way to run OPA policies against Terraform plans.

For example, if you have a Terraform plan file named terraform_plan.json, you can use conftest to evaluate the policy against the plan:

conftest test --input terraform_plan.json --policy terraform_authz.rego

Conftest will evaluate the Terraform plan against the OPA policy. If the plan violates the policy, Conftest will output a violation message. Otherwise, it will indicate that the plan is compliant with the policy.

You can also use OPAs HTTP API to check a Terraform plan against the policy using OPA’s HTTP API. You need to send a POST request with the Terraform plan JSON data to the /v1/data/terraform/authz/allow endpoint.

To do this with curl (Replace http://localhost:8181 with the appropriate URL if your OPA server is running on a different host or port):

curl -X POST \
  http://localhost:8181/v1/data/terraform/authz/allow \
  -H 'Content-Type: application/json' \
  -d @terraform_plan.json

Key points

Policy as code is a key practice in modern DevOps and cloud-native environments, enabling organizations to maintain security, compliance, and operational excellence at scale.

OPA is an open-source policy as code tool that can be used across the cloud-native stack, whereas Hashicorps Sentinel is limited to use with Terraform and products in the Hashicorp stack.

Luckily, at Spacelift, we’ve done all the heavy lifting, allowing you to reap the benefits of using OPA for policy as code without having to implement everything from scratch yourself. Spacelift also provides a Terraform provider for managing your Spacelift account. This means that you can manage the policies available within your account, along with the Stacks they apply to in code.

If you’re interested in trying out Spacelift to see what we have to offer, why not sign up for a free trial or book a demo with one of our engineers? You can set up a Spacelift account in minutes and get started on your policy as code journey today!

Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.

Discover better way to manage Terraform

Spacelift helps manage Terraform state, build more complex workflows, supports policy as code, programmatic configuration, context sharing, drift detection, resource visualization and many more.

Start free trial

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide