Fairwinds | Blog

Fairwinds Insights Basic Tutorial: Validating OPA Policies in the CLI for Cloud-Native Infrastructure

Written by Robert Brennan | Apr 25, 2023 2:41:19 PM

The Open Policy Agent (OPA) is an open source, general-purpose policy engine that provides a framework for validating structured data across your cloud-native stack. It encourages users to write policy-as-code to extend the community’s move towards infrastructure as code (IaC). OPA can validate any kind of structured data, including Terraform, HTTP requests, Envoy, Kafka, SQL, Linux, and Dockerfiles; it is frequently used and associated with Kubernetes manifests.

The OPA team maintains a suite of tools for configuration validation using a domain-specific language called Rego. Rego can be a bit challenging for those unfamiliar with it, because the syntax is unlike a typical programming language. However, like any good domain-specific language (DSL), it’s quite powerful once you become familiar with it. If you want to learn how to start thinking in Rego, read this linked article.

The Kubernetes community has chosen OPA for creating configuration policies. To support that need, you can use the Fairwinds Insights command line interface (CLI) to test and validate OPA policies. The CLI helps you in two ways, by: 

  1. Validating the OPA policy syntax

  2. Validating the Action Items that the policy outputs in Fairwinds Insights

This improves the feedback loop for developers when working with OPA policies and allows you to test your policies locally before you upload them to Fairwinds Insights.

Installing the Insights CLI

Your first step is to install the Fairwinds Insights CLI. You can do that by visiting our GitHub page for the Insights CLI, which includes links to the CLI documentation and installation options.

Our team created a video that walks you through the steps you need to take to validate OPA policies in the CLI. If you’re not already using Insights, the  free tier is available for environments up to 20 nodes, two clusters, and one repo, so you can use it to get started and follow these steps. First, run a --help command to see which validation options are currently available. At the command line, type: insights-cli validate opa --help. In the demo video, you can see it only validates a single policy, but you can also validate multiple policies, such as one might use in continuous integration/continuous deployment (CI/CD).

Validating OPA Policy 

Here’s an example OPA policy that makes sure the “department” label is set on every Deployment. We’ll call this file policy.yaml

package fairwinds

labelrequired[actionItem] {

    requiredLabels := {"department"}

    kinds := {"Deployment"}

    kind := lower(kinds[val])

    lower(input.kind) == kind

    provided := {label | input.metadata.labels[label]}

    missing := requiredLabels - provided

    count(missing) > 0

    description := sprintf("Label %v is missing", [missing])

    actionItem := {

        "title": "Label is missing",

        "description": description,

        "severity": .2,

        "remediation": "Add the label",

        "category": "Reliability"

    }

}

In order to validate this policy, we’d want to supply a Kubernetes Deployment that passes the policy and another one that fails. Here’s an example Deployment that should pass validation. We’re going to call this policy.success.yaml, which signals to the insights-cli that this should pass the OPA policy.

apiVersion: apps/v1

kind: Deployment

metadata:

  name: policy-test

  labels:

    department: development

spec:

  replicas: 1

  template:

    spec:

      containers:

      - image: busybox

Let’s see what happens when we use the Insights CLI to validate the policy above, using this Kubernetes manifest:

❯ insights-cli validate opa -r policy.rego -k policy.success.yaml

OPA policy validated successfully.

Great! Looks like everything passes. What happens if we remove the label?

❯ cat policy.success.yaml | grep -v department > policy.failure.yaml

❯ insights-cli validate opa -r policy.rego -k policy.failure.yaml

✔ Action Item:

        Title: Label is missing

        Category: Reliability

        Severity: 0.2

        Description: Label {"department"} is missing

        Resource Namespace: notset

        Resource Kind: Deployment

        Resource Name: policy-test

        Remediation: Add the label

        Event Type: policy

OPA policy validated successfully.

We generated an Action Item, as expected! So we’ve confirmed that Insights will warn us if any of our Deployments are missing the “department” label.

Validating Namespaces

What if we want to get a bit more specific? Maybe we don’t want to enforce our policy in the kube-system namespace, which contains a bunch of deployments we don’t manage. Fortunately, with Rego, that’s easy! And again we can use the CLI to validate that everything works as expected.

To exempt the kube-system namespace, we’ll add a new function to the policy:

blockedNamespace(elem) {

    blockedNamespaces := ["kube-system"]

    ns := blockedNamespaces[_]

    elem.metadata.namespace == ns

}

Then, in labelrequired function, we just have to add the line

not blockedNamespace(input)

We can tell the insights-cli which namespace we’re working in using the -N flag. If we set that to kube-system, we should see a complaint about policy.failure.yaml, which no longer generates an Action Item.

❯ insights-cli validate opa -r policy.rego -k policy.failure.yaml -N kube-system

OPA policy failed validation: 0 action items were returned, but 1 is expected

exit status 1

Getting Feedback During Policy Execution

If you’re having trouble debugging an issue with your policy, you can use the “print” statement inside your rego code to get more feedback during policy execution. E.g. we can print the input’s kind to make sure we’re looking at the right thing:

labelrequired[actionItem] {

    print("The Kind is", input.kind)

    not blockedNamespace(input)

    # …

}

❯ insights-cli validate opa -r policy.rego -k policy.success.yaml

The Kind is Deployment

OPA policy validated successfully.

Using OPA in Insights

Going through these steps, you now know how to validate that this policy is working as you intend it to. Excellent! It’s time to upload that policy to Insights. Just make sure that the OPA report is enabled in Report Hub and you are ready to start using OPA for policy management in Kubernetes. 

​​Watch the video to walk through the steps of Validating OPA Policies in the CLI step by step.