Dynamic and reactive parameterization in Jenkins pipelines using HTML, Groovy, and Bash.

Esteban Echavarria Collazos
Globant
Published in
8 min readMay 12, 2021

A few years ago DevOps culture boomed and started to become a must-have in most microservices architectures thanks to the ease of automating the applications life-cycle for hundreds of services simultaneously. This increase in demand also brought new challenges and possible ways to develop CI/CD workflows and multiple technologies to do it.

In our particular case, we will be talking about Jenkins and how you could extend its possibilities in terms of pipeline parameterization using a plugin called “Active Choices”

Source: Jenkins + Gitlab

Content:

  • 1- What is this plugin called “Active Choices” and why is it so useful
  • 2- How does the plugin “Active Choices” works?
  • 3- A practical example of the Active Choices plugin in AWS: Preview and upload an image to an existing S3 bucket.
  • 4- Creating pipeline parameters
  • 5- Conclusions

1- What is this plugin called “Active Choices” and why is it so useful?

As described in its docs: “The Active Choices plugin is used in parametrized freestyle Jenkins jobs to create scripted, dynamic and interactive job parameters. Active Choices parameters can be dynamically updated and can be rendered as combo-boxes, check-boxes, radio-buttons, or rich HTML UI widgets.”

Usually, when there are hundreds of services to deploy, the pipeline is parameterized to allow you to select from only one pipeline, multiple kinds of deployment, (i.e. which environment should be deployed, with what name, if it should execute test…) Jenkins currently allows you to use some predefined parameters like choice, checkbox or string parameter. When you’ve to manage pipelines that are not the same, you will see that there are certain cases when the parameters provided by Jenkins are not enough because of its static nature, in these cases, the plugin “Active Choices” comes to enrich your parameterization options allowing you to pass reactive references between parameters and render custom HTML in your parameterization options.

2- How does the plugin “Active Choices” works?

It provides 3 new kinds of parameters when you’re configuring your pipeline:

  • Active Choices Parameter: allows you to use a Groovy or Scriplet script to determine whether your input will be computed or predefined and return your results depending on the computations made.
  • Active Choices Reactive Parameter: Same as the active choices, allows you to use a Groovy or Scriplet script, and additionally, these parameters will be recalculated when a referenced parameter changes (i.e. ENV is the referenced parameter when ENV is DEV, the parameters will react and disable the “Execute test” choice parameter)
  • Active Choices Reactive Reference Parameter: Contains Active Choice Parameter and Active Choice Reactive Parameter options, and additionally enables new parameter options such as HTML widgets, bulleted or numbered lists, and input boxes.
Source: Active Choices Plugin Github Repository

3- A practical example of the Active Choices plugin in AWS: Preview and upload an image to an existing S3 bucket.

Suppose you do now want your team to have direct access to AWS management console to upload your assets to S3, since it will incur operational overheat (Users creation, permissions, policies…), instead you would prefer to centralize the image uploading for your assets in Jenkins avoiding giving individual credentials with S3-specific permissions to users. You also want to be able to list the S3 directories and determine in which directory will be the asset uploaded.

To accomplish that, you will need the following things:

  • An input string parameter for the image URL with an HTML Reactive Reference Parameter to preview the image.
  • An input text box for your image name. (Tunned with HTML)
  • A scripted Active Choices Parameter that pulls all S3 buckets to select where to upload the image.

And as a pre-requisite you will need the following things:

  • Jenkins Plugin: Active Choices
  • AWS Credentials are already configured in your Jenkins agent.
  • AWS S3 Permission for Read and Put.

4- Creating pipeline parameters:

To create the parameters, we are going to enter into the “Configure” tab in our pipeline, click on “This project is parameterized”, once enabled, click on “Add parameter” and select “String Parameter” to create our image input box.

Once our regular String parameter is created, we will define a name for this parameter and check the “Trim” box, to trim its value and avoid any whitespace that could generate errors later in our HTML.

If you want to see how it looks after adding our first parameter, click on “Save”, close the configuration window and click on “Build with parameters”

As you see it’s very simple, but this will change once we add our new Reactive Reference Parameter for the image preview.

Let’s go back to “Parameters” settings and add the new parameter, for this, we will click on “Add parameter” and select “Active Choices Reactive Reference Parameter”. Before configuring the script, navigate to the bottom of the parameter and select the “Choice Type” as “Formatted HTML” to enable HTML rendering in our parameter and add the String parameter created earlier as a “Referenced Parameter”, adding the String parameter there, basically enables the reactive behavior and when there is an update in the String parameter, this will be recalculated.

To configure our script, first, we will check the box “Groovy Script” at the top of the parameter and the text-box we will add our Groovy returning the HTML we want to render.

return """<img src=" """+ image + """ "alt="no-image">"""

This is a very simple HTML tag but is all we need to preview an image, as you see the script basically is concatenating the “img” HTML tag with the referenced parameter “image”, setting it as the source image for our parameter.

Note: the fallback script is an alternate script that will be executed if the main script returns an exception. We are also using triple quotes to enable multi-line string interpolation, which is used when you want to replace any tag with another parameter. (Using the ${parameter} syntax)

Once done, save and test how it works. To test it, all we need to do is to copy an image URL in our “image” parameter and the referenced parameter will render this image in plain HTML (Or return an error message if fails)

Try replacing the image URL and see how the reactive parameter re-renders the HTML image.

Ok, now we already have the image and can preview it, now we want to select to which S3 the asset twill be uploaded, for this, we will go again into the settings and add a new parameter, as this parameter won’t react any other variable, we will use an “Active Choices Parameter”. Since we want to select from a list 1 choice, the “Choice Type” will be “Single Select”, we will also enable the check box “Enable filters” this basically will render an input box where we can type a string to search and list only matches.

Now, for the script since we want to use the AWS CLI to list all the S3 and format them appropriately, to achieve this we will use the Groovy function “execute” along with the pipe operator to move the std output to the next command input. The directive “Execute” basically will run bash code inside our Groovy script and once it finishes, we will tokenize the output(Split using the line break as a split character).

Once you’ve saved your new parameter, now you can see how it will render the bucket and filters with the string you type

Now, we just need to add an input box to set the image name and configure the pipeline to use our parameters to upload the image and we’re done, for this, to give use to the parameter “preview” which holds the HTML, we will use it to append an input tag and use later in the pipeline extracting its value.

return """<h5>Image name</h5><input type="text" class="setting-input" style="width:auto" name="value" value="image.jpg" ><br><img src=" """+ image + """ "alt="no-image" style="margin:5% 2% 5% 2%">"""

Now, just append a new h5 tag and an input tag to the previous HTML for the parameter “Preview” and add a default value (In my case, image.jpg), something important to take as a note is that for Jenkins to appropriately use the parameter value, the class in the HTML must be “setting-input”.

Finally, we will just configure the pipeline to use our parameters and upload to S3 the image selected by the user with the following code:

pipeline {
agent any
stages {
stage('Upload image to s3') {
environment{
name = sh(script:"echo ${params.preview} | cut -d',' -f1", returnStdout: true).trim()
}
steps {

sh """#!/usr/bin/env bash
curl ${params.image} > ${name}
aws s3 cp ./${name} s3://${params.bucket}
rm ./${name}
"""
}
}
}
}

As you see it’s very simple and it just uses the parameters created before to download and upload the image, the only thing you should notice is we removed a comma from the “preview” param in the environment “name” and it's because when you use the formatted HTML parameters it will export them as a list separated by commas (i.e. 1, 2, 3). Now that everything is ready we can test the final pipeline.

Once finished we will just see a successful execution and if we go to our S3 bucket, the image file is created.

Now, to just verify if everything was OK, download the image and open it.

Great, now you know how to dynamically parameterize your pipeline using Groovy, bash, and HTML.

5- Conclusions

This example shows multiple new ways to parameterize your pipeline using reactive references and HTML, making Jenkins Pipelines more robust and flexible, surely there will be fewer situations where you would need to create or modify the pipeline to run specific situations!

Thanks for your time!

--

--