# Jenkins

This walkthrough will guide you through using Jenkins with CloudTruth enabling you to manage your multiple environments parameters and secrets from a centralized location.

## Prerequisites

* You have created one or more [CloudTruth Parameters](https://github.com/cloudtruth/ctdocs/blob/live/integrations/broken-reference/README.md).
* You have created a [CloudTruth API Access token](https://github.com/cloudtruth/ctdocs/blob/live/integrations/broken-reference/README.md).
* Working knowledge of [Jenkins](https://www.jenkins.io/doc/book/installing/).
* [Docker](https://docs.docker.com/) installed

## Install Jenkins with a Dockerfile

This example will install Jenkins as a [Docker image](https://www.jenkins.io/doc/book/installing/docker/) based on the official Jenkins guide. The Dockerfile will be customized to install the [CloudTruth CLI ](https://docs.cloudtruth.com/cli-and-api/cloudtruth-cli#installation)in the official [Jenkins image](https://hub.docker.com/r/jenkins/jenkins/). Secrets and variables will be passed directly into Jenkins pipelines with the CloudTruth CLI.

Create a [bridge network](https://docs.docker.com/network/bridge/) in Docker using the following command:

```
docker network create jenkins
```

Customize the official Jenkins Docker image:

```
FROM jenkins/jenkins:2.303.2-jdk11
USER root
RUN apt-get update && apt-get install -y apt-transport-https \
       ca-certificates curl gnupg2 \
       software-properties-common
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN apt-key fingerprint 0EBFCD88
RUN add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/debian \
       $(lsb_release -cs) stable"

RUN apt-get update && apt-get install -y docker-ce-cli

# Install the CloudTruth CLI
RUN (curl -sL https://github.com/cloudtruth/cloudtruth-cli/releases/latest/download/install.sh || wget -qO- https://github.com/cloudtruth/cloudtruth-cli/releases/latest/download/install.sh) | sh

USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean:1.25.0 docker-workflow:1.26"
```

Build a new docker image from this dockerfile:

```
docker build -t jenkins-cloudtruth:1 .
```

Run the customized image:

```
 docker run --name jenkins-blueocean --rm --detach \
 --network jenkins --env DOCKER_HOST=tcp://docker:2376 \
 --env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 \
 --publish 8080:8080 --publish 50000:50000 \
 --volume jenkins-data:/var/jenkins_home \
 --volume jenkins-docker-certs:/certs/client:ro \
 jenkins-cloudtruth:1
```

Obtain the admin password for your deploy once the container is running:

```
sudo docker exec jenkins-blueocean cat /var/jenkins_home/secrets/initialAdminPassword
```

Navigate to [http://localhost:8080](http://localhost:8080/) to login and customize Jenkins with a username of `admin` and the password you obtained from the previous step. You can Install Suggested plugins from this screen to complete setup and skip the rest of the configuration.

## Provide Jenkins Access to CloudTruth

Adding a [Jenkins global credential](https://www.jenkins.io/doc/book/using/using-credentials/#adding-new-global-credentials) for the CloudTruth API key allows a Jenkins pipeline to securely access parameters and secrets stored in CloudTruth.

Navigate to Dashboard -> Manage Credentials -> Jenkins store -> Global credentials -> Add:

Select the Credential Kind as `Secret text`.

Fill in the **Secret** field with a [generated CloudTruth API Access token](https://docs.cloudtruth.com/org-management/access-control/access-tokens) as a Jenkins Global Credential. Add a description which is used to reference the key in the pipeline then click OK.

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-fdf21a73adcb4f2731c1de76c34bb5daaa49baab%2Fimage%20\(240\)%20\(1\)%20\(1\).png?alt=media)

## Configure a Jenkins Pipeline with CloudTruth

#### Create a new pipeline

From the Jenkins dashboard select `New Item`. Provide a name, select pipeline and hit OK:

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-303887903d6b6c4ee000268a1556031a510dbb1f%2Fimage%20\(250\)%20\(1\)%20\(1\)%20\(1\)%20\(1\).png?alt=media)

#### Configure the CloudTruth API Key as a pipeline parameter

Select `This project is parameterized` and add a [`Credentials Parameter`](https://www.jenkins.io/doc/book/using/using-credentials/).

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-f88161876d4d6b7b395edf53804ac273c56ce702%2Fimage%20\(233\)%20\(1\)%20\(1\).png?alt=media)

Provide the parameter Name as `CLOUDTRUTH_API_KEY`. The CloudTruth CLI uses this variable to pull secrets and parameters from CloudTruth.

Select Default value as the [Global Credential](#provide-jenkins-access-to-cloudtruth) we created as the value for `CLOUDTRUTH_API_KEY` and mark the parameter as required.

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-78cce2be86ed2e0680ffd3a1a666055f239d546b%2Fimage%20\(251\)%20\(1\)%20\(1\)%20\(1\).png?alt=media)

#### Create pipeline environment variables from CloudTruth

Add the following pipeline script and click Save:

```
pipeline {
    environment {
        CLOUDTRUTH_API_KEY = credentials('CLOUDTRUTH_API_KEY')
        CLOUDTRUTH_PARAMETER = sh(script:'cloudtruth --project MyFirstProject --env default parameters get jenkins', returnStdout: true).trim()

    }
    agent any

    stages {
        stage('CloudTruth') {
            steps {
                echo "Retrieve Parameter from CloudTruth: ${env.CLOUDTRUTH_PARAMETER}"
                }
            }
        }
    }
```

This groovy script sets the `CLOUDTRUTH_API_KEY` using the Jenkins [credential](https://www.jenkins.io/doc/book/using/using-credentials/) value we specified as a pipeline parameter. It then populates an environment variable `CLOUDTRUTH_PARAMETER` with a sh script that calls the CLI. This allows variables to be used in downstream stages.

You can update the CLI command with your own parameter or create a parameter named `jenkins` in `MyFirstProject`.

You can use these CLI commands to set the variables used in this example:

```
cloudtruth --project MyFirstProject parameter set jenkins -v pipeline
cloudtruth --project MyFirstProject parameter set secret -v masked --secret true
```

{% hint style="info" %}
The environment variable for CLI access in the pipeline script must be named: `CLOUDTRUTH_API_KEY`
{% endhint %}

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-c685d38aa828c16a62d94339c72c2bdb7a1c12c4%2Fimage%20\(227\)%20\(1\).png?alt=media)

#### Build pipeline with parameters

From the pipeline click `Build with Parameters` and select `CloudTruth API Key` then click Build.

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-8b58b705794e71f6ddeb90fd919d1c032c929be1%2Fimage%20\(249\)%20\(1\)%20\(1\)%20\(1\).png?alt=media)

From the build page view the Console Output. The parameter value `pipeline` is successfully set and echoed in our pipeline stage!

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-cab40d72bfe0652fbb07adf01382ec361e7e0de4%2Fimage%20\(234\)%20\(1\).png?alt=media)

### Masking external secrets in a Jenkins Pipeline

Jenkins will automatically mask built in [credentials parameters](https://www.jenkins.io/doc/book/using/using-credentials/) like the CloudTruth API key. When using external secret stores we will call the [Mask Passwords](https://plugins.jenkins.io/mask-passwords/) plugin.

From the Plugin Manager search for Mask Passwords. Select the plugin and Install with a restart of Jenkins.

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-4a659031e49624a869b8e75631b6eaef391e164d%2Fimage%20\(228\)%20\(1\).png?alt=media)

We can now use the `MaskPasswordsBuildWrapper` and `withEnv` to wrap the CloudTruth secret returned from our CLI call.

The pipeline is built with the CloudTruth API key as described in [configuring a Jenkins pipeline](#configure-a-jenkins-pipeline-with-cloudtruth). We set a variable from a CloudTruth parameter called `secret` .

The following groovy is an example pipeline script that sets a masked environment variable using the plugin wrapper.

```
pipeline {
    environment {
        CLOUDTRUTH_API_KEY = credentials('CLOUDTRUTH_API_KEY')
    }
    agent any

    stages {
        stage('CloudTruth') {
            steps {
            script{
                CLOUDTRUTH_SECRET = sh(script:'cloudtruth --project MyFirstProject --env default parameters get secret', returnStdout: true).trim()
                wrap([$class: 'MaskPasswordsBuildWrapper', varPasswordPairs: [[password: CLOUDTRUTH_SECRET]]]) {  
                  withEnv(["SECRET=${CLOUDTRUTH_SECRET}"]){
                  sh 'echo Retrieve Secret from CloudTruth: $SECRET'
                  sh 'printenv'
            }
          }
        }
      }
    }
  }
}
```

As a result when viewing the console output the secret is masked in the echo. It is also masked when viewing an export of the current environment variables for the step.

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-6fb6ca529e6da55f68085620afac397caf15dddd%2FScreenshot%202021-11-11%20091731.png?alt=media)

With this technique the secrets are also masked in Blue Ocean build details.

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-32998cd8ca825f7ee8006cafbc0f2779a522bc97%2Fimage%20\(263\)%20\(1\)%20\(1\).png?alt=media)
