_images/login_button.png _images/signup_button.png



Governance with OPA

Reading time: 5 minutes

Scalr utilizes the Open Policy Agent to inject governance policies in the Terraform pipeline. Account admins can define groups of policies that are applied to specific environments which are the injected into every Terraform run immediately after the plan and cost estimation phases.

What is OPA?

Open Policy Agent (OPA) is a declarative policy-as-code language that allows input data to be evaluated against rules. The evaluation returns a result which is then interpreted by the caller 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 the caller then uses to make a decision.

In the context of Terraform, the input data to OPA will be the output of terraform plan (tfplan) and the run time environment data, such as workspace details, user name etc (tfrun). From this data OPA can be used to evaluate the attributes to all Terraform providers, resources, data and anything mentioned in the plan.

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

Example data - tfrun

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.

Example data - tfplan

tfplan data is literally 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.

How is OPA Implemented in Scalr?

  • OPA Policies are policy-as-code stored in VCS repo’s and registered in Scalr as policy groups.

  • VCS repository contains one or more policy files and 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

  • Policy groups are linked to specific environments

  • Policies are evaluated for every run in every workspace in the linked environments

Scalr requires that the OPA evaluation returns and array of strings called 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 calls deny that performs the evaluation. Here is a very simple example that checks the increase in cost 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 a delta > 10 would return a result like this.

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

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

Creating Policy Groups

There are 3 steps to create a policy group in Scalr.

  1. Create policy rego files in a VCS repo.

    _images/opa_repo.png
  2. Add a scalr-policy.hcl file to set the enforcement levels 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 (green) 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” off the main menu.

    • Create a new policy group of type “Open Policy Agent” and add the details of the VCS Provider and repository

      _images/opa_vcs.png
    • Save and a summary of the policies will be displayed.

      _images/opa_enforced.png
    • Now that the policy is created, attach it to an environment by clicking on “environments”, “policies”, then click on “attach policy groups” on the right and save:

      _images/link1.png

Policy Group Checks

The “Policy Check” column in the policy group allows an account administrator to see a summary of recent evaluations of each policy.

_images/policy_check.png

The colored summary bar is a link to a detailed and filterable list of all the evaluations.

_images/policy_check2.png

OPA Pull Request Previews

Scalr provides a preview of future policy changes based on pull requests against the repository linked to the policy group. This allows impact assessment of planned changes without disrupting workflows. These previews do not cause a run to fail. To do start an OPA dry run, open a pull request against master with the changes.

New Runs

Once the pull request is made, it will be displayed in the policy group screen:

_images/opa_pr.png

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

_images/start_preview.png

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

_images/preview_run.png

Once the pull request is merged to master, the preview will disappear and the new policy will be applied to all runs.

Existing 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:

_images/existing_ws_check.png

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

_images/existing_ws_check_detail.png

This will help the administrator understand the blast radius that the policy could potentially have prior to merging it to master.

OPA Examples

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