In a previous blog post, we shared some high-level concepts around policy code as a means of governance and risk reduction. We also talked about Open Policy Agent (OPA) as the policy engine that enforces policies created as code. In this blog post, we will showcase how to use OPA to create a policy-enforced CI/CD pipeline built in Harness. 

Getting Started with Open Policy Agent

To start creating a policy-enforced pipeline, you will need to install OPA onto your environment. In this guide, we installed OPA directly onto a Kubernetes cluster. This tutorial by Open Policy Agent describes how to deploy OPA as an admission controller in Kubernetes.

Note you can also create a Harness workflow or pipeline to deploy OPA and apply predefined policies. 

Graphical user interface, application

Description automatically generated

Creating OPA Policies on Kubernetes

Developing a policy in Rego is fairly straightforward. You can also leverage developer tools to get a better development experience when validating and creating policies. Below is an example policy that denies a Kubernetes deployment of any container images that start with the name Nginx. We want to govern our deployment, so specific images are denied entry into the Kubernetes environment.

package kubernetes.admission
deny[msg] {
  input.request.kind.kind == "Deployment"
  image := input.request.object.spec.template.spec.containers[i].image
  startswith(image, "nginx")
  msg := sprintf(""Can't deploy image %v",[image])
}

Copy the code snippet into a file called ‘deploy-restrict.rego’. Store this policy in Kubernetes as a ConfigMap into the same namespace where you are running OPA.

kubectl create configmap deploy-restrict --from-file=deploy-restrict.rego -n opa

By default, kube-mgmt loads policies out of configmaps in the OPA namespace OR configmaps in other namespaces labeled openpolicyagent.org/policy=rego. 

Next, we can exercise the policy by trying to deploy a simple Nginx image. Here I have an deployment.yaml file containing a nginx-deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: Nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

As shown below, when we try to create a deployment in the default namespace, the policy denies the action and returns the formatted policy message. 

Creating additional policies for police Kubernetes resources can help you protect specific environments like QA or production.

Creating a policy enforced pipeline in Harness

Now that we have a policy that works in our Kubernetes cluster, we can ensure that our deployment pipelines adhere to these policies. 

I have a simple Harness pipeline that contains a few workflows to deploy to a development namespace. My pipeline also promotes the ready container image to QA and production. Note that in our policy, we did not want any images starting with the name Nginx in our cluster.

As shown below, our entire deployment pipeline fails because it does not have the authorization to proceed based on our defined policies. 

A screenshot of a computer

Description automatically generated

We can create more complex policies while utilizing our pipelines to apply, test, validate, and triggers these policies. If you’d like to learn more about the common use cases for policy-as-code, check out this policy-as-code introduction. Otherwise, I hope this blog post helped showcase the capabilities of Harness and OPA. Here’s to not only delivering quickly but also safely.

Conclusion

Policy as code will continue to be important as organizations continue to govern their processes and software better. There are many use cases for creating policies and integrating them alongside your CI/CD pipelines. This blog post shows how to create Harness pipeline policies. If you’d like to try Harness for free, click here