Skip to main content

Jenkins Integration

Integrate Cloudgeni security scanning into your Jenkins pipelines to automatically check Infrastructure as Code for security issues during your build process.

What You'll Get

  • Automated security scanning in your CI/CD pipeline
  • Build quality gates that block insecure code
  • Pipeline integration with declarative and scripted syntax
  • Detailed reports published as build artifacts
  • Webhook triggers for automated scanning

Prerequisites

  • Jenkins server with Pipeline plugin installed
  • Cloudgeni account and API key
  • Repository containing IaC files (.tf, .bicep, .hcl, .yaml, etc.)

Quick Start

Step 1: Create API Key

  1. Go to SettingsAPI Keys in Cloudgeni
  2. Click Create API Key
  3. Name it jenkins
  4. Copy the generated key

Step 2: Add Jenkins Credential

  1. Go to Manage JenkinsManage Credentials
  2. Select appropriate domain (or Global)
  3. Click Add Credentials
  4. Configure:
    • Kind: Secret text
    • Secret: Your Cloudgeni API key
    • ID: cloudgeni-api-key
    • Description: Cloudgeni API Key
  5. Click OK

Step 3: Create Pipeline

Create a Jenkinsfile in your repository:
pipeline {
    agent any

    environment {
        CLOUDGENI_API_KEY = credentials('cloudgeni-api-key')
    }

    stages {
        stage('Security Scan') {
            steps {
                sh '''
                    curl -sSL https://get.cloudgeni.ai/install.sh | bash
                    cloudgeni scan --api-key $CLOUDGENI_API_KEY
                '''
            }
        }
    }
}

Configuration Options

Scanner Options

OptionDescriptionDefault
--api-keyCloudgeni API keyRequired
--fail-on-criticalExit 1 on critical findingsfalse
--fail-on-highExit 1 on high findingsfalse
--pathDirectory to scan.
--excludePaths to excludeNone
--outputOutput format (text, json, junit)text

Basic Stage

stage('Security Scan') {
    steps {
        sh 'cloudgeni scan --api-key $CLOUDGENI_API_KEY'
    }
}

Strict Mode

stage('Security Scan') {
    steps {
        sh '''
            cloudgeni scan \
                --api-key $CLOUDGENI_API_KEY \
                --fail-on-critical \
                --fail-on-high
        '''
    }
}

Pipeline Examples

Declarative Pipeline

pipeline {
    agent any

    environment {
        CLOUDGENI_API_KEY = credentials('cloudgeni-api-key')
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Security Scan') {
            steps {
                sh '''
                    curl -sSL https://get.cloudgeni.ai/install.sh | bash
                    cloudgeni scan --api-key $CLOUDGENI_API_KEY --fail-on-critical
                '''
            }
        }

        stage('Terraform Plan') {
            steps {
                sh '''
                    terraform init
                    terraform plan -out=tfplan
                '''
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: '**/cloudgeni-report.*', allowEmptyArchive: true
        }
    }
}

Scripted Pipeline

node {
    def cloudgeniKey = credentials('cloudgeni-api-key')

    stage('Checkout') {
        checkout scm
    }

    stage('Install Cloudgeni') {
        sh 'curl -sSL https://get.cloudgeni.ai/install.sh | bash'
    }

    stage('Security Scan') {
        try {
            sh "cloudgeni scan --api-key ${cloudgeniKey} --fail-on-critical --output json > cloudgeni-report.json"
        } catch (err) {
            currentBuild.result = 'UNSTABLE'
            echo "Security findings detected: ${err}"
        } finally {
            archiveArtifacts 'cloudgeni-report.json'
        }
    }

    stage('Plan') {
        if (currentBuild.result != 'UNSTABLE') {
            sh 'terraform plan'
        }
    }
}

Production Pipeline

pipeline {
    agent any

    environment {
        CLOUDGENI_API_KEY = credentials('cloudgeni-api-key')
        TF_ROOT = 'infrastructure'
    }

    options {
        timeout(time: 30, unit: 'MINUTES')
        disableConcurrentBuilds()
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install Tools') {
            steps {
                sh '''
                    # Install Cloudgeni
                    curl -sSL https://get.cloudgeni.ai/install.sh | bash

                    # Verify installation
                    cloudgeni --version
                '''
            }
        }

        stage('Security Scan') {
            steps {
                dir("${TF_ROOT}") {
                    sh '''
                        cloudgeni scan \
                            --api-key $CLOUDGENI_API_KEY \
                            --fail-on-critical \
                            --fail-on-high \
                            --output json > ../cloudgeni-report.json
                    '''
                }
            }
            post {
                always {
                    archiveArtifacts artifacts: 'cloudgeni-report.json', allowEmptyArchive: true
                }
            }
        }

        stage('Terraform Init') {
            steps {
                dir("${TF_ROOT}") {
                    sh 'terraform init'
                }
            }
        }

        stage('Terraform Plan') {
            steps {
                dir("${TF_ROOT}") {
                    sh 'terraform plan -out=tfplan'
                }
            }
        }

        stage('Approval') {
            when {
                branch 'main'
            }
            steps {
                input message: 'Deploy to production?', ok: 'Deploy'
            }
        }

        stage('Terraform Apply') {
            when {
                branch 'main'
            }
            steps {
                dir("${TF_ROOT}") {
                    sh 'terraform apply -auto-approve tfplan'
                }
            }
        }
    }

    post {
        failure {
            emailext(
                subject: "Security Scan Failed: ${currentBuild.fullDisplayName}",
                body: "Security issues detected. Check build: ${env.BUILD_URL}",
                recipientProviders: [requestor()]
            )
        }
    }
}

Multi-Branch Pipeline

pipeline {
    agent any

    environment {
        CLOUDGENI_API_KEY = credentials('cloudgeni-api-key')
    }

    stages {
        stage('Security Scan') {
            steps {
                script {
                    def scanArgs = '--api-key $CLOUDGENI_API_KEY --fail-on-critical'

                    // Stricter checks for main branch
                    if (env.BRANCH_NAME == 'main') {
                        scanArgs += ' --fail-on-high'
                    }

                    sh "cloudgeni scan ${scanArgs}"
                }
            }
        }
    }
}

Docker Agent

Using Docker for consistent environments:
pipeline {
    agent {
        docker {
            image 'cloudgeni/scanner:latest'
        }
    }

    environment {
        CLOUDGENI_API_KEY = credentials('cloudgeni-api-key')
    }

    stages {
        stage('Scan') {
            steps {
                sh 'cloudgeni scan --api-key $CLOUDGENI_API_KEY'
            }
        }
    }
}

Reports and Artifacts

JUnit Report

Publish as test results:
stage('Security Scan') {
    steps {
        sh 'cloudgeni scan --api-key $CLOUDGENI_API_KEY --output junit > security-results.xml'
    }
    post {
        always {
            junit 'security-results.xml'
        }
    }
}

HTML Report

Generate HTML report:
stage('Security Scan') {
    steps {
        sh 'cloudgeni scan --api-key $CLOUDGENI_API_KEY --output html > security-report.html'
    }
    post {
        always {
            publishHTML(target: [
                allowMissing: false,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: '.',
                reportFiles: 'security-report.html',
                reportName: 'Security Report'
            ])
        }
    }
}

JSON Artifact

Archive JSON report:
post {
    always {
        archiveArtifacts artifacts: '**/cloudgeni-report.json', allowEmptyArchive: true
    }
}

Webhook Triggers

GitHub Webhook

Configure webhook to trigger on push:
  1. In Jenkins, create a new Pipeline job
  2. Configure Build TriggersGitHub hook trigger for GITScm polling
  3. In GitHub, add webhook pointing to Jenkins

GitLab Webhook

  1. Install GitLab plugin in Jenkins
  2. Configure GitLab connection in Jenkins
  3. Enable Build when a change is pushed to GitLab
  4. Add webhook in GitLab project settings

Shared Libraries

Create reusable scanning function:
// vars/cloudgeniScan.groovy
def call(Map config = [:]) {
    def apiKey = config.apiKey ?: 'cloudgeni-api-key'
    def path = config.path ?: '.'
    def failOnCritical = config.failOnCritical ?: true
    def failOnHigh = config.failOnHigh ?: false

    withCredentials([string(credentialsId: apiKey, variable: 'CLOUDGENI_API_KEY')]) {
        def args = "--api-key ${CLOUDGENI_API_KEY} --path ${path}"
        if (failOnCritical) args += ' --fail-on-critical'
        if (failOnHigh) args += ' --fail-on-high'

        sh "cloudgeni scan ${args}"
    }
}
Use in pipeline:
@Library('my-shared-library') _

pipeline {
    agent any
    stages {
        stage('Security') {
            steps {
                cloudgeniScan(
                    path: './infrastructure',
                    failOnCritical: true,
                    failOnHigh: true
                )
            }
        }
    }
}

Troubleshooting

Credential Not Found:
  • Verify credential ID matches
  • Check credential scope includes the job
  • Ensure credential type is correct (Secret text)
Command Not Found:
  • Verify installation step completed
  • Check PATH includes Cloudgeni binary
  • Try using full path to binary
Permission Denied:
  • Check workspace permissions
  • Verify Jenkins user can execute scripts
  • Review file permissions on IaC files
Build Timeout:
  • Add timeout to pipeline options
  • Consider scanning specific paths
  • Check for large files in repository
No Test Results:
  • Verify output format is junit
  • Check file path in junit step
  • Ensure scan completed successfully