Skip to main content
In this lesson we’ll cover YAML fundamentals and how to use YAML templates in Azure DevOps pipelines. Whether you are an experienced DevOps engineer, moving from development, or transitioning from systems administration, this guide will help you understand essential CI/CD pipeline design: starting from small pipelines and progressing to reusable templates that keep your configuration DRY (Don’t Repeat Yourself). Below are concise, practical examples and clear explanations that follow the original sequence.

What is YAML for pipelines?

YAML (YAML Ain’t Markup Language) is a human-friendly data serialization format used to describe Azure DevOps pipelines. A pipeline YAML defines what triggers a run, which agents execute jobs, and the ordered steps performed (build, test, publish, deploy, etc.). A full ASP.NET build-and-test pipeline example:
We will begin with a much smaller pipeline and show how to extract repeated logic into templates.

Creating a new pipeline in Azure DevOps

When you create a pipeline in Azure DevOps, the wizard asks where your source code is hosted and offers a starter pipeline that you can customize.
A screenshot of the Azure DevOps "New pipeline" page asking "Where is your code?" with options like Azure Repos Git, Bitbucket Cloud, GitHub, and GitHub Enterprise Server shown. The left sidebar shows a project named KodeKloudData and pipeline-related navigation.
The Starter pipeline is a minimal YAML template you can evolve. Example starter pipeline:
  • trigger — branches or events that start the pipeline (example: pushes to master).
  • pool — selects the agent image the job runs on.
  • steps — executed sequentially; script steps run shell/cmd lines. Use displayName for readable step names in the pipeline UI.
Example trimmed run output for the one-line script:

YAML structure: keys, lists, and nested dictionaries

YAML constructs are simple and consistent:
  • Key-value pairs (scalars): e.g., vmImage: ubuntu-latest
  • Lists: items prefixed with - under a parent key (e.g., entries under steps)
  • Nested dictionaries: keys with indented child keys (e.g., properties under pool)
Example showing nested dictionaries, lists, and variables:
Key points:
  • Lists use - and indentation attaches items to their parent key.
  • Scalars are often unquoted, but quote any string that could be misinterpreted (numbers, booleans, values with colon or leading zero).
Use quotes for strings that could be misinterpreted (for example, values that look like numbers or booleans, or values with special characters). This prevents surprising parsing behavior.

Quick reference table: common pipeline keys

Variables in pipelines

Variables let you parameterize pipelines and avoid repeating values. Define at top-level with variables: and reference as $(VariableName). Example:
Use inside steps:
Variables can also be set or overridden in the Azure DevOps UI (including marking secrets or allowing queue-time overrides). They are ideal for controlling environments or selecting agent pools.

Best practices

  • Comment your YAML to explain intent for future readers.
  • Keep pipelines DRY — use variables and templates to reduce duplication.
  • Validate frequently — save and run pipelines to confirm behavior.
  • Use displayName to make pipeline runs easier to read in the UI.

Templates: centralize common tasks and avoid duplication

Templates let you reuse pipeline fragments across multiple pipelines. Azure DevOps supports including and extending templates and passing parameters to them. A typical pattern is to extract repeating task groups (NuGet restore, build, test) into separate YAML files and reference them with - template: 'file.yml'. Create nuget.yml for NuGet-related tasks:
Including this file in many pipeline YAMLs avoids retyping the same steps across projects.

Using templates in the main pipeline

Example main pipeline azure-pipelines.yml that reuses templates:
Warning: the Visual Studio build (VSBuild) and VSTest tasks require a Windows agent. Ensure your main pipeline uses a Windows VM image such as vmImage: 'windows-latest' when including those templates.
The VSBuild@1 and VSTest@2 tasks run only on Windows agents. If your pipeline includes Windows-specific templates, set vmImage: 'windows-latest' in the parent pipeline.
Example build.yml (Visual Studio build task):
Example test.yml (VSTest task):
With templates in place, your main pipeline becomes shorter, easier to read, and centralized: a change to a template affects all pipelines that include it.

Observing templates run in the UI

When a pipeline referencing templates runs, Azure DevOps renders template steps inline in the run view. For example, after adding templates you should see your initial scripts followed by the NuGet installer/restore, then build, then tests — all listed sequentially in the run output.
A screenshot of an Azure DevOps Pipelines page for the "KodeKloudData" project showing a list of recent pipeline runs with green check marks indicating successful builds. The left sidebar shows navigation items like Overview, Boards, Repos, Pipelines, and Artifacts.
Example trimmed run log showing NuGet installer execution:
You will see NuGet steps followed by Visual Studio build and VSTest steps in the overall run summary.

Closing notes

  • Use templates to centralize repetitive logic (NuGet restore, build, test).
  • Keep templates small and focused — easier to maintain and reuse.
  • Validate often and use displayName for meaningful pipeline run entries.
  • Templates and variables are practical for real-world CI/CD workflows and are commonly covered on certification exams such as AZ-400.
Further reading and references: This article covered YAML basics, variables, and extracting repeated steps into templates to build maintainable Azure DevOps pipelines.

Watch Video