In this post I want to show another step in using PODs as Jenkins agents. I have already shown how to use Jenkins – Agents in Kubernetes., how to Jenkins – Pods, Containers and Pipelines, Jenkins – Pod Template at Pipeline runtime., Jenkins – Shared Libraries, Containers and Manifests. and now, I will show how to declare the POD manifest dynamically.
https://github.com/faustobranco/devops-db/tree/master/knowledge-base/jenkins/Dynamic_PodTemplate
This way, we will use a function in Shared Library (Jenkins – Shared Libraries) to generate the manifest, this makes the creation of PODs extremely flexible.
The example I’m going to leave here is extremely simple, even to show how it works, so it’s easier to understand and I leave the complexity of the code up to each person’s needs. Note that this way the complexity can increase a lot, and opens up countless ways to create the manifest, you can even create it in Groovy, use a file template, call other libraries in Java, Python, search in Consul, etc, etc, etc.
So to get started, I created a function called GeneratePodTemplate and added it to our Shared Library. Its operation is as simple as possible, as said before, just to show how to make a call, parameters and return of the manifest, I leave the logic inside the function to you.
The function, in this example, receives two parameters, a string “build ID” and another with the name of the image to be used.
The return is the assembled manifest, in string format.
GeneratePodTemplate.groovy (https://github.com/faustobranco/devops-db/blob/master/knowledge-base/jenkins/Dynamic_PodTemplate/shared-library/vars/GeneratePodTemplate.groovy)
def call(str_Build_id, str_image) {
def obj_PodTemplate = """
apiVersion: v1
kind: Pod
metadata:
labels:
some-label: "pod-template-${str_Build_id}"
spec:
containers:
- name: container-1
image: "${str_image}"
env:
- name: CONTAINER_NAME
value: "container-1"
volumeMounts:
- name: shared-volume
mountPath: /mnt
command:
- cat
tty: true
volumes:
- name: shared-volume
emptyDir: {}
"""
return obj_PodTemplate
}
With this, we will use the same pipeline model that we used in previous k8s posts. Don’t worry about the content of the Stages, they are just examples, in this case, without any function.
See that in the pipeline kubernetes agent declaration, I call the function created above in Yaml, with the two parameters (which can even be used as in the pipeline parameters post).
pipeline.groovy (https://github.com/faustobranco/devops-db/blob/master/knowledge-base/jenkins/Dynamic_PodTemplate/dynamic-pod/pipeline.groovy)
@Library('devopsdb-global-lib') _
import devopsdb.utilities.Utilities
def obj_Utilities = new Utilities(this)
pipeline {
agent {
kubernetes {
yaml GeneratePodTemplate('1234-ABCD', 'registry.devops-db.internal:5000/img-jenkins-devopsdb:2.0')
retries 2
}
}
options { timestamps ()
skipDefaultCheckout(true)
}
stages {
stage('Script') {
steps {
container('container-1') {
script {
def str_folder = "${env.WORKSPACE}/pipelines/python/log"
def str_folderCheckout = "/python-log"
obj_Utilities.CreateFolders(str_folder)
obj_Utilities.SparseCheckout('git@gitlab.devops-db.internal:infrastructure/pipelines/tests.git',
'master',
str_folderCheckout,
'usr-service-jenkins',
str_folder)
}
}
}
}
stage('Cleanup') {
steps {
cleanWs deleteDirs: true, disableDeferredWipeout: true
}
}
}
}
The result of executing the pipeline can be seen below. Note that in the Log, the image and the label ‘some-label’ are the parameters sent in the function.