How Does Jenkins Use Environment Variables?
Environment variables are dynamic named values that can affect the way running processes will behave on a computer. They are used in Jenkins to set configuration settings and command options for various jobs and scripts. This enables users to configure job parameters, paths, or other data without hardcoding them within scripts or Jenkins job configurations.
These variables are particularly useful in managing different environments across the development, testing, and production stages. By using environment variables, Jenkins can help simplify the continuous integration and delivery (CI/CD) process by ensuring that scripts or jobs run correctly under various conditions just by changing the variables.
In this article:
What Is a Jenkinsfile?
A Jenkinsfile is a text file that contains the definition for a Jenkins pipeline and is checked into the source control repository. Essentially, it’s a script that tells Jenkins what to do when your pipeline is running.
The Jenkinsfile follows the Groovy syntax and is utilized to automate tasks like building, testing, and deploying applications in a defined sequence and environment, essentially acting as the cornerstone for implementing continuous delivery pipelines.
Here is an example of a simple Jenkinsfile:
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building...'
// Add build commands here
}
}
stage('Test') {
steps {
echo 'Testing...'
// Add test commands here
}
}
stage('Deploy') {
steps {
echo 'Deploying...'
// Add deploy commands here
}
}
}
}
Tips From the Expert
In my experience, here are tips that can help you better use environment variables in Jenkins:
-
Leverage shared libraries for managing environment variables
When managing multiple Jenkins pipelines, store common environment variables in Jenkins shared libraries. This ensures consistency across jobs and simplifies maintenance by centralizing variable management. -
Secure sensitive variables using Jenkins credentials
For sensitive data like API keys or passwords, store them in Jenkins credentials instead of environment variables. Use thecredentials()
function in the pipeline to securely inject these into your jobs without exposing them in logs. -
Use dynamic environment variables for flexible pipelines
Capture dynamic environment values (like branch names or build results) during runtime using shell commands andreturnStdout: true
. This allows your pipelines to adapt based on the environment or external conditions. -
Utilize the
withEnv
step for scoped variable control
Use thewithEnv
step to define environment variables that apply only to specific stages or steps. This isolates environment variables for particular jobs, preventing unintentional overrides and maintaining clean separation between different tasks. -
Set environment variables globally for job reuse
Define global environment variables using theenvironment
directive in declarative pipelines. This helps maintain consistency across stages and allows variables to be reused, reducing duplication in long pipelines.
Viewing Jenkins Environment Variables
Jenkins exposes many of its configuration details through environment variables. These variables provide information about the job and the specific build that is running. Some commonly used variables include:
- JOB_NAME: Provides the name of the job in Jenkins (e.g.,
envvars
). - JOB_URL: Gives the URL to the job in the Jenkins UI (e.g.,
http://localhost:8082/job/envvars/
). - BUILD_NUMBER: Prints the build number in Jenkins console output (e.g.,
5, 6
). - BUILD_TAG: Gives a unique tag for a specific job name and build number (e.g.,
envvars-build-8
).
You can view the list of Jenkins environment variables using two different methods:
Using env-vars.html
For this method:
- Open your web browser.
- In the address bar, type
${MY_JENKINS_HOST}/env-vars.html
. For example, if you are running Jenkins on your local machine, you would typehttp://localhost:8080/env-vars.html
.
- Press Enter. This will open a page displaying all the environment variables defined by Jenkins. The page is dynamically generated and provides a comprehensive list of all variables available in your Jenkins environment.
- This method is particularly useful for quickly viewing and verifying the environment variables without needing to run a job or script.
Windows Batch Script/Shell Command
To view environment variables using the shell:
- Create a new pipeline: In Jenkins, go to New Item and create a new pipeline named
envvars
.
- Configure the pipeline script: In the Pipeline section, select Pipeline script and enter the following script:
pipeline {
agent any
stages {
stage("Env Variables") {
steps {
bat 'set' // For Windows
sh 'printenv' // For Linux/Unix
}
}
}
}
Here are the main details of the script:
- The
pipeline
block defines the Jenkins pipeline. agent any
specifies that the pipeline can run on any available agent.- Inside the
stages
block, we define a stage named Env Variables. - The
steps
block contains the commands to list the environment variables:bat 'set'
: This command is used for Windows systems. It executes the set command, which lists all environment variables in the command prompt. The output will be displayed in the Jenkins console logs.sh 'printenv'
: This command is used for Linux/Unix systems. It executes theprintenv
command, which lists all environment variables in the terminal. The output will be displayed in the Jenkins console logs.
- Run the pipeline: Save the pipeline script and click Build Now to run the pipeline. After the build completes, check the console output to see the list of environment variables:
Reading Jenkins Environment Variables
To read Jenkins environment variables in a pipeline, you can use the env
object. This allows you to access environment variables defined by Jenkins. For example, env.BUILD_NUMBER
will give the current build number of a pipeline. Variables can also be referenced using the ${}
syntax, such as ${env.BUILD_NUMBER}
.
Here’s a script that demonstrates how to read and print the build number:
pipeline {
agent any
stages {
stage("Env Build Number") {
steps {
echo "Build number: ${env.BUILD_NUMBER}"
}
}
}
}
This script will print the build number to the console, showing the current build number of the pipeline.
Setting Environment Variables in Jenkins
The code and instructions below are adapted from the Jenkins documentation.
Jenkins Pipeline exposes environment variables through the global variable env
, accessible from anywhere within a Jenkinsfile. This allows you to reference various build parameters, system properties, and more. For example:
pipeline {
agent any
stages {
stage('Example') {
steps {
echo "Running build number ${env.BUILD_NUMBER} on Jenkins instance at ${env.JENKINS_URL}"
}
}
}
}
In this script:
env.BUILD_NUMBER
retrieves the current build number.env.JENKINS_URL
retrieves the Jenkins instance URL.
These environment variables are part of a larger set documented at ${MY_JENKINS_URL}/pipeline-syntax/globals#env
.
The output should look like this:
Setting Local or Global Environment Variables
Jenkins environment variables can be set using declarative or scripted pipelines.
Declarative Pipeline
To set environment variables in a declarative pipeline, you use the environment
directive:
pipeline {
agent any
environment {
CC = 'clang'
}
stages {
stage('Example') {
environment {
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}
In this script:
- The
environment
block at the top level sets variables globally across all stages. - The
environment
block within a stage sets variables only for that stage.
Scripted Pipeline
For scripted pipelines, use the withEnv
step:
node {
withEnv(['CC=clang', 'DEBUG_FLAGS=-g']) {
stage('Example') {
sh 'printenv'
}
}
}
In this example, withEnv
sets CC
and DEBUG_FLAGS
only for the steps within the stage
.
The output should look like this:
Setting Environment Variables Dynamically
You can also set environment variables dynamically using shell commands. This can be done using sh
, bat
, or powershell
steps with returnStdout
or returnStatus
options:
pipeline {
agent any
environment {
CC = """${sh(
returnStdout: true,
script: 'echo "clang"'
).trim()}"""
EXIT_STATUS = """${sh(
returnStatus: true,
script: 'exit 1'
)}"""
}
stages {
stage('Example') {
environment {
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}
In this script:
returnStdout: true
captures the output of the shell command as a string.returnStatus: true
captures the exit status of the command.
The output should look like this:
Managing Jenkins Environment Variables with Configu
Configu is a configuration management platform comprised of two main components, the stand-alone Orchestrator, which is open source, and the Cloud, which is a SaaS solution:
Configu Orchestrator
As applications become more dynamic and distributed in microservices architectures, configurations are getting more fragmented. They are saved as raw text that is spread across multiple stores, databases, files, git repositories, and third-party tools (a typical company will have five to ten different stores).
The Configu Orchestrator, which is open-source software, is a powerful standalone tool designed to address this challenge by providing confConfigu is a configuration management platform comprised of two main components, the stand-alone Orchestrator, which is open source, and the Cloud, which is a SaaS solution:
Configu Cloud
Configu Cloud is the most innovative store purpose-built for configurations, including environment variables, secrets, and feature flags. It is built based on the Configu configuration-as-code (CaC) approach and can model configurations and wrap them with unique layers, providing collaboration capabilities, visibility into configuration workflows, and security and compliance standardization.
Unlike legacy tools, which treat configurations as unstructured data or key-value pairs, Configu is leading the way with a Configuration-as-Code approach. By modeling configurations, they are treated as first-class citizens in the developers’ code. This makes our solution more robust and reliable and also enables Configu to provide more capabilities, such as visualization, a testing framework, and security abilities.