Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
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.