Develop pipelines by using YAML
Develop pipelines by using YAML
A YAML pipeline is stored with its repository, so its history can be versioned and governed alongside the code it builds. Azure DevOps lets an author commit directly to a branch or create another branch and optionally open a pull request; whether a PR is mandatory depends on repository policy.
The four levels
Every YAML pipeline uses the same nesting, whether or not every level is written:
| Level | Execution target | Purpose |
|---|---|---|
| Stage | — | A major division such as build, test, or deploy |
| Agent-pool job | One assigned agent | The scheduling unit whose steps run sequentially on that agent |
| Step | Its job's execution target | One script, task, powershell, bash, or checkout |
| Deployment job | An environment | A job with a deployment strategy; each lifecycle hook resolves to an agent or server job, and VM hooks run on their VM targets |
You can omit levels. A pipeline containing only steps: is legal because Azure
Pipelines implies one job in one stage. Server jobs are agentless, so “one job,
one agent” is specifically an agent-pool-job rule rather than a universal rule.
Job and stage defaults
Jobs in a stage run in parallel by default. Ordering happens when you set
dependsOn. Actual concurrency still depends on agents and parallel-job capacity. Stages, by contrast, run sequentially by default.
jobs:
- job: A
steps:
- script: echo "A and B may start together"
- job: B
steps:
- script: echo "no dependsOn, so B does not wait for A"
- job: C
dependsOn: [A, B]
condition: succeeded()
steps:
- script: echo "C waits for both"At least one job must have no dependencies so the graph can start. Classic release pipelines differ: job dependencies are unsupported and multiple jobs run in sequence.
Conditions have a parent boundary
dependsOn defines the dependency graph and order. condition decides whether
a scheduled stage, job, or step runs, and a custom condition replaces the
implicit succeeded().
| Condition | Evaluates true when |
|---|---|
succeeded() | Dependencies succeeded; this is the default |
failed() | A dependency failed; useful for rollback or notification |
always() | Success, failure, or cancellation |
canceled() | The run was cancelled |
succeededOrFailed() | Success or failure, but not cancellation |
always() does not escape hierarchy: if a parent is skipped, its child cannot
run regardless of the child's condition. Cleanup after cancellation also needs
enough cancellation timeout to finish.
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))Deployment jobs and strategies
A deployment job targets an environment. Environments record deployment
history and provide a resource boundary for checks and approvals.
jobs:
- deployment: DeployWeb
environment: production
strategy:
runOnce:
preDeploy:
steps:
- script: echo "initialise"
deploy:
steps:
- script: echo "deploy the app"
routeTraffic:
steps:
- script: echo "shift traffic"
postRouteTraffic:
steps:
- script: echo "watch health"
on:
failure:
steps:
- script: echo "roll back"
success:
steps:
- script: echo "clean up"| Strategy | Behaviour | Constraint |
|---|---|---|
runOnce | Each lifecycle hook executes once | Simplest strategy |
rolling | Replaces targets in maxParallel batches | VM resources only |
canary | Deploys in increasing increments | Uses increments |
For rolling deployments, Azure Pipelines enters each lifecycle phase once per
batch. Within that phase, lifecycle-hook jobs and steps run on each VM target in
the batch. Six VMs with maxParallel: 2 therefore means three batches but six
executions of a per-VM install step.
Reuse and enforcement are separate
# Include: insert reusable content
steps:
- template: templates/npm-steps.yml
# Extend: let the template define allowed pipeline structure
extends:
template: templates/secure-pipeline.yml
parameters:
buildSteps:
- script: npm citemplate: composes content. extends: lets a platform-owned template define
the consumer's allowed structure, and typed parameters constrain what the
consumer can inject. But a team that controls its YAML can omit bare extends:.
To enforce adoption, configure a Required template check on a protected
resource every governed pipeline must consume. A pipeline fails that check if it
does not extend the required template. Enforcement therefore comes from the
protected-resource check; extends: supplies the constrained structure.
parameters:
- name: buildSteps
type: stepList
default: []Template-usable parameter types are string, number, boolean, object,
step, stepList, job, jobList, deployment, deploymentList, stage,
and stageList. stringList is not available inside templates. Choose the
narrowest type that supports the intended extension point.
What to carry into the exam
- Jobs default to parallel; stages default to sequential.
- Agent-pool job steps share one assigned agent; server jobs are agentless.
- A custom condition replaces
succeeded(), but a skipped parent still wins. - Rolling is VM-only: lifecycle phases iterate by batch and steps execute per VM.
extends:constrains structure; a Required template check enforces adoption.- Typed template parameters restrict the structures consumers can inject.
Primary sources
- https://learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/az-400
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/phases
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/stages
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/conditions
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/deployment-jobs
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/approvals
- https://learn.microsoft.com/en-us/azure/devops/pipelines/security/templates
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/runtime-parameters
- https://learn.microsoft.com/en-us/azure/devops/pipelines/get-started/yaml-pipeline-editor
- https://learn.microsoft.com/en-us/azure/devops/pipelines/process/environments