Learn Jenkins - Parameterized Pipelines & Manual Approval Gates
Episode 6 of 21

Learn Jenkins - Parameterized Pipelines & Manual Approval Gates

Fully automated pipelines can be dangerous when they touch production. This episode covers parameterized pipelines with string, choice, boolean, and password parameters, plus a manual approval gate using the input step so that deploy decisions stay in the hands of authorized people, complete with timeout handling.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Introduction

In episode 5 we dissected variables, environment, and secret management — now your pipelines can read configuration and credentials safely without storing secrets in code. But there is one big question before a pipeline is fit to touch production: is full automation always safe?

Imagine this. Your team builds an autopilot that can land an airplane by itself without a pilot. Technically it might work, but who is accountable when the landing gear fails in the middle of a storm? In the CI/CD world, automatically deploying to production on every commit without human approval is that pilotless autopilot. Aviation safety procedures use the two-man rule: two people must verify before a critical action is taken.

In this episode we build an interactive pipeline: a parameterized pipeline that accepts input from the user through a form before the build runs, and a manual approval gate using the input step that pauses the pipeline and waits for approval from an authorized person — plus timeout handling so an idle pipeline does not clog the system forever.

Main Discussion

The Parameterized Pipeline Concept

A parameterized pipeline turns a static Jenkinsfile into a fillable form before the build runs. Every time you click the Build with Parameters button on the job page, Jenkins displays a form whose contents you define yourself. The values you enter can then be accessed throughout the pipeline via the params object.

The analogy is ordering coffee at a shop: without parameters, the barista always makes the exact same drink for everyone; with parameters, you choose the size, temperature, and sugar. One recipe, many variations — without writing one pipeline per variation.

The four parameter types most commonly used:

TypeExampleWhen to Use
stringstring(name: 'APP_VERSION', defaultValue: '1.0.0', description: 'Versi')Free values: version, tag, branch name
booleanParambooleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Jalankan test')On/off switch to run or skip a stage
choicechoice(name: 'ENVIRONMENT', choices: ['staging', 'production'], description: 'Target')A selection from a fixed drop-down list
passwordpassword(name: 'DEPLOY_TOKEN', defaultValue: '', description: 'Token')Secret input displayed as dots

The rule of thumb: string for values that are free and change often, choice for values that must stay consistent with a team-agreed list, booleanParam for switches, and password only for one-off secret values filled in by an operator.

Defining Parameters in the Jenkinsfile

Parameters are declared inside the parameters block directly below agent:

JenkinsThe parameters block
pipeline {
    agent any
 
    parameters {
        string(name: 'APP_VERSION', defaultValue: '1.0.0', description: 'Versi aplikasi')
        choice(name: 'ENVIRONMENT', choices: ['staging', 'production'], description: 'Target environment')
        booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Jalankan test suite')
        password(name: 'DEPLOY_TOKEN', defaultValue: '', description: 'Token deployment')
    }
 
    stages {
        stage('Build') {
            steps {
                echo "Membangun versi ${params.APP_VERSION} untuk ${params.ENVIRONMENT}"
            }
        }
    }
}

When a build is first run without clicking Build with Parameters, Jenkins uses the defaultValue. This is important: design parameters with safe, non-breaking defaults, because those defaults are what get used when automatic triggers (webhooks, cron) fire a build without a human filling in the form.

Accessing Parameter Values

Parameter values are accessed through the params object. Two ways often confuse beginners: params.X accesses the parameter named X, while the bare variable X (without the params prefix) is also automatically available as an environment variable. The most explicit reference is params.X:

  • params.APP_VERSION returns the string value the user entered.
  • params.RUN_TESTS returns true or false for booleans.
  • params.ENVIRONMENT returns the selection chosen from the choice list.

Tip

Do not store params.X secret values into the environment block. For secrets, keep using withCredentials from episode 5 — the password parameter type is not a replacement for the credentials store.

The Manual Approval Gate with the input Step

This is the heart of this episode. The input step pauses pipeline execution and shows a prompt in the Jenkins UI waiting for a Proceed or Abort click from an authorized user. The pipeline stays "alive" but does not continue to the next stage until a decision is made:

JenkinsManual approval gate
stage('Persetujuan') {
    steps {
        timeout(time: 15, unit: 'MINUTES') {
            input message: 'Deploy ke Production?', ok: 'Ya, lanjutkan', submitter: 'admin-user'
        }
    }
}

The most important parameters:

  • message — the text shown to the approver; it must clearly state what is about to happen.
  • submitter — the list of usernames (or group names) allowed to approve, comma-separated. Leave empty if any user may approve.
  • ok — the label of the Proceed button, useful for context such as "Yes, deploy to production".

Why place input in its own stage rather than tucking it in the middle of other steps? Because this stage is clearly visible in the pipeline Stage View, easy to audit, and separate from technical logic. The approver does not need to understand build details — they only see a green gate that reads "Deploy to Production?".

Timeout Handling

Without a time limit, a pipeline waiting for approval can hang forever — blocking an executor, piling up the queue, and making the team forget a build is pending. Two timeout levels to understand:

JenkinsPipeline-level timeout
pipeline {
    agent any
 
    options {
        timeout(time: 1, unit: 'HOURS')
        buildDiscarder(logRotator(numToKeepStr: '10'))
    }
 
    stages {
        stage('Build') {
            steps {
                echo 'Build sedang berjalan'
            }
        }
    }
}

options { timeout(time: 1, unit: 'HOURS') } limits the total duration of the entire pipeline to one hour — after that the build is automatically aborted. This is the last safety net. Meanwhile timeout(time: 15, unit: 'MINUTES') around the input step only limits the waiting time for approval, so the pipeline aborts quickly if no one approves, without sacrificing normal build time.

Warning

The password parameter type does look tempting for tokens and API keys, but its value is still stored as part of the build and carries a higher risk than the Jenkins credentials store. For static credentials such as registry tokens, always use withCredentials from episode 5; use the password parameter only for secret values genuinely entered manually by an operator per build.

Complete Pipeline Example

All the concepts above are combined into one Jenkinsfile: parameters to control version and environment, a boolean switch to skip tests, an approval gate before deploy, and a timeout as a safety net:

JenkinsParameterized Jenkinsfile with approval gate
pipeline {
    agent any
 
    parameters {
        string(name: 'APP_VERSION', defaultValue: '1.0.0', description: 'Versi aplikasi')
        choice(name: 'ENVIRONMENT', choices: ['staging', 'production'], description: 'Target environment')
        booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Jalankan test suite')
        password(name: 'DEPLOY_TOKEN', defaultValue: '', description: 'Token deployment')
    }
 
    options {
        timeout(time: 1, unit: 'HOURS')
        buildDiscarder(logRotator(numToKeepStr: '10'))
    }
 
    stages {
        stage('Build') {
            steps {
                echo "Membangun versi ${params.APP_VERSION} untuk ${params.ENVIRONMENT}"
                sh "make build VERSION=${params.APP_VERSION}"
            }
        }
 
        stage('Test') {
            when {
                expression { return params.RUN_TESTS }
            }
            steps {
                sh 'make test'
            }
        }
 
        stage('Persetujuan') {
            steps {
                input message: 'Deploy ke Production?', submitter: 'admin-user'
            }
        }
 
        stage('Deploy') {
            steps {
                sh "make deploy ENV=${params.ENVIRONMENT}"
            }
        }
    }
}

The full flow: the user fills in the form → the build runs with the chosen version and environment → tests run only if the switch is active → the pipeline stops at the approval stage until admin-user clicks Proceed → only then is the Deploy stage executed. If the ENVIRONMENT parameter is set to staging, the pipeline runs without strict approval; the production choice should always pass through the approval gate.

Tip

The combination of when with expression can be used to decide whether the approval gate is needed: skip the approval stage if the target is staging, require it for production. The combination of parameters + input + when is the standard pattern for environment-gated deployment in enterprise teams.

Conclusion

In episode 6 we dissected how to build an interactive, accountable pipeline: a parameterized pipeline with string, choice, booleanParam, and password that turns a static Jenkinsfile into a form, value access through params, a manual approval gate with the input step that pauses the pipeline until an authorized person approves, and timeout handling both at the pipeline level and around the approval step so no build hangs indefinitely.

The key takeaways to carry with you:

  • Parameters turn a pipeline into a form; always provide a safe defaultValue for automatic triggers.
  • params.X is the explicit way to read parameter values across the pipeline.
  • The input step with submitter is the human approval gate; place it in a separate stage for easy auditing.
  • options { timeout(time: 1, unit: 'HOURS') } limits total duration; wrap input in a shorter timeout so the pipeline aborts quickly if not approved.
  • Do not put static credentials in password parameters — use the credentials store from episode 5.

Now you can build a pipeline that is process-safe. But a pipeline this long still runs sequentially — one stage waits for the previous one to finish, which wastes a lot of time. In episode 7 we will speed everything up: advanced flow control with parallel execution, matrix strategies for multi-environment builds, conditional execution with when, and post-build actions with post. See you in episode 7!

Learn Jenkins - Parameterized Pipelines & Manual Approval Gates | Learn Jenkins