Pro Jenkinsfile: Avoid These Common Mistakes – Part 2

27 / Jun / 2024 by Karandeep Singh 0 comments

Introduction
Hello again, DevOps Engineers! Uncle Jenkins is back, ready to dive deeper into the world of Jenkinsfiles. Our previous blog covered some important tips to avoid common CI/CD pitfalls. If you missed it, check out Part 1 of this series to catch up on those crucial points. In this blog, we’ll explore more advanced strategies to refine and optimize your Jenkinsfiles. Let’s continue our journey towards mastering Jenkinsfile creation. Ready to level up? Let’s get started!

Jenkin-logo

Jenkin-logo

1.  Ignoring Environment Variables: Don’t Hardcode Values

Hardcoding values make your pipeline inflexible and difficult to maintain.
Avoidance Tip: Use the environment directive to set variables and the withCredentials blocks to manage configurations and secrets.

pipeline {
    agent any
    environment {
        APP_ENV = ‘prod’
        API_ENDPOINT = ‘https://api.example.com’
    }
    stages {
        stage(‘Build’) {
            steps {
                echo “Building application for ${env.APP_ENV}
            }
        }
        stage(‘Deploy’) {
            steps {
                withCredentials([string(credentialsId: ‘aws-credentials-id’, variable: ‘AWS_CREDENTIALS’)]) {
                    echo “Deploying to ${env.APP_ENV} using ${env.API_ENDPOINT}
                }
            }
        }
    }
}

2. Stashing and Unstashing Artifacts

Common Mistakes:
– Overuse of stash and unstash: Excessive use can lead to unnecessary resource usage and complexity.
– Naming Collisions: Using non-unique names for stashes can lead to unexpected behaviors.
– Size Limitations: Not considering the size of stashed files, can lead to performance issues.

Best Practices:
– Use stash and unstash for small, critical artifacts that need to be transferred between stages.
– Ensure unique and meaningful names for each stash to avoid collisions.
– Be mindful of the size and frequency of stashed content.

pipeline {
    agent any
    stages {
        stage(‘Build’) {
            steps {
                sh ‘echo “Build artifact” > artifact.txt’
                stash includes: ‘artifact.txt’, name: ‘build-artifact’
            }
        }
        stage(‘Deploy’) {
            steps {
                unstash ‘build-artifact’
                sh ‘echo “Deploying artifact:” && cat artifact.txt’
            }
        }
    }
}

3. Overusing sh Steps for Shell Commands: Keep it Clean

Using sh steps everywhere makes your Jenkinsfile look like a tangled mess of shell scripts.

Avoidance Tip
:
Use built-in Jenkins steps and plugins whenever possible. Reserve sh steps for when you truly need to execute shell commands. Example:
Instead of this:

pipeline {
  agent any
  stages {
      stage(‘Build’) {
          steps {
              sh ‘cp src/* output/’
              sh ‘gradle build’
          }
      }
  }
}

Keep it clean like this:

pipeline {
  agent any
  stages {
      stage(‘Build’) {
          steps {
              sh ”’
                  cp src/* output/
                  gradle build
              ”’
          }
      }
  }
}

4. Ignoring Pipeline as Code Best Practices

Not treating your Jenkinsfile with the same care as other code can lead to issues. This includes not version controlling your Jenkinsfile, not reviewing changes through pull requests, and not testing changes thoroughly.

Avoidance Tip
:

  • Storing your Jenkinsfile in your version control system like Github.

    Code Best Practices

    Code Best Practices

  • Using code reviews and pull requests to review changes to the Jenkinsfile.
  • Testing Jenkinsfile changes in a staging environment before applying them to production.

5. Neglecting Notifications: Don’t Keep Stakeholders in the Dark

Failing to notify stakeholders about build status can lead to communication breakdowns and delays.
Avoidance Tip: Use the post section to send notifications about build status.

@Library(‘shared_lib@master’) _
pipeline {
  agent any
  stages {
      stage(“Custom Stage”) {
        // some steps
      }
  }
  post {
        failure {
          script {
              def failureMessage = “Job Failed – ${BUILD_URL}
              jenkinsNotifications.notify(“Failure”, failureMessage, “Jenkins-prod-failures”)
          }
      }
  }
}

6. Ignoring Agent Specification for Different Stages

Problem: Not specifying agents for different stages can lead to inefficient resource usage, especially in multi-node setups.
Avoidance Tip: Specifying agents at the stage level when different resources are needed.

Jenkins-agents

Jenkins-agents

Example With Stage-specific Agents :

pipeline {
  stages {
      stage(‘Build’) {
          agent {
              label ‘build_agent’
          }
          steps {
              sh ‘make build’
          }
      }
      stage(‘Test’) {
          agent {
              label ‘test_agent’
          }
          steps {
              sh ‘make test’
          }
      }
  }
}

 7. Implementing Complex workflow with build and waitUntil.

Problem: Incorrect Job Triggering and Poor Error Handling. Misconfiguring downstream job triggers can lead to pipeline failures and hard-to-debug issues.
Avoidance Tip: Handle Downstream Jobs and Errors Gracefully.

  • Use build and waitUntil with proper error handling and exit conditions. Example: Triggering Downstream Job
pipeline {
    agent any
    stages {
        stage(‘Trigger Downstream’) {
            steps {
                script {
                    try {
                        def downstreamBuild = build job: ‘downstream-job’, wait: true
                        echo “Downstream build result: ${downstreamBuild.result}
                    } catch (Exception e) {
                        error “Downstream job failed: ${e.message}
                    }
                }
            }
        }
    }
}

Conclusion
In this second part of our blog series, we dived deeper into the degree of professional Jenkinsfile creation. These strategies are designed to streamline your CI/CD processes and mitigate risks. In the next blog of our series, we will continue to explore additional strategies to help you master Jenkinsfile creation and further improve your CI/CD practices. Contact our team at TO THE NEW for personalized assistance and to elevate your DevOps practices. Let’s build a more reliable and efficient CI/CD pipeline together!

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *