Policy as Code¶
Note
The Open Policy Agent integration is only available on paid tiers. See Scalr pricing here.
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 similar to your Terraform code in that it is stored in a VCS provider and managed through a GitOps model. Adminstrators create, manage, and open pull requests on the policies directly in VCS providers as well as trigger speculitve 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 to 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | { "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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | { "tfplan": "<terraform plan content>", "tfrun": { "workspace": { }, "vcs": { }, "cost_estimate": { }, "credentials": { }, "source": "ui", "message": "Update README.md", "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 polices on 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 enforment 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:
Create policy rego files in a VCS repo:
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"
}
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 “Policy Engine” then “Policy Groups” by clicking on the Scalr icon on the top left.
Create a new policy group of type “Open Policy Agent” and add the details of the VCS provider and repository:
Save and a summary of the policies will be displayed:
Now that the policy is created, link it to an environment by clicking on “environments”, “policies”, then click on “link policy groups” on the right and save.
Policy Group Checks¶
Once a group is created and assigned to an environment, it will automatically start checking runs, but from an adminstrative perspective you likely want to see the status of the policies across all environments and workspaces. Policy checks give you a single view into the current results of policies across all environments and workspaces. To view this, click on the policy and look at the “Policy Check” column on the bottom right.

By clicking on the colored summary bar, you will be link to a detailed and filterable list of all the policies with the results.

OPA Previews¶
Note
The policy preview feature is only available on the pro tiers. See Scalr pricing here.
Scalr provides a preview of future policy changes based on pull requests against the repository linked to the policy group. This allows the policy adaminstator to view an impact assessment of planned changes without disrupting workflows. This tells an adminstrator if they made an error updating the policy or if their are workspaces that will violate the upcoming policy change and gives the adminstrator time to contact the workspace owner prior to merging. The results of the previews are also pushed back to the VCS provider to allow for a GitOps model. These previews do not cause current runs to fail. To do start an OPA dry run, open a pull request against master with the changes.
Viewing Previews on Workspaces¶
When a pull request is opened on an existing policy, Scalr will automatically check all existing workspaces for violations and report back after a few minutes. The time will very depending on the size of the environment it is evaluating:

Clicking on the policy check section it will provide details of exactly what has failed, where the workspace is, and who owns it:

This will help the administrator understand the blast radius that the policy could potentially have prior to merging it to master.
Viewing Previews on New Runs¶
Once the pull request is made, it will be displayed in the policy group screen:

The preview mode can be turned on and off as needed:

In the next run, the workspace owner will see the implemented policy vs the preview policy:

Once the pull request is merged to master, the preview will disappear and the new policy will be applied to all runs.
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: