Create Jenkins Pipeline Using Groovy and Integrate with the Github and Kubernets

ankit
7 min readAug 30, 2020

--

What is Groovy ?

Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming.

What is Jenkins Pipeline ?

Jenkins Pipeline (or simply “Pipeline” with a capital “P”) is a suite of plugins which supports implementing and integrating continuous delivery pipelines into Jenkins.

A continuous delivery (CD) pipeline is an automated expression of your process for getting software from version control right through to your users and customers. Every change to your software (committed in source control) goes through a complex process on its way to being released. This process involves building the software in a reliable and repeatable manner, as well as progressing the built software (called a “build”) through multiple stages of testing and deployment.

Pipeline provides an extensible set of tools for modeling simple-to-complex delivery pipelines “as code” via the Pipeline domain-specific language (DSL) syntax.

The definition of a Jenkins Pipeline is written into a text file (called a Jenkinsfile) which in turn can be committed to a project’s source control repository. This is the foundation of “Pipeline-as-code”; treating the CD pipeline a part of the application to be versioned and reviewed like any other code.

Creating a Jenkinsfile and committing it to source control provides a number of immediate benefits:

  • Automatically creates a Pipeline build process for all branches and pull requests.
  • Code review/iteration on the Pipeline (along with the remaining source code).
  • Audit trail for the Pipeline.
  • Single source of truth for the Pipeline, which can be viewed and edited by multiple members of the project.

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

Declarative versus Scripted Pipeline syntax

A Jenkinsfile can be written using two types of syntax – Declarative and Scripted.

Declarative and Scripted Pipelines are constructed fundamentally differently. Declarative Pipeline is a more recent feature of Jenkins Pipeline which:

  • provides richer syntactical features over Scripted Pipeline syntax, and
  • is designed to make writing and reading Pipeline code easier.

Many of the individual syntactical components (or “steps”) written into a Jenkinsfile, however, are common to both Declarative and Scripted Pipeline. Read more about how these two types of syntax differ in Pipeline concepts and Pipeline syntax overview below.

Problem Statement :

1. Create container image that’s has Jenkins installed using dockerfile Or You can use the Jenkins Server on RHEL 8/7.

2. When we launch this image, it should automatically starts Jenkins service in the container.

3. Create a job chain of job1, job2, job3 and job4 using build pipeline plugin in Jenkins.

4. Job2 ( Seed Job ) : Pull the Github repo automatically when some developers push repo to Github.

5. Further on jobs should be pipeline using written code using Groovy language by the developer

6. Job1 : A. By looking at the code or program file, Jenkins should automatically start the respective language interpreter installed image container to deploy code on top of Kubernetes ( eg. If code is of PHP, then Jenkins should start the container that has PHP already installed )

B. Expose your pod so that testing team could perform the testing on the pod

C. Make the data to remain persistent using PVC ( If server collects some data like logs, other user information )

7. Job3 : Test your app if it is working or not.

8. Job4 : if app is not working , then send email to developer with error messages and redeploy the application after code is being edited by the developer.

First of all we have to create the docker image which jenkins as well as kubectl configured.

Here we have the genrate the script using Groovy language. In this particular task we don’t need to configure every job of jenkins we have to only create the job and seed job automatically configure all the jobs according to the script of Groovy language.Before did this we have to install some plugin of jenkins which are helpful in running the script. This is the concept Self-Service means in this system developer write the program code as well as write the code for jenkins jobs . This is the real meaning of DevOps in which some work of operational team done by the developer team.

Download the following Jenkins plugins

  1. PostBuildScript
  2. Job DSL

Here we have the seed job generate_job.

GROOVY LANGUAGE SCRIPT FOR CONFIGURE ALL THE JOBS :

JOB1:

This job is triggered when developer push some the repo/code from Git to Github then jenkins automatically download the code. In the job1 we use poll scm to see the code of Github if somethink is changed then it trigger the job1.

job("task6_job1") {
description("Download the data from github")
scm {
github('whytedork/devopstask6')
}
triggers {
scm(" * * * * * ")
}
steps {
shell("sudo cp -rvf * /root/devops_task6")
}
}

JOB2:

In this job we check the code file extension and according to the code type Jenkins should automatically start the respective language interpreter installed image container to deploy code on top of Kubernetes. Expose your pod so that testing team could perform the testing on the pod. Also make the data to remain persistent ( If server collects some data like apache logs).

job("task6_job2") {
description("checking the code and launching the pods")
triggers {
upstream('task6_job1' , 'SUCCESS')
}
steps {
shell('''sudo python3 /root/devops_task6/extension.py
sleep 60''')
}
}

Deployment for code by using yaml file:

apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
labels:
app: webapp
spec:
selector:
matchLabels:
app: webapp
env: production
template:
metadata:
name: myweb-pod
labels:
env: production
app: webapp
spec:
containers:
- name: myweb-con
image: hemant123/myweb:v1
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/local/apache2/htdocs"
name: jenkins-pvc
volumes:
- name: jenkins-pvc
persistentVolumeClaim:
claimName: pv-claim-jenkins

Exposing the service by using yaml file:

apiVersion: v1
kind: Service
metadata:
name: myweblb
spec:
selector:
app: webapp
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 31000

Create PVC for storing the logs of apache web server by yaml file:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-claim-jenkins
labels:
app: webapp
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

JOB3:

In this job we check the status code of the code.Mainly it is the testing job.

job("task6_job3") {
description("Testing the code by seeing its status code")
triggers {
upstream('task6_job2' , 'SUCCESS')
}
steps {
shell('''status1=$(curl -s -o /dev/null -sw "%{http_code}"
http://192.168.99.108:31000/index.html)
if [ $status1 == '200' ]
then
echo "webpage code is good"
exit 0
else
echo "webpage code is not good"
exit 0
fi''')
}
}

JOB4:

If the code is not running properly then this job send the mail to the developer and remove all the pods , services as well as persistent volume.

job("task6_job4") {
description("Sending Email if error occur in the code otherwise not")
triggers {
upstream('task6_job3' , 'SUCCESS')
}
steps {
shell('''if [ $(curl -s -o /dev/null -w "%{http_code}"
192.168.99.108:31000/test.html) == '200' ]
then
echo "code is good"
exit 0
else
echo "code is not right"
sudo python3 /root/devops_task6/sendemail.py
sudo cd /root/devops_task6/
sudo rm -f *
sudo kubectl delete all --all
sudo kubectl delete pvc --all
exit 0
fi''')
}
}

--

--