Skip to main content

CI/CD Automation: How to wait for Helm deployment into Kubernetes cluster

 So I created this post because with Helm v3, if you use --wait option and the timeout is reached and the deployment isn't successful, Helm marks the deployment as failed. The problem is that subsequent deployment (upgrade) that may contain the fix won't work as expected and it will end up in error like this:

[some-name] has no deployed release

 

The only way to fix this is manual intervene and deleting the previous failed release. This is not only scary but also against the automation process.

If we remove --wait option, Helm will mark the deployment as successful regardless.

My solution to this that works nicely is as per below:


  • Remove --wait option from helm deploy
  • Use this command to retrieve the list of deployment for that namespace that you are deploying against: kubectl get deployments -n ${namespace} -o jsonpath='{range .items[*].metadata}{.name}{","}{end}'
  • You can use split to turn the comma separated list above into an array
  • Then you can run multiple commands in parallel (we use Jenkins so it's easy to do so) as kubectl rollout status deployment ${deploymentName} --watch=true --timeout=${timeout} -n ${namespace}
  • If after the timeout, for example 7m means 7 minutes, the deployment still not successful, the command exits with error

    Problem solved.

A Jenkins groovy function can look like this:

Note: devopsToolsContainerName is used to switch to a container in which kubectl command is available.


  
  def call(map) {
    def namespace = map?.namespace
    assert namespace : '[namespace] argument must be procided'

    def devopsToolsContainerName = map?.devopsToolsContainerName ?: 'devops-tools'
    def timeout = map?.timeout ?: '7m'
    def runInStage = map?.runInStage ?: true

    def func = {
        container(devopsToolsContainerName) {

            String result = sh(returnStdout: true, script: "kubectl get deployments -n ${namespace} -o jsonpath='{range .items[*].metadata}{.name}{\",\"}{end}'")
            log "=> ${result}"
            String[] deployments = result.split(',')
            log "=> ${deployments}"
            def stages = [failFast: true]
            def report = [:]
            deployments.each {
                stages["${it}"] = {
                    report["${it}"] = sh(returnStdout: true, script: "kubectl rollout status deployment ${it} --watch=true --timeout=${timeout} -n ${namespace}")
                    log "${it} report => ${report["${it}"]}"
                }
            }

            parallel stages
        }
    }

    if(runInStage) {
        stage("Waiting for deployment") {
            func()
        }
    } else {
        func()
    }
}

Comments

Popular posts from this blog

Hibernate And Mapping enum to customized values

With Hibernate, enums can be easily mapped either by enum item name or the position of each item but what if you want to map it to a customized value? In my case, we have so many one-character long columns in our tables, representing flags, statuses etc. We have heaps of them. Writing UserTypes for each enum field is very boring and nasty job. As every where you see in internet, you need to keep a Map for each user-type in order to map those values to enum elements. So to avoid this, I ended up with something more clean, easy and more generic. Now imagine you have following enum: public enum PaymentFrequencyEnum { WEEKLY("WK"), FORTNIGHTLY("FN"), MONTHLY("MT"), QUARTERLY("QL"), YEARLY("YL"); private String value;     private PaymentFrequency(String value) { this.value = value; } } I've chosen two-letter code as value so that you understand m...

Migrating from OJB to Hibernate

Okay now I have to migrate a dozen of domain objects from OJB to Hibernate entities and since we still have to use hbm files as opposed to Annotation, this is no enjoying task... I found this XML Stylesheet from this website below but had to make some changes in order to get it working... so I thought it may help someone: Download XSL file here Original file can be found here but so far at this time which is 16th of December 2013 and 6:37pm, it's not working properly :) martindavidsson blog