• Blog
  • Info Support
  • Career
  • Training
  • International Group
  • Info Support
  • Blog
  • Career
  • Training
  • International Group
  • Search
logo InfoSupport
  • Latest blogs
  • Popular blogs
  • Experts
      • All
      • Bloggers
      • Speakers
  • Meet us
  • About us
    • nl
    • en
    • .NET
    • 3D printing
    • Advanced Analytics
    • Agile
    • Akka
    • Alexa
    • Algorithms
    • Api's
    • Architectuur
    • Artificial Intelligence
    • ATDD
    • Augmented Reality
    • AWS
    • Azure
    • Big Data
    • Blockchain
    • Business Intelligence
    • Chatbots
    • Cloud
    • Code Combat
    • Cognitive Services
    • Communicatie
    • Containers
    • Continuous Delivery
    • CQRS
    • Cyber Security
    • Dapr
    • Data
    • Data & Analystics
    • Data Science
    • Data Warehousing
    • Databricks
    • DataOps
    • Developers life
    • DevOps
    • Digital Days
    • Digital Twin
    • Docker
    • eHealth
    • Enterprise Architecture
    • Event Sourcing
    • Hacking
    • Infrastructure & Hosting
    • Innovatie
    • Integration
    • Internet of Things
    • Java
    • Machine Learning
    • Microservices
    • Microsoft
    • Microsoft Bot Framework
    • Microsoft Data Platform
    • Mobile Development
    • Mutation Testing
    • Open source
    • Pepper
    • Power BI
    • Privacy & Ethiek
    • Python
    • Quality Assistance & Test
    • Quality Assurance & Test
    • Requirements Management
    • Scala
    • Scratch
    • Security
    • SharePoint
    • Software Architecture
    • Software development
    • Software Factory
    • SQL Server
    • SSL
    • Start-up
    • Startup thinking
    • Stryker
    • Test Quality
    • Testing
    • TLS
    • TypeScript
    • Various
    • Web Development
    • Web-scale IT
    • Xamarin
    • All
    • Bloggers
    • Speakers
Home » Policy as Code with Open Policy Agent and Conftest
  • Policy as Code with Open Policy Agent and Conftest

    • By Remco Westerhoud
    • Quality Assurance & Test 2 years ago
    • Quality Assurance & Test 0 comments
    • Quality Assurance & Test Quality Assurance & Test
    Policy as Code with Open Policy Agent and Conftest

    Did you ever make a change in a Kubernetes manifest only to find out upon deployment that you’ve messed up a piece of configuration. I know I have. Wouldn’t it be nice to catch these mistakes before deploying? Open Policy Agent (OPA) allows us to do so.

    OPA is a policy engine which enables us to write our own policies and run them against our manifests. We will write these policies in Rego, a declarative language that is provided by OPA.
    We will use a utility tool called Conftest to run the policies we’ve made against our configuration files.

    Starting off

    First off, let’s go ahead and install Conftest. OPA will be included in this installation.

    brew tap instrumenta/instrumenta
    brew install conftest

    Now that we’ve got everything installed we’ll need a manifest that we can run against our policy check. For this I’ve created an example deployment:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: example-app-deployment
     labels:
       app: example-app
     namespace: example
    spec:
     replicas: 1
     selector:
       matchLabels:
         app: example-app
     template:
       metadata:
         labels:
           app: example-app
       spec:
         imagePullSecrets:
           - name: example-pull-secret
         containers:
         - name: example-app
           image: <registry>/example-app
           ports:
           - containerPort: 80

    Writing the first policy

    Our deployment currently has a single replica. Imagine our company requires all of our Deployments to have at least 2 replicas. We’ll be able to guarantee this by writing a policy for it.

    package main
    
    deny_replicas[msg] {
        input.kind == "Deployment"                          # If it is a Deployment
        input.spec.replicas < 2                             # And the replicas are < 2
        msg := "Deployments must have 2 or more replicas"   # Set the return variable to the error message and fail the test
    }

    The policy is fairly straightforward. There are two noteworthy things. First is the input variable that is used. Input is a variable that Conftest creates for you. It takes the input we give it, parses it to JSON format and makes it available as an input variable in our policies.
    The second noteworthy thing is something that might feel a bit unnatural. The name of this policy starts with deny. This means that if this test reaches the end, it will fail. If any of the statements in the test resolve to false, the test will abort and it will be considered a success.

    Running the policy

    Conftest by default requires our policies to be placed in a directory called policy. Therefore our directory structure should look something like this.

    dir-structure
    Directory structure

    We can now run our policy check by executing the following command in our project directory.

    Failing testrun

    As expected our test failed, since we did not meet our policy by having 2 replicas in our Deployment. Let’s go ahead and fix that and rerun our test.

    Succeeding testrun

    This time the test passed with flying colors!

    Create some more!

    Testing our example deployment against our policy is fun, but in any realistic scenario you’d have a lot more configuration files and policies. Therefore I’ve added two more configurations, one for a Service and one for a Secret:

    dir-structure2
    Directory structure
    apiVersion: v1
    data:
      .dockerconfigjson: supersecret
    kind: Secret
    metadata:
      name: example-pull-secret
      namespace: example
    type: kubernetes.io/dockerconfigjson
    apiVersion: v1
    kind: Service
    metadata:
      name: example-app
      labels:
        app: example-app
      namespace: example
    spec:
      type: ClusterIP
      ports:
        - port: 80
          targetPort: http
          protocol: TCP
          name: http
      selector:
        app: example-app

    Now that we’ve added those, we also want a new policy. Let’s say we want every manifest to explicitly declare its namespace. We can write a policy for this:

    package main
    
    deny_namespace[msg] {
       not input.metadata.namespace               # There is no namespace
       msg := "Resources must have a namespace"   # Set the return variable to the error message; The test has reached the end thus has failed
    }

    Just like the other policy we will deny any input for which all the statements resolve to true. If there is no namespace, input.metadata.namespace will resolve to false. By using the not operator we can resolve this to true if the namespace is missing.In order to run the tests we need to use a wildcard in our conftest command.

    We now have 6 tests that have been executed. That’s because we run 2 policies for each of our 3 configuration files.

    Unit testing our policies

    OPA provides us with an easy way to unit test the policies we’ve written.

    test_deny_replicas {
        deny_namespace[msg] with input as {
            "kind": "Deployment",
            "metadata": {
             "name": "example-app-deployment"
            }
        }
    }
    
    
    test_deny_namespace {
        deny_namespace[msg] with input as {
            "kind": "Deployment",
            "spec": {
                "replicas": 2
            }
        }
    }

    Writing the tests is pretty straightforward. The name of the test must begin with test_. In the test itself all we need to do is call the policy we’d like to test, and provide it with our own input. After this we can run all our unit tests by performing the following command in our policy directory.

    What’s next?

    We’ve now learned how we can create policies and test our yml files against them. This is only the beginning. Conftest supports many more configuration files like JSON, XML and Dockerfile. Writing policies for all these and running them in your pipeline is a strong way to help guarantee certain standards for your configuration files and could prevent issues that would otherwise stay hidden until deployment.

    For more information on Conftest reference their documentation. Make sure to check out the documentation for Open Policy Agent as well. There you will find their syntax, Rego, explained in detail.

    Share this

Remco Westerhoud

View profile

Related blogs

  • Mijn ontwikkelpad

    Mijn ontwikkelpad Stephan Versteegh - 2 years ago

  • Verantwoordelijkheid pakken in jouw eigen persoonlijke …

    Verantwoordelijkheid pakken in jouw eigen persoonlijke … Stephan Versteegh - 2 years ago

  • TestBash Netherlands 2018

    TestBash Netherlands 2018 Rouke Broersma - 4 years ago

Data Discovery Channel

  • Explainable AI - Break open the blackbox

  • Toekomstvaste microservice data architecturen

  • Modern Data Platform

Nieuwsbrief

* verplichte velden

Contact

  • Head office NL
  • Kruisboog 42
  • 3905 TG Veenendaal
  • T +31 318 552020
  • Call
  • Mail
  • Directions
  • Head office BE
  • Generaal De Wittelaan 17
  • bus 30 2800 Mechelen
  • T +32 15 286370
  • Call
  • Mail
  • Directions

Follow us

  • Twitter
  • Facebook
  • Linkedin
  • Youtube

Newsletter

Sign in

Extra

  • Media Library
  • Disclaimer
  • Algemene voorwaarden
  • ISHBS Webmail
  • Extranet
Beheer cookie toestemming
Deze website maakt gebruik van Functionele en Analytische cookies voor website optimalisatie en statistieken.
Functioneel Always active
De technische opslag of toegang is strikt noodzakelijk voor het legitieme doel het gebruik mogelijk te maken van een specifieke dienst waarom de abonnee of gebruiker uitdrukkelijk heeft gevraagd, of met als enig doel de uitvoering van de transmissie van een communicatie over een elektronisch communicatienetwerk.
Voorkeuren
De technische opslag of toegang is noodzakelijk voor het legitieme doel voorkeuren op te slaan die niet door de abonnee of gebruiker zijn aangevraagd.
Statistieken
De technische opslag of toegang die uitsluitend voor statistische doeleinden wordt gebruikt. De technische opslag of toegang die uitsluitend wordt gebruikt voor anonieme statistische doeleinden. Zonder dagvaarding, vrijwillige naleving door uw Internet Service Provider, of aanvullende gegevens van een derde partij, kan informatie die alleen voor dit doel wordt opgeslagen of opgehaald gewoonlijk niet worden gebruikt om je te identificeren.
Marketing
De technische opslag of toegang is nodig om gebruikersprofielen op te stellen voor het verzenden van reclame, of om de gebruiker op een website of over verschillende websites te volgen voor soortgelijke marketingdoeleinden.
Manage options Manage services Manage vendors Read more about these purposes
Voorkeuren
{title} {title} {title}