| title | Use runtime and type-safe parameters |
|---|---|
| description | Learn how to use runtime parameters to customize pipeline behavior, control data types, and dynamically pass values. |
| ms.topic | concept-article |
| ms.date | 07/15/2025 |
| monikerRange | <=azure-devops |
| ai-usage | ai-assisted |
[!INCLUDE version-lt-eq-azure-devops]
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.
[!INCLUDE variables-vs-parameters]
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.
You can also use parameters as part of conditional logic. With conditionals, part of a YAML runs if it meets the if criteria.
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"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...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 UnitTestUse 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[!INCLUDE parameter-data-types]
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.
