magickatt / OpenPolicyAgentTerraformExample

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Open Policy Agent example using Terraform

Simple example of how to use Open Policy Agent with Terraform including setting up a GitHub Action.

main.tf and plan.json are taken from the provided documentation (and are not based on any real infrastructure) purely to demonstrate how Open Policy Agent can be run within a container and subsequently the GitHub Action.

Documentation does not explain particularly well (for a newcomer) what each part of the supplied commands do, so please find a breakdown below. Additionally there is a slightly easier-to-read explanation of how OPA works.

There is a provided Dockerfile to run the command below in a container, mounting the appropriate files.

opa exec --decision terraform/analysis/authz --bundle policies/ plan.json

Decision

opa exec --decision 

Most examples will show commands such as opa test which uses a subcommand such as test. However for Terraform, they expect you to determine a "decision" (allowed or not allowed) based on polic(ies), input (Terraform plan file) and query (from a policy in a remote bundle or 1 of the user-supplied policies, we are doing the latter in this case)

The string argument referenced after --decision is the name of a variable in package namespace. In their example, since the package is terraform.analysis the argument is for the authz boolean, therefore --decision terraform.analysis.authz. So you essentially tell OPA how to decide by telling it what variable to inspect.

opa exec --decision 

Adding description and message to decision output

By default the output from a decision will be fairly basic, simply telling you what input data was evaluated and what the result of the decision was.

{
  "result": [
    {
      "path": "plan.json",
      "result": true
    }
  ]
}

For Continuous Integration checks this is not overly useful, so you can supply a description and message if the decision is not successful.

authz[msg] {
    desc := "Sample description"
    msg := sprintf("Sample message, score is %d, blast radius is %d", [score, blast_radius])
    score < blast_radius
    not touches_iam
}

Multiple decisions

If you want to evaluate multiple decisions, you must query each variable separately (referencing their namespaced name) as an additional command line parameter.

opa exec --decision terraform/analysis/authz \
  --decision terraform/analysis/something \
  --bundle policies/ plan.json

An alternative way to potentially do this is to include a file that includes a decision that depends on code evaluations in other files. Provided they are in the same package they should be available.

authz {
    score < blast_radius
    not touches_iam
    something # Referenced from policies/additional.rego
}

Policy bundle

--bundle policies/

Policies are either user-supplied or loaded from a remote bundle. In the provided simple example they provided in a single Rego policy file. Seemingly this will not work if you specify the path to a specific policy file (even if you only have 1) it must be a directory.

Input data

plan.json

The 1st (and in this case only) positional argument is the input data. It must always be JSON, so for Terraform we need to convert outputted plan files into their JSON representation.

About


Languages

Language:Open Policy Agent 70.2%Language:Shell 20.6%Language:HCL 8.9%Language:Dockerfile 0.3%