Wednesday, 24 January 2018

Pipeline as Code in Jenkins

Pipeline: pipeline defination
Agent: mention jenkins label/agent run

Tools: usage of existing jenkins tools from manage jenkins

While the syntax for defining a Pipeline, either in the web UI or with a Jenkinsfile, is the same, it’s generally considered best practice to define the Pipeline in a Jenkinsfile and check that in to source control.

Jenkinsfile (Declarative Pipeline):

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'make'
            }
        }
        stage('Test'){
            steps {
                sh 'make check'
                junit 'reports/**/*.xml'
            }
        }
        stage('Deploy') {
            steps {
                sh 'make publish'
            }
        }
    }
}

Pipeline Terms:

Step: A single task; fundamentally steps tell Jenkins what to do. For example, to execute the shell command make use the sh step: sh 'make'. When a plugin extends the Pipeline DSL, that typically means the plugin has implemented a new step.

Declarative Pipeline:
All valid Declarative Pipelines must be enclosed within a pipeline block, for example:

pipeline {
    /* insert Declarative Pipeline here */
}

The basic statements and expressions which are valid in Declarative Pipeline follow the same rules as Groovy’s syntax with the following exceptions:
  • The top-level of the Pipeline must be a block, specifically: pipeline { }
  • No semicolons as statement separators. Each statement has to be on its own line
  • Blocks must only consist of Sections, Directives, Steps, or assignment statements.
  • A property reference statement is treated as no-argument method invocation. So for example, input is treated as input()

Sections:
Sections in Declarative Pipeline typically contain one or more Directives or Steps

agent
The agent section specifies where the entire Pipeline, or a specific stage, will execute in the Jenkins environment depending on where the agent section is placed. The section must be defined at the top-level inside the pipeline block, but stage-level usage is optional

Parameters
In order to support the wide variety of use-cases Pipeline authors may have, the agent section supports a few different types of parameters. These parameters can be applied at the top-level of the pipeline block, or within each stage directive.
any
Execute the Pipeline, or stage, on any available agent. For example: agent any
none
When applied at the top-level of the pipeline block no global agent will be allocated for the entire Pipeline run and each stage section will need to contain its own agent section. For example: agent none
label
Execute the Pipeline, or stage, on an agent available in the Jenkins environment with the provided label. For example: agent { label 'my-defined-label' }
node
agent { node { label 'labelName' } } behaves the same as agent { label 'labelName' }, but node allows for additional options (such as customWorkspace).

Docker
Execute the Pipeline, or stage, with the given container which will be dynamically provisioned on a node pre-configured to accept Docker-based Pipelines, or on a node matching the optionally defined label parameter. docker also optionally accepts an argsparameter which may contain arguments to pass directly to a docker run invocation, and an alwaysPull option, which will force a docker pull even if the image name is already present. For example: agent { docker 'maven:3-alpine' } or

agent {
    docker {
        image
'maven:3-alpine'
        label
'my-defined-label'
        args 
'-v /tmp:/tmp'
    }
}

dockerfile
Execute the Pipeline, or stage, with a container built from a Dockerfile contained in the source repository.
In order to use this option, the Jenkinsfile must be loaded from either a Multibranch Pipeline, or a "Pipeline from SCM."
Conventionally this is the Dockerfile in the root of the source repository: agent { dockerfile true }.
If building a Dockerfile in another directory, use the dir option: agent { dockerfile { dir 'someSubDir' } }.
You can pass additional arguments to the docker build ...command with the additionalBuildArgs option, like agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }

Customworkspac:

agent {
    node {
        label
'my-defined-label'
        customWorkspace
'/some/other/path'
    }
}


reuseNode:
A boolean, false by default. If true, run the container on the node specified at the top-level of the Pipeline, in the same workspace, rather than on a new node entirely

This option is valid for docker and dockerfile, and only has an effect when used on an agent for an individual stage.
Example
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent { docker
'maven:3-alpine' }
    stages {
        stage(
'Example Build') {
            steps {
                sh
'mvn -B clean verify'
            }
        }
    }
}
Execute all the steps defined in this Pipeline within a newly created container of the given name and tag (maven:3-alpine)

Stage-level agent section:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent none
    stages {
        stage(
'Example Build') {
            agent { docker
'maven:3-alpine' }
            steps {
                echo
'Hello, Maven'
                sh
'mvn --version'
            }
        }
        stage(
'Example Test') {
            agent { docker
'openjdk:8-jre' }
            steps {
                echo
'Hello, JDK'
                sh
'java -version'
            }
        }
    }
}

  • Defining agent none at the top-level of the Pipeline ensures that an Executor will not be assigned unnecessarily.
  • Using agent none also forces each stage section contain its own agent section.
  • Execute the steps in this stage in a newly created container using this image.
  • Execute the steps in this stage in a newly created container using a different image from the previous stage.

Post:
The post section defines actions which will be run at the end of the Pipeline run or stage. A number of post-condition blocks are supported within the post section: alwayschangedfailuresuccessunstable, and aborted. These blocks allow for the execution of steps at the end of the Pipeline run or stage, depending on the status of the Pipeline.

Conditions:
always
Run regardless of the completion status of the Pipeline run.
changed
Only run if the current Pipeline run has a different status from the previously completed Pipeline.
failure
Only run if the current Pipeline has a "failed" status, typically denoted in the web UI with a red indication.
success
Only run if the current Pipeline has a "success" status, typically denoted in the web UI with a blue or green indication.
unstable
Only run if the current Pipeline has an "unstable" status, usually caused by test failures, code violations, etc. Typically denoted in the web UI with a yellow indication.
aborted
Only run if the current Pipeline has an "aborted" status, usually due to the Pipeline being manually aborted. Typically denoted in the web UI with a gray indication

Example:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage(
'Example') {
            steps {
                echo
'Hello World'
            }
        }
    }
    post {
        always {
            echo
'I will always say Hello again!'
        }
    }
}

Stages:
Containing a sequence of one or more stage directives, the stages section is where the bulk of the "work" described by a Pipeline will be located. At a minimum it is recommended that stages contain at least one stage directive for each discrete part of the continuous delivery process, such as Build, Test, and Deploy.

Example:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage(
'Example') {
            steps {
                echo
'Hello World'
            }
        }
    }
}

Steps:
The steps section defines a series of one or more steps to be executed in a given stage directive

Example:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage(
'Example') {
            steps {
                echo
'Hello World'
            }
        }
    }
}

Directives
Environment:
The environment directive specifies a sequence of key-value pairs which will be defined as environment variables for the all steps, or stage-specific steps, depending on where the environment directive is located within the Pipeline.

Example:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    environment {
        CC =
'clang'
    }
    stages {
        stage(
'Example') {
            environment {
                AN_ACCESS_KEY = credentials(
'my-prefined-secret-text')
            }
            steps {
                sh
'printenv'
            }
        }
    }
}

  • An environment directive used in the top-level pipeline block will apply to all steps within the Pipeline.
  • An environment directive defined within a stage will only apply the given environment variables to steps within the stage.
  • The environment block has a helper method credentials() defined which can be used to access pre-defined Credentials by their identifier in the Jenkins environment.

Options:
The options directive allows configuring Pipeline-specific options from within the Pipeline itself. Pipeline provides a number of these options, such as buildDiscarder, but they may also be provided by plugins, such as timestamps
Available Options:
buildDiscarder
Persist artifacts and console output for the specific number of recent Pipeline runs. For example: options { buildDiscarder(logRotator(numToKeepStr: '1')) }
disableConcurrentBuilds
Disallow concurrent executions of the Pipeline. Can be useful for preventing simultaneous accesses to shared resources, etc. For example: options { disableConcurrentBuilds() }
overrideIndexTriggers
Allows overriding default treatment of branch indexing triggers. If branch indexing triggers are disabled at the multibranch or organization label, options { overrideIndexTriggers(true) } will enable them for this job only. Otherwise, options { overrideIndexTriggers(false) } will disable branch indexing triggers for this job only.
skipDefaultCheckout
Skip checking out code from source control by default in the agent directive. For example: options { skipDefaultCheckout() }
skipStagesAfterUnstable
Skip stages once the build status has gone to UNSTABLE. For example: options { skipStagesAfterUnstable() }
timeout
Set a timeout period for the Pipeline run, after which Jenkins should abort the Pipeline. For example: options { timeout(time: 1, unit: 'HOURS') }
retry
On failure, retry the entire Pipeline the specified number of times. For example: options { retry(3) }
timestamps
Prepend all console output generated by the Pipeline run with the time at which the line was emitted. For example: options { timestamps() }
Example:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    options {
        timeout(
time: 1, unit: 'HOURS')
    }
    stages {
        stage(
'Example') {
            steps {
                echo
'Hello World'
            }
        }
    }
}
Specifying a global execution timeout of one hour, after which Jenkins will abort the Pipeline run.
Parameters:
The parameters directive provides a list of parameters which a user should provide when triggering the Pipeline. The values for these user-specified parameters are made available to Pipeline steps via the params object, see the Example for its specific usage.

Available Parameters:
  • string
A parameter of a string type, for example: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
  • booleanParam
A boolean parameter, for example: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
Example:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    parameters {
        string(
name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
    }
    stages {
        stage(
'Example') {
            steps {
                echo
"Hello ${params.PERSON}"
            }
        }
    }
}

Triggers:
The triggers directive defines the automated ways in which the Pipeline should be re-triggered. For Pipelines which are integrated with a source such as GitHub or BitBucket, triggers may not be necessary as webhooks-based integration will likely already be present. Currently the only two available triggers are cron and pollSCM.

Example:
Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    triggers {
        cron(
'H 4/* 0 0 1-5')
    }
    stages {
        stage(
'Example') {
            steps {
                echo
'Hello World'
            }
        }
    }
}

Stage:
The stage directive goes in the stages section and should contain a steps section, an optional agent section, or other stage-specific directives. Practically speaking, all of the real work done by a Pipeline will be wrapped in one or more stage directives.
Example:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage(
'Example') {
            steps {
                echo
'Hello World'
            }
        }
    }
}

Tools:
A section defining tools to auto-install and put on the PATH. This is ignored if agent none is specified.
Supported Tools
maven
jdk
gradle
Example
Jenkinsfile (Declarative Pipeline)

pipeline {
    agent any
    tools {
        maven
'apache-maven-3.0.1'
    }
    stages {
        stage(
'Example') {
            steps {
                sh
'mvn --version'
            }
        }
    }
}

Ansible: Roles

Use Ansible roles to orchestrate more complex configurations.Let's create a new directory named  nginx , which will be a Role. Then we&...