- Notifications
You must be signed in to change notification settings - Fork44
Jenkins CI/CD - Advanced Jenkinsfile & Groovy Shared Library of reusable functions and pipelines - AWS, GCP, Docker, Kubernetes, ArgoCD, Slack notifications, Git Merge, Terraform, Cloudflare, Jenkins Job Backups, most major Docker registries, DockerHub, GHCR, ECR, GCR, GAR, ACR, GitLab, Quay
License
HariSekhon/Jenkins
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Advanced Jenkinsfile & Jenkins Shared Library.
- Jenkinsfile - epic Jenkinsfile template - full of real-world tricks from Production
- vars/ - Groovy Shared Library reusable functions - used in Production for years
Additional Jenkins scripts are available in myHariSekhon/DevOps-Bash-tools repo for Jenkins Rest API and Jenkins Groovy scripts for the Admin Script Console, and Jenkins-on-Kubernetes in myHariSekhon/Kubernetes-configs repo.
HariSekhon/Knowledge-Base - Jenkins
HariSekhon/Knowledge-Base - Jenkins-on-Kubernetes
Jenkinsfile:
// load this library straight from github - the '_' at the end imports all functions@Library('github.com/harisekhon/jenkins@master') _pipeline { stages { stage('Simple Example'){ steps {// call any function from this libary by its filename under vars/... without the .groovy extension//// see each var/<function>.groovy file for any arguments//// calls vars/printEnv.groovy printEnv()// run logins for anything you have environment variable secrets/tokens for,// including AWS, GCP, DockerHub, GHCR, ECR, GCR, GAR, ACR, GitLab, Quay// see examples of individual service login functions in the next Stage login()// show all the cloud systems you're logged in to and who you're logged in as printAuth()// uses whichever package manager is available - portable, used by other functions too installPackages(['curl','unzip'])// launch a GCP Cloud Build job, by default against your cloudbuild.yaml if no args given gcpCloudBuild()// download tools to $HOME/bin downloadTerraform('1.2.3') downloadJenkinsCLI()// prompts for human click approval before proceeding to next step ie. production deployment approval()// GitOps update docker image version for app1 & app2 in Kubernetes Kustomize gitKustomizeImage(['myrepo/app1','myrepo/app2'])// trigger ArgoCD deployment to Kubernetes for app 'my-app' argoDeploy('my-app')// see groovy files under vars/ for more documentation, details and many more useful functions } } }// send notifications on broken builds and recoveries post { failure {// finds Git committers who broke build,// resolves their Slack user IDs and// actively notifies them with @user1 @user2 tags slackNotify() } fixed {// calls one or more notify functions to send Slack messages, emails etc.// such as slackNotify()// Uppercase N because lowercase clashes with java keyword// Use Notify() instead of multiple calls to different notify functionsNotify() } }}
some slightly more advanced functions:
@Library('github.com/harisekhon/jenkins@master') _pipeline { stages { stage('Advanced Example'){ steps {// run individual login functions instead of login()// log in to GCP cloud with a service account key gcpActivateServiceAccount()// set up GOOGLE_APPLICATION_CREDENTIALS keyfile for 3rd party apps like Terraform gcpSetupApplicationCredentials()// log in to DockerHub dockerLogin()// log in to AWS Elastic Container Registry dockerLoginECR()// log in to Google Container Registry dockerLoginGCR()// flexible custom targeted binary downloads instead of convenience functions like downloadTerraform(), downloadJenkinsCLI()://// download, extract and install a specific version of a binary to /usr/local/bin if root or $HOME/bin if run as a user// here ${version} is a variable previously defined, while {os} and {arch} with no dollar sign are auto-inferred placeholders installBinary(url:"https://releases.hashicorp.com/terraform/${version}/terraform_${version}_{os}_{arch}.zip",binary:'terraform') installBinary(url:"$JENKINS_URL/jnlpJars/jenkins-cli.jar")// run a script with locks to prevent another script or deployment happening at same time// newer runs will wait to acquire the locks, older pending runs will be skipped// third arg is optional to time out this script after 30 minutes scriptLockExecute('/path/to/script.sh', ['deployment lock','script lock'],30)// GitOps update docker image version for app1 & app2 in Kubernetes Kustomize, images served from GCR registry gitKustomizeImage(["$GCR_REGISTRY/$GCR_PROJECT/app1","$GCR_REGISTRY/$GCR_PROJECT/app2"])// parallelizes deployments by triggering syncs before deployment wait// if you want to save an extra 30 secs, use 2 parallel stages for these 2 syncs argoSync('app1') argoSync('app2')// waits on each app being fully deployed and passing healthchecks argoDeploy('app1') argoDeploy('app2') } } }}
Builds Docker images and deploys them toKubernetes viaArgoCD. Optionally scans the repo code, built container images, and purges Cloudflare Cache.
@Library('github.com/harisekhon/jenkins@master') _gcpDeployKubernetesPipeline(project:'my-gcp-project',region:'europe-west2',app:'my-app',env:'uk-production',images: ["my-app-webapp","my-app-sidecar", ],gcr_registry:'eu.gcr.io',gcp_serviceaccount_key:'jenkins-gcp-serviceaccount-key',// Jenkins credential idcloudflare_email:'my-cicd-account@domain.co.uk',// optional, triggers Cloudflare Cache Purgecloudflare_zone_id:'12a34b5c6d7ef8a901b2c3def45ab6c7',// if both these are set and Jenkins 'cloudflare-api-key' credential is available)
SeegcpDeployKubernetesPipeline.groovy for more details, options etc.
SeeJenkins on Kubernetes Diagram further down.
Handles all logins, Terraform fmt, validate, plan, approval, apply etc.
Non-apply branches do Plan only so you can see if you want to merge.
On the apply branch, eg.master
ormain
, only prompts for approval is there are actual changes in the Terraform plan output.
Saves the Terraform plan output and an approval will only apply that exact plan for safety.
@Library('github.com/harisekhon/jenkins@master') _terraformPipeline(version:'1.1.7',dir:'deployments/dev',apply_branch_pattern:'master',creds: [ string(credentialsId:'jenkins-gcp-serviceaccount-key',variable:'GCP_SERVICEACCOUNT_KEY') ],container:'gcloud-sdk',yamlFile:'ci/kubernetes-agent-pod.yaml')
Applied, ignoring informational fmt check:
Plan found no changes so skipped Apply or asking for Approval:
Plan found changes but Approval was not authorized, so Apply did not proceed:
https://github.com/HariSekhon/Terraform
Automatically merge one branch into another upon any change eg. backport between environment branches such as any hotfixes in Staging to Dev:
@Library('github.com/harisekhon/jenkins@master') _// git merge from staging branch into dev branchgitMergePipeline('staging','dev')
Enumerates all Jenkins Jobs and Git Tags and Branches to give user a pop-up with parameter choices about which Pipeline's Jenkinsfile to update its@Library
tag for, and optionally build that pipeline afterwards.
@Library('jenkins@master') _jenkinsfileLibraryUpdatePipeline(env: ["JENKINS_USER_ID=hari@domain.co.uk","JENKINS_CLI_ARGS=-webSocket" ],creds: [string(credentialsId:'job-config-backups',variable:'JENKINS_API_TOKEN')],container:'gcloud-sdk',yamlFile:'ci/kubernetes-agent-pod.yaml')
Download and commit all Jenkins job configurations to the calling Git repo every 3 hours (configurable via optionalcron: '...'
parameter)
@Library('github.com/harisekhon/jenkins@master') _jenkinsBackupJobConfigsPipeline(dir:'jobs',// directory in current repo to download and git commit toenv: ["JENKINS_USER_ID=hari@mydomain.co.uk","JENKINS_CLI_ARGS=-webSocket"// -webSocket gets through reverse proxies like Kubernetes Ingress ],creds: [ string(credentialsId:'jenkins-api-token',variable:'JENKINS_API_TOKEN') ],container:'gcloud-sdk',yamlFile:'ci/kubernetes-agent-pod.yaml'))
Read the comments at the top of each library function undervars/<function>.groovy
for more details.
If you want to prevent changes to this library re-triggering the last run of your pipelines, configure it as a a Shared Library in your global Jenkins configuration and untick "Include @Library changes in job recent changes".
See thisJenkins Documentation for more details.
For more excellent diagrams like this, see my Diagrams-as-Code repo:
https://github.com/HariSekhon/Diagrams-as-Code
Import the library as shown above directly from this repo, replacing@master
with@<hashref>
to fix to an immutable version (tags are not immutable). This is a GitHub security best practice for CI/CD as seen in thisdoc.
Fork this repo for more control and visibility over all updates.
Enable thefork-sync github actions workflow in your fork to keep the master branch sync'd every few hours.
You can then create tags or environment branches to stage updates across dev/staging/production.
If using environment branches, enable thefork-update-pr github actions workflow to automatically raise GitHub Pull Requests for your environment branches to audit, authorize & control updates.
Download the functions you want into your private jenkins shared library repo.
You can use thevars/download.sh script to help you download given*.groovy
files and periodically run it to get updates to these previously downloaded functions.
You will be responsible for committing and reconciling any divergences in your local copies.
The rest of my original source repos arehere.
Pre-built Docker images are available on myDockerHub.
About
Jenkins CI/CD - Advanced Jenkinsfile & Groovy Shared Library of reusable functions and pipelines - AWS, GCP, Docker, Kubernetes, ArgoCD, Slack notifications, Git Merge, Terraform, Cloudflare, Jenkins Job Backups, most major Docker registries, DockerHub, GHCR, ECR, GCR, GAR, ACR, GitLab, Quay