Open Policy Agent

Scalr utilizes Open Policy Agent (OPA) to govern Terraform deployments. OPA is policy-as-code that uses the rego language to evaluate Terraform input data against administrator defined rules. Any data which is in the Terraform JSON can be evaluated as part of the OPA checks. The evaluation returns a result which is then interpreted by the Scalr to determine what course of action to take. To be clear, OPA does not make any decisions regarding a policy, it simply returns a result (true, false, some text) which Scalr then uses to make a decision.

The OPA code is treated similarly to your Terraform code in that it is stored in a VCS provider and managed through a GitOps model. Administrators create, manage, and open pull requests on the policies directly in VCS providers as well as trigger speculative runs to preview the impact of policy changes.

There are two main sections that the policies can evaluate, the tfplan and tfrun. The Terraform input data will be the output of terraform plan (tfplan in rego) and the run time (tfrun in rego) environment data, such as workspace details, username, etc. From this data, OPA can be used to evaluate the attributes of all Terraform providers, resources, data, and anything mentioned in the plan.

Example data - tfplan

The tfplan data is the output from terraform plan in JSON format. There are multiple sections to the plan data to enable checks on planned_values, resource_changes, configuration etc. OPA policies will most often use resource_changes to evaluate changes to attribute values. The structure of tfplan, with details omitted, is shown below.

   "tfplan": {
       "format_version": "0.1",
       "terraform_version": "0.13.4",
       "variables": {

       "planned_values": {

       "resource_changes": [

       "output_changes": {

       "configuration": {

   "tfrun": {

A more complete example of the tfplan data, with an example policy, can be viewed here: tfplan example data.

Example data - tfrun

The tfrun data can be evaluated by OPA to check on data related to the run time environment in Scalr, such as user names, VCS provider details, cloud credentials, cost estimation, and more. The structure of tfrun, with details omitted, is shown below.

 "tfplan": "<terraform plan content>",
 "tfrun": {
   "workspace": {

   "vcs": {

   "cost_estimate": {

   "credentials": {

   "source": "ui",
   "message": "Update",
   "is_destroy": false,
   "is_dry": false,
   "created_by": {


A more complete example of the tfrun data, with an example policy, can be viewed here: tfrun example data.

Using OPA in Scalr

OPA policies are stored in a VCS repository and registered in Scalr as policy groups. The VCS repository contains one or more policy rego files and a scalr-policy.hcl file that sets the enforcement level of each policy:

  • Hard Mandatory - Cannot be overridden
  • Soft Mandatory - Can be overridden by account admins and other authorized roles
  • Advisory - Provides a warning only

Once the policy groups are created, the groups are linked to specific environments to enforce the policies in those environments. The policies are evaluated against every run in every workspace in the linked environments.

Scalr requires that the OPA evaluation returns an array of strings named deny. The presence of any values in the array will be interpreted by Scalr as a policy failure. Thus, in policies used with Scalr there must always be a rule named deny that performs the evaluation. Here is a very simple example that checks the cost of the resources in a Terraform run using the cost estimation data:

package terraform

import input.tfrun as tfrun

deny[reason] {
    cost_delta = tfrun.cost_estimate.delta_monthly_cost
    cost_delta > 10
    reason := sprintf("Plan is too expensive: $%.2f, while up to $10 is allowed", [cost_delta])

An evaluation that detects the cost to be higher than $10 would return a result like this:

  "deny": [
    "Plan is too expensive: $12.00, while up to $10 is allowed"

Creating Policy Groups

A policy group is the collection of one or more OPA policies stored in a repository with a scalr-policy.hcl file declaring if the policies are enabled and what the enforcement level is. One or more policies can be attached to each environment and it is normal to have a common policy shared across all environments as well as environment-specific policies to ease overhead. Common shared policies could include restricting network access, preventing public S3 buckets, allowing specific Terraform modules, and much more. Follow these steps to create a policy group:

  1. Create policy rego files in a VCS repo:

  1. Add a scalr-policy.hcl file to set the enforcement levels and if the policy is enabled or not for each policy file in the repo, as shown in this example. Note the version is required:
version = "v1"

policy "limit_modules" {
    enabled = true
    enforcement_level = "advisory"

policy "workspace_name_convention" {
    enabled = true
    enforcement_level = "advisory"
  1. Create the policy group in Scalr at the account level. To use policy groups it is necessary to create a VCS provider if this has not already been done.
  • Go to the "run policy engine" at the account scope and create a run policy group:
  • Create a new policy group with the VCS details:

Once saved, the policy can be enforced on environments by clicking on "Enforce run policy group":

Policy reports will appears within a few seconds (maybe longer depending on the amount of workspaces) once the policy is enforced.

Policy Reports

Once a policy is created and enforced, it will automatically start checking runs, but from an administrative perspective, you likely want to see the status of the policies across all environments and workspaces. Policy checks give you a single view of the current results of policies across all environments and workspaces. To view this click on “Policy Reports”:


More Resources

For examples of OPA policies, please visit our GitHub repository: Open Policy Agent Examples

To learn more about using the terraform plan data with OPA please review our Scalr OPA Blog series, in particular OPA Series Part 3: How to analyze the JSON plan.

To learn more about writing OPA policies for Terraform and Scalr we recommend the following resources:


More of a visual learner? Check out this feature on YouTube.