5

I want to create a Jenkins job which deploys Helm chart into Kubernetes cluster. Helm charts are stored into Bitbucket repository.

    pipeline {
        agent any
        stages {
            stage('Download Helm Charts') {
                steps {
                    sh "echo 'Downloading Helm Charts from Bitbucket repository...'"
                    git checkout http://192.168.1.30:7990/scm/jen/helm.git
                    // not sure do I need ot point the root folder of the Helm repository or only the single chart
                }
            }
            stage('Test Kubernetes version') {
                steps {
                    sh "echo 'Checking Kubernetes version..'"
                    // How to do remote test of kubernetes version
                }
            }
            stage('Push Helm Charts to Kubernetes') {
                steps {
                    sh "echo 'building..'"
                    // push here helm chart from Jenkins server to Kubernetes cluster
                }
            }     
            stage('Build Image') {
                steps {
                    sh "echo 'building..'"
                    git checkout http://192.168.1.30:7990/scm/jen/spring-boot-microservice.git
                    // execute Java -jar ... and build docker image
                }
            }
            stage('Push Image into Nexus registry') {
                steps {
                    sh "echo 'building..'"
                    // push compiled docker image into Nexus repository
                }
            }
            stage('Deploy Image from Nexus registry into Kubernetes') {
                steps {
                    sh "echo 'building..'"
                }
            }
            stage('Test'){
                steps {
                    sh "echo 'Testing...'"
                    // implement a check here is it deployed sucessfully
                }
            }
        }
    }

What configuration I need to add into this Jenkins file in order to download Heml chart repository from bitbucket and apply the configuration into Kubernetes cluster? Can you give me an example for such a Jenkins file?

JoSSte
  • 2,953
  • 6
  • 34
  • 54
Peter Penzov
  • 1,126
  • 134
  • 430
  • 808
  • As a note, people generally do not deploy with their build system but use a tool such as flux or argocd to update their clusters when a new image is published in the registry. See https://fluxcd.io/flux/components/helm/ for some ideas. – Vetsin Jan 22 '23 at 00:19

1 Answers1

1

Assuming your Pipeline is already in Bitbucket repo where Helm charts reside. Following is a example structure of the repo.

jenkins
├── app1-charts
│   ├── Chart.yaml
│   ├── templates
│   │   ├── app1.yml
│   │   └── _helpers.tpl
│   └── values.yaml
└── Jenkinsfile

The Jenkinsfile in the root directory would have a simple Pipeline like below.

pipeline {
    agent any
    stages {
        stage('Build1') {
            steps { 
                echo "Doing some build here if you need"
            }
        }
        
        stage('Applying helm charts') {
            steps {
                echo "Running Helm"
                sh "helm upgrade --wait --timeout 60 --set image.tag=${SOME_INPUT} app1-name ./app1-charts"
            }
        }
    }
}

The above Pipeline assumes that you have Helm setup in the Jenkins agents. Now in Jenkins, you can create a New Pipeline Job and select the option Pipeline Script from SCM, and then provide the Bitbucket configurations.

Jenkins Pipeline

Make sure the Script Path is set to point to your Jenkinsfile. Also, make sure Lightweight checkout is unchecked.

Once you add the configurations this will clone the repo with your helm charts and run the Pipeline in the repo which will execute the Helm charts.

Update: Pipeline to checkout bitbucket repo

Check the following Pipeline example. You may have to generate an access token with the necessary permissions to checkout the repo if the repo is Private.

pipeline {
    agent any

    stages {
        stage('checkout') {
            steps {
                echo 'Checking out code from bitbucket'
                git(url: 'https://x-token-auth:REPO_ACCESS_TOKEN@bitbucket.org/ORG_NAME/your-repo.git', branch: 'master')
                sh """
                cd your-helm-directory
                helm install .............. Or whatever command you need
                """
            }
        }
    }
}

Update

pipeline {
    agent any
    stages {
        stage('Download Helm Charts') {
            steps {
                sh "echo 'Downloading Helm Charts from Bitbucket repository...'"
                git(url: 'http://192.168.1.30:7990/scm/jen/helm.git', branch: 'master')
                
            }
        }
        stage('Test Kubernetes version') {
            steps {
                sh "echo 'Checking Kubernetes version..'"
                sh'''
                  kubectl version -o json // After getting the verson do whatever validations. 
                '''
            }
        }
        stage('Push Helm Charts to Kubernetes') {
            steps {
                sh "echo 'building..'"
                sh """
                  cd your-helm-directory
                  helm install .............. Or whatever command you need
                """
            }
        }     
        stage('Build Image') {
            steps {
                sh "echo 'building..'"
                git checkout http://192.168.1.30:7990/scm/jen/spring-boot-microservice.git
                // execute Java -jar ... and build docker image
                sh'''
                 git clone http://192.168.1.30:7990/scm/jen/spring-boot-microservice.git
                  cd TO_JAR_LOCATION 
                  Java -jar some.jsr
                  #Assuming you have a docker file defined
                  docker build -t nexusurl/Imagename:5.0 .
                '''
            }
        }
        stage('Push Image into Nexus registry') {
            steps {
                sh "echo 'building..'"
                sh'''
                  docker push nexusurl/Imagename:1.0
                '''
                // push compiled docker image into Nexus repository
            }
        }
        stage('Deploy Image from Nexus registry into Kubernetes') {
            steps {
                sh "echo 'building..'"
                # This again depends on how you plan to update. Assuming you are using the same helm charts then you can override what ever imagetag in your values file and run. Or else update the values file and then run. 
                sh'''
                    helm install --set image.tag=5.0
                '''
            }
        }
        stage('Test'){
            steps {
                sh "echo 'Testing...'"
                // This depends on how you have written your tests. 
            }
        }
    }
}

Update

Here is a full working example of how to list the images.

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
                script {
                    INPUT_IMAGE_TO_DEPLOY = input message: 'Please Select Docker Image to deploy', ok: 'Next',
                                                          parameters: [
                                                          choice(name: 'IMAGE_NAME', choices: getDockerImages(), description: 'Select Docker Image to delete')]
                }
            }
        }
    }
}

def getDockerImages() {
    REPOSITORY = 'YOUR_REPO_NAME'
    output = sh(returnStdout: true, script: "aws ecr list-images --repository-name $REPOSITORY --output json").trim()
    json = readJSON text: output
    println json
    return json.imageIds.imageTag
}

enter image description here

JoSSte
  • 2,953
  • 6
  • 34
  • 54
ycr
  • 12,828
  • 2
  • 25
  • 45
  • Can you give me more details, please? – Peter Penzov Jan 16 '23 at 12:42
  • @PeterPenzov added some more details. Let me know if something i not clear. – ycr Jan 16 '23 at 14:09
  • I'm not clear what should be the build jobs steps. Maybe: Step 1: Connect to Bitbucket and download the HELM chart locally on the Jenkins server. Step 2 Connect to Kubernetes Cluster to check the connection and version. Step 3: Upload the downloaded HELM charts into Kubernetes cluster. Step : apply them. Can you give some more details, please? – Peter Penzov Jan 16 '23 at 14:15
  • @PeterPenzov In the approach I have suggested, you do not have to explicitly clone/download the repo to get the Helm charts. When Jenkins retrieves the Pipeline script from Bitbucket the entire repo will be cloned to the Jenkins agent which will have the helm charts. The build steps depend on what you want to achieve. If you simply want to apply the charts the mentioned Pipeline will work. As you mentioned you can do additional validations if that's something required. – ycr Jan 16 '23 at 14:23
  • I think in my case I prefer to download the Helm charts locally to Jenkins first because of a security reasons. Can you show me how to implement this step please? – Peter Penzov Jan 16 '23 at 14:47
  • ok after the checkout how to push the helm chants to Kubernetes and apply them? – Peter Penzov Jan 16 '23 at 15:20
  • @PeterPenzov Just execute the helm command with a `sh` step by going to the relevant directory or by pointing to the correct directory. Check the first Pipeline in the answer. Updated the second Pipeline as well. – ycr Jan 16 '23 at 15:23
  • I added update version of Jenkins file. Can you guide me how to implement the missing steps, please? – Peter Penzov Jan 16 '23 at 22:45
  • kind remind, if you can advise please? – Peter Penzov Jan 17 '23 at 23:47
  • @PeterPenzov Sorry I missed your comment. Take a look at the update. Hope that helps. – ycr Mar 17 '23 at 13:03
  • Thank you. I have a question: Is it a good idea to split the job in 2 sub jobs: 1-st got to build and push the image. 2-nd only to deploy? – Peter Penzov Mar 17 '23 at 22:06
  • @PeterPenzov Build and Deploy are two orthogonal processes. So ideally yes it makes more sense to have two separate Jobs. One important use case would be, the Deploy job will not necessarily deploy the same version you build using the build Job. You may want to revert the current version to an older version where you will not perform a build just a deploy. – ycr Mar 17 '23 at 22:12
  • Is it possible to give me an example how to do this with second job to display with dropdown which version to upload if possible with aws ecr, please? – Peter Penzov Mar 17 '23 at 22:14
  • @PeterPenzov I'm afraid I do not have access to a AWS ECR repo. But your question will be answered once this is sorted https://stackoverflow.com/a/75744706/2627018 – ycr Mar 17 '23 at 22:27
  • I have a trial aws trial account. Can you send me e-mail to send you api credentials so that you can test it? – Peter Penzov Mar 17 '23 at 23:39
  • I get `An error occurred (InvalidParameterException) when calling the ListImages operation: Invalid parameter at 'repositoryName' failed to satisfy constraint: 'must satisfy regular expression '(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*''` – Peter Penzov Mar 17 '23 at 23:48
  • @PeterPenzov did you pass a repository name? Hardcode your repository name and see. – ycr Mar 17 '23 at 23:50
  • ok, now I get `java.lang.NoSuchMethodError: No such DSL method 'readJSON' found among steps [archiv.....` – Peter Penzov Mar 18 '23 at 00:03
  • @PeterPenzov you need to install this plugin to use readJSON https://plugins.jenkins.io/pipeline-utility-steps/ Have you installed it? – ycr Mar 18 '23 at 00:13
  • 1
    ok, it's working after I installed `pipeline-utility-steps` – Peter Penzov Mar 18 '23 at 00:31
  • Bad news. when I select a value from the drop down list and the job finishes nothing is deleted from the ecr registry. Maybe wrong image key is send? – Peter Penzov Mar 18 '23 at 22:08
  • @PeterPenzov You may ave to further debug and see what's going on. Probably create a new SO question as it's a different question altogether. – ycr Mar 18 '23 at 22:33