Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

Azure DevOps

Reusable Pipeline Templates for Azure DevOps

Pipeline templates let you write build and deploy logic once and reuse it across every repository. We create step, job and stage templates in a central repository, version them, add guardrails with extends templates, and convert classic task groups so teams stop copying YAML.

Key takeaways

  • Templates remove copy-paste, so a fix or improvement lands in every pipeline at once.
  • Step, job, stage and variable templates each solve a different reuse problem.
  • Extends templates can enforce required steps that teams cannot remove.
  • Templates live in a versioned repository and are consumed by tag, so changes are deliberate.
  • Classic task groups are converted to YAML templates, which are reviewable and testable.

The cost of copy-paste pipelines

In a young Azure DevOps organisation every repository gets its own azure-pipelines.yml, copied from the last one. A year later there are forty variants. One has the vulnerability scan, one does not. Three still use a deprecated task version. A bug fixed in one place is alive in the others. Nobody can answer the question “what do all our builds actually do?”

Templates are the fix. They are a core part of our Azure DevOps consulting, and they sit directly on top of a well-designed multi-stage pipeline.

What good looks like

  • Common logic lives in one place and is consumed by reference.
  • A template has a small, documented interface: parameters with sensible defaults.
  • Templates are versioned, so a change is released rather than leaked.
  • Security and compliance steps are enforced centrally, not requested politely.
  • Teams still have room to extend, so the template is a platform and not a cage.

How it works in practice

Four kinds of reuse

Step templates share a sequence of tasks, such as restore, build and test for a language. Job templates share a whole job, including its pool and dependencies. Stage templates share a full stage, for example “deploy to an environment”. Variable templates share values. We start with the smallest unit that removes real duplication, because large templates are harder to adapt.

A step template with parameters, saved as templates/dotnet-build.yml:

parameters:
  - name: project
    type: string
  - name: configuration
    type: string
    default: Release

steps:
  - task: DotNetCoreCLI@2
    displayName: Restore
    inputs:
      command: restore
      projects: ${{ parameters.project }}
  - task: DotNetCoreCLI@2
    displayName: Build and test
    inputs:
      command: test
      projects: ${{ parameters.project }}
      arguments: --configuration ${{ parameters.configuration }}

A consuming pipeline pulls the shared repository in as a resource and pins a tag:

resources:
  repositories:
    - repository: platform
      type: git
      name: Platform/pipeline-templates
      ref: refs/tags/v2.3.0

stages:
  - stage: Build
    jobs:
      - job: Build
        steps:
          - template: templates/dotnet-build.yml@platform
            parameters:
              project: src/Api/Api.csproj

Because the reference pins v2.3.0, a new template release reaches a service only when its team bumps the tag. That is the safety property that makes sharing practical.

Guardrails with extends

An extends template takes control of the whole pipeline structure. The shared template defines the required stages, such as a security scan before any deployment, and lets the team inject their own steps through parameters. When combined with required template checks on environments and service connections, it becomes enforceable: a pipeline that does not extend the approved template cannot reach production resources. Without those checks it is only convention, so we configure both.

Converting task groups

Task groups often hide important behaviour behind a name. We open each, list its tasks and parameters, and rewrite it as a step template. The new template is reviewed, tested on one pipeline, and then adopted widely. This is also the moment to remove tasks that are deprecated or no longer needed.

Testing and documenting templates

Shared code deserves the same care as application code. Each template in the central repository has a small sample pipeline that exercises it, and a validation pipeline runs those samples on every pull request to the template repository. A broken template is then caught before a tag is cut, not after forty teams pull it. Azure Pipelines can also validate a YAML file without running it, which is a cheap first check.

Documentation matters as much as the code. Every template carries a short description of its purpose, a table of parameters with types and defaults, and one copy-paste example. We keep this beside the template, so it changes in the same pull request as the behaviour.

Handling variation between teams

Teams rarely differ in everything. Most variation is a language version, a project path, a test filter or a target environment. We model those as parameters with defaults. When a team needs something genuinely different, we prefer to add a clearly named optional step list parameter, so they can inject steps at defined points, rather than forking the template. Forks are how consistency dies quietly.

Governance without bureaucracy

A lightweight change process keeps the shared repository healthy: pull requests reviewed by at least one platform engineer, a changelog, semantic version tags, and a deprecation window for old versions. For most organisations this is an hour of effort per release and avoids days of firefighting.

Decisions and trade-offs

Central repository or per-team templates? A central repository gives consistency but needs an owner and a release process. For a small organisation, one folder in one repository is enough. For many teams, a dedicated repository with tags is worth it.

Flexibility or strictness? More parameters make templates flexible and harder to reason about. We expose what teams genuinely vary, and keep the rest fixed.

When not to template. If a pipeline is unique, used once, and unlikely to change, inline YAML is clearer. Templates earn their keep from the third repetition onward.

Variable templates and environment settings

Values that change by environment, such as resource group names or scale settings, belong in variable templates keyed by stage. This keeps the deploy template identical for dev and production while the inputs differ, and it makes a review of “what is different in production” a one-file diff.

Common failure modes

  • Over-abstraction. Templates calling templates calling templates make debugging a treasure hunt.
  • Unpinned references. Pointing at main means a template change can break every build at once.
  • No owner. Shared code without an owner stagnates. We name one and document the contribution path.
  • Parameter explosion. When a template needs thirty parameters, it is probably two templates.

Delivery and handover

You receive the template repository, documentation with an example per template, a release process, and converted pipelines. Templates also make later work simpler, including a Jenkins migration, because converted jobs map onto known building blocks.

How to tell it is working

A change to a shared step reaches all services within days, new repositories get a working pipeline in minutes, audit questions about “what every build does” have a one-page answer, and the number of unique pipeline files shrinks. If you would like a review of your pipeline estate, get in touch.

References

How we deliver it

  1. 01

    Inventory what is duplicated

    We read your existing pipelines and task groups to find the logic that repeats and the differences that matter.

  2. 02

    Design the template API

    Parameters, defaults and boundaries are defined so templates are easy to use and hard to misuse.

  3. 03

    Build the central repository

    Templates are written and documented in one repository, with a tested sample pipeline for each.

  4. 04

    Add guardrails

    Where required, extends templates enforce scanning, signing or approval steps across teams.

  5. 05

    Migrate consumers

    Existing pipelines are switched to the templates one service at a time, each verified by a real run.

  6. 06

    Set versioning and ownership

    Release tags, a change process and a named owner keep the shared code safe to depend on.

Tools and technologies

Azure PipelinesYAML templatesAzure ReposGitHubAzure ArtifactsDockerTrivySonarQubeTerraformPowerShell

Frequently asked questions

What is the difference between a template and a task group?
Task groups are a classic-pipeline feature that bundles tasks in the web UI. YAML templates do the same job in source control, with parameters, conditionals and loops. Templates are reviewable, versioned and testable, so we convert task groups to templates rather than keep building on them.
What types of templates exist in Azure Pipelines?
There are four common types: step templates, job templates, stage templates and variable templates. Step templates reuse a sequence of tasks, job templates reuse a whole job, and stage templates reuse a full stage. Variable templates share values. We choose the smallest unit that removes the duplication.
How do we version shared templates safely?
Keep templates in their own repository and reference them with a resource that pins a tag or branch. Consumers upgrade by changing the reference, so a template change never silently alters every pipeline. Breaking changes get a new major tag and a short migration note.
Can templates enforce security steps?
Yes. An extends template wraps the whole pipeline, so required steps such as scanning or signing are baked in. Combined with checks on protected resources, teams can add their own jobs but cannot skip the mandatory ones. This must be paired with permissions, otherwise it is a convention.
Do templates make pipelines harder to read?
They can if overused. Deep nesting forces readers to jump through several files. We keep templates shallow, name them clearly, document parameters, and leave simple one-off logic inline. The goal is less repetition, not more indirection.

Talk to an engineer about azure pipelines templates

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.