Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

Runtime parameters

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Runtime parameters give you more control over the values you pass to a pipeline. With runtime parameters, you can:

  • Supply different values to scripts and tasks at runtime
  • Control parameter types, allowed ranges, and default values
  • Dynamically select jobs and stages with template expressions

You can specify parameters in templates and in the pipeline. Parameters have data types such as number and string, and they can be restricted to a subset of values. The parameters section in a YAML defines what parameters are available.

Parameters are available only during template parsing. They expand before the pipeline runs, replacing values surrounded by ${{ }} with parameter values. Use variables if your values need to be available throughout the pipeline run.

Note

This guidance doesn't apply to classic pipelines. For parameters in classic pipelines, see Process parameters (classic).

Parameters must contain a name and data type. You can't make parameters optional. You need to assign a default value in your YAML file or when you run your pipeline. If you don't assign a default value or set default to false, the first available value is used.

Use templateContext to pass more properties to stages, steps, and jobs used as parameters in a template.

What is the difference between parameters and variables?

The following table highlights the key differences between parameters and variables in Azure Pipelines.

Feature Parameters Variables
Evaluation Time Template parsing (queue) Evaluation is syntax-dependent. Variables defined with macro syntax ($(var)) evaluate at runtime before a task runs and used in scripts and tasks. Variables defined with runtime expressions ($[variables.var]) evaluate before a job or stage runs and are used in conditions or dynamic variable assignment.
Mutability Immutable after queue User-defined, environment, and output variables can be updated dynamically during pipeline execution
UI exposure during run Shown in Run Pipeline UI and can be set before a run Exposed during run if set in Pipeline UI as overridable
Secret values No support for secret values Can be set as secrets

Use parameters in pipelines

Set runtime parameters at the start of a YAML file.

This example pipeline includes an image parameter with three hosted agents as string options. In the jobs section, the pool value specifies the agent from the parameter used to run the job. The trigger is set to none so that you can select the value of image when you manually trigger your pipeline to run.

parameters:
- name: image
 displayName: Pool Image
 type: string
 default: ubuntu-latest
 values:
 - windows-latest
 - ubuntu-latest
 - macOS-latest

trigger: none

jobs:
- job: build
 displayName: build
 pool: 
 vmImage: ${{ parameters.image }}
 steps:
 - script: echo building $(Build.BuildNumber) with ${{ parameters.image }}

From the pipeline runs page, select Run pipeline to run the pipeline. You see the option to select the Pool Image. If you don't make a selection, the default option ubuntu-latest is used. You can't select a Pool Image if you run your pipeline from the YAML editor.

Use conditionals with parameters

You can also use parameters as part of conditional logic. With conditionals, part of a YAML runs if it meets the if criteria.

Use parameters to determine what steps run

This pipeline adds a second boolean parameter, test, which controls whether to run tests in the pipeline. When the value of test is true, the step that outputs Running all the tests runs.

parameters:
- name: image
 displayName: Pool Image
 values:
 - windows-latest
 - ubuntu-latest
 - macOS-latest
- name: test
 displayName: Run Tests?
 type: boolean
 default: false

trigger: none

jobs:
- job: build
 displayName: Build and Test
 pool: 
 vmImage: ${{ parameters.image }}
 steps:
 - script: echo building $(Build.BuildNumber)
 - ${{ if eq(parameters.test, true) }}:
 - script: echo "Running all the tests"

Use parameters to set what configuration is used

You can also use parameters to set which job runs. In this example, different architectures build depending on the value of config parameter, which is a string type. By default, both the x86 and x64 architectures build.

parameters:
- name: configs
 type: string
 default: 'x86,x64'

trigger: none

jobs:
- ${{ if contains(parameters.configs, 'x86') }}:
 - job: x86
 steps:
 - script: echo Building x86...
- ${{ if contains(parameters.configs, 'x64') }}:
 - job: x64
 steps:
 - script: echo Building x64...
- ${{ if contains(parameters.configs, 'arm') }}:
 - job: arm
 steps:
 - script: echo Building arm...

Selectively exclude a stage

You can also use parameters to set whether a stage runs. In this example, there's a pipeline with four stages and different jobs for each stage. The Performance Test stage runs if the parameter runPerfTests is true. The default value of runPerfTests is false, so only three of the four stages run unless you update the value.

parameters:
- name: runPerfTests
 type: boolean
 default: false

trigger: none

stages:
- stage: Build
 displayName: Build
 jobs:
 - job: Build
 steps:
 - script: echo running Build

- stage: UnitTest
 displayName: Unit Test
 dependsOn: Build
 jobs:
 - job: UnitTest
 steps:
 - script: echo running UnitTest

- ${{ if eq(parameters.runPerfTests, true) }}:
 - stage: PerfTest
 displayName: Performance Test
 dependsOn: Build
 jobs:
 - job: PerfTest
 steps:
 - script: echo running PerfTest

- stage: Deploy
 displayName: Deploy
 dependsOn: UnitTest
 jobs:
 - job: Deploy
 steps:
 - script: echo running UnitTest

Check for an empty parameter object

Use the length() expression to check if an object parameter has no value.

parameters:
- name: foo
 type: object
 default: []

steps:
- checkout: none
- ${{ if eq(length(parameters.foo), 0) }}:
 - script: echo Foo is empty
 displayName: Foo is empty

Parameter data types

Data type Notes
string string
stringList a list of items, multiple can be selected. Not available in templates
number may be restricted to values:, otherwise any number-like string is accepted
boolean true or false
object any YAML structure
step a single step
stepList sequence of steps
job a single job
jobList sequence of jobs
deployment a single deployment job
deploymentList sequence of deployment jobs
stage a single stage
stageList sequence of stages

The step, stepList, job, jobList, deployment, deploymentList, stage, stringList, and stageList data types all use standard YAML schema format. This example includes string, number, boolean, object, step, and stepList.

Note

The stringList data type isn't available in templates. Use the object data type in templates instead.

parameters:
- name: myString # Define a parameter named 'myString'
 type: string # The parameter type is string
 default: a string # Default value is 'a string'

- name: myMultiString # Define a parameter named 'myMultiString'
 type: string # The parameter type is string
 default: default # Default value is 'default', only one default
 values: # Allowed values for 'myMultiString'
 - default 
 - ubuntu 

- name: myStringlist # Define a parameter named 'myStringlist'
 type: stringList # The parameter type is stringList
 displayName: Regions
 values: # Allowed values for 'myStringlist'
 - WUS
 - CUS
 - EUS
 default: # Default values
 - WUS
 - CUS
 
- name: myNumber # Define a parameter named 'myNumber'
 type: number # The parameter type is number
 default: 2 # Default value is 2
 values: # Allowed values for 'myNumber'
 - 1 
 - 2 
 - 4 
 - 8 
 - 16 

- name: myBoolean # Define a parameter named 'myBoolean'
 type: boolean # The parameter type is boolean
 default: true # Default value is true

- name: myObject # Define a parameter named 'myObject'
 type: object # The parameter type is object
 default: # Default value is an object with nested properties
 foo: FOO # Property 'foo' with value 'FOO'
 bar: BAR # Property 'bar' with value 'BAR'
 things: # Property 'things' is a list
 - one 
 - two 
 - three 
 nested: # Property 'nested' is an object
 one: apple # Property 'one' with value 'apple'
 two: pear # Property 'two' with value 'pear'
 count: 3 # Property 'count' with value 3

- name: myStep # Define a parameter named 'myStep'
 type: step # The parameter type is step
 default: # Default value is a step
 script: echo my step 

- name: mySteplist # Define a parameter named 'mySteplist'
 type: stepList # The parameter type is stepList
 default: # Default value is a list of steps
 - script: echo step one 
 - script: echo step two 
 
trigger: none 

jobs: 
- job: stepList # Define a job named 'stepList'
 steps: ${{ parameters.mySteplist }} # Use the steps from the 'mySteplist' parameter

- job: myStep # Define a job named 'myStep'
 steps:
 - ${{ parameters.myStep }} # Use the step from the 'myStep' parameter

- job: stringList # Define a job named 'stringList'
 steps:
 - ${{ each region in parameters.myStringlist }}:
 - script: echo ${{region}}

Parameter security best practices

When you use runtime parameters in Azure Pipelines, don't pass secrets or sensitive values as parameter inputs. Parameter values are expanded at template parsing time and might be exposed in pipeline logs or outputs.

Always validate and restrict allowed parameter values to prevent injection of unexpected or unsafe input. Follow the principle of least privilege when granting access to pipeline resources.

For credentials, tokens, or other confidential data, use pipeline variables marked as secrets and stored in Azure Key Vault, the Pipeline UI, or variable groups. For more information, see Protect secrets in Azure Pipelines.


Feedback

Was this page helpful?

Additional resources