Documentation / Tools and Integrations

CLI for CI

CLI for CI

Run Prancer's IaC static analysis (SCA) directly inside your CI pipeline — GitHub Actions, Azure DevOps, GitLab CI, Jenkins, anything that can execute shell. The CLI clones your IaC repo, evaluates it against the compliance configured in your Prancer collection, and fails the build on policy violations.

Before you start

  • A Prancer collection created via the Configuration Wizard for the Git repo you want to scan.
  • A Prancer API token — see Token.
  • A Git personal access token with repo and user permissions.
  • A CI runner with the binaries below installed.

Required binaries on the CI runner

| Binary | Purpose |

| --- | --- |

| prancer-basic | The Prancer CLI itself. |

| OPA | Rego policy evaluation. |

| Helm | Required only if you scan Helm charts. |

Install the Prancer CLI

pip3 install -U prancer-basic

To make sure prancer is installed successfully, you can run this command:

  $ prancer --version
  Prancer 2.0.21

For the complete installation description, you can visit the following URL: Prancer Installation

Setup on Prancer SaaS solution

New collection

Create a new collection from the Configuration Wizard for the git repository you want to do the security scan. To understand how to use the Configuration Wizard, you can review this post

CI Variables

Defining variables in CI tool to run Prancer CLI in your pipeline, you need to define some variables.

Prancer API token

Generate a user access token from Prancer SaaS solution How to generate token in Prancer SaaS

You should define this variable as APITOKEN in your CI tool. Add this as a secret.

Github token

you need to generate a new personal access token for prancer with the following permissions: Repo permission / User permission You should define this variable as GITTOKEN in your CI tool. Add this as a secret as well.

How to run

To integrate Prancer CLI into your CI tool, you need to have the base structure and run the appropriate commands.

-> The easiest way is to clone the following repo for the base structure files Sample GitHub Actions file

Run the following command:

    collection_name="the name of the collection from prancer saas"
    company_name="the name of your company in prancer tenant."

    prancer $collection_name --db REMOTE --company $company_name

Link to the repo with the base structure: Prancer Armof

Link to the sample GitHub Actions pipeline: Sample GitHub Actions file

# This is a basic workflow to help you get started with Actions

name: Prancer CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the master branch
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a set of commands using the runners shell  
      - name: Install Prancer
        run: |
          pip3 install -U prancer-basic

      - name: Install opa 
        run: |
          echo "opa and helm binariees required, helm is packaged with ubuntu, install opa only"
          curl -L -o /usr/local/bin/opa https://openpolicyagent.org/downloads/v0.36.1/opa_linux_amd64_static
          chmod 755 /usr/local/bin/opa
          echo "opa binary path..."
          which opa
          echo "helm binary path..."
          which helm

      - name: Run Prancer
        run: |
          export APITOKEN=${{ secrets.APITOKEN }}
          export GITTOKEN=${{ secrets.GITTOKEN }}
          prancer --db REMOTE --company prancer-liquware armof

Running prancer-basic pipeline script

trigger:
  - master

resources:
  - repo: self

stages:
  - stage: prancer_static_code_analysis_for_iac
    displayName: "Prancer Static Code Analysis for IaC"
    jobs:
      - job: prancer_basic
        displayName: "prancer basic install in agent"
        pool: "Default"
        steps:
          - bash: |
              echo "Setup start"

              binary="pip3"
              ispresent=`which $binary`
              if [ -z $ispresent ]; then
              apt-get -y install python3-pip
              else
              echo "using existing pip3 path: $ispresent"
              fi

              pip3 install -U prancer-basic
              binary="opa"
              ispresent=`which $binary`
              if [ -z $ispresent ]; then
              curl -L -o /usr/local/bin/opa https://openpolicyagent.org/downloads/v0.36.1/opa_linux_amd64_static
              chmod 755 /usr/local/bin/opa
              else
              echo "using existing opa binary path: $ispresent"
              fi

              binary="helm"
              ispresent=`which $binary`
              if [ -z $ispresent ]; then
              snap install helm --classic
              else
              echo "using existing helm binary path: $ispresent"
              fi

              export APITOKEN=${APITOKEN}
              export GITTOKEN=${GITTOKEN}
              prancer --db REMOTE --company liquware --apitoken "${APITOKEN}" --gittoken "${GITTOKEN}" scenario_aws_githubEntNon
            env:
              GITTOKEN: $(GITTOKEN)
              APITOKEN: $(APITOKEN)

Running prancer-basic inside a docker image pipeline script

trigger:
  - master

resources:
  - repo: self

stages:
  - stage: prancer_basic_setup_pipeline
    displayName: "Prancer basic setup in pipeline"
    jobs:
      - job: prancer_basic
        displayName: "prancer basic install in agent"
        pool: "Default"
        steps:
          - bash: |
              echo "Setup start"

              # Creating Working Directory
              mkdir prancer
              cd prancer

              # Downloading setup.py from prancer-basic to find latest version
              curl -L -o setup.py https://raw.githubusercontent.com/prancer-io/cloud-validation-framework/master/setup.py
              version=`cat setup.py  | grep -i 'version=' | sed -e "s/version='//" | sed -e "s/',//" | sed -e 's/ //g'`

              echo $version

              # Creating temp dir for opa and helm
              mkdir helmdir opadir

              # Download opa binary
              curl -L -o opadir/opa https://openpolicyagent.org/downloads/v0.36.1/opa_linux_amd64_static
              chmod 755 opadir/opa

              # Download helm binary
              curl -L -o helmdir/helm-v3.8.1-linux-amd64.tar.gz https://get.helm.sh/helm-v3.8.1-linux-amd64.tar.gz
              tar -zxvf helmdir/helm-v3.8.1-linux-amd64.tar.gz -C helmdir
              chmod 755 helmdir/linux-amd64/helm

              # Creating Docker File

              cat << EOF >> Dockerfile
              FROM python:3.9-alpine3.15
              ENV APP_VERSION=$version
              RUN apk update     && apk upgrade     && apk add git build-base libffi-dev openssl-dev
              COPY opadir/opa /usr/local/bin/opa
              RUN chmod +x /usr/local/bin/opa
              COPY helmdir/linux-amd64/helm /usr/local/bin/helm
              RUN chmod +x /usr/local/bin/helm
              RUN pip install ply    
              RUN pip install prancer-basic==$version
              EOF

              # Building Docker image with prancer-basic as per version
              docker build -t prancer-basic:${version} -f Dockerfile .

              # Running Prancer-basic docker image with remote for scenario_aws_githubEntNon collection
              docker container run prancer-basic:${version} prancer --db REMOTE --company liquware --env QA --apitoken "${APITOKEN}" --gittoken "${GITTOKEN}" scenario_aws_githubEntNon
            env:
              GITTOKEN: $(GITTOKEN)
              APITOKEN: $(APITOKEN)