A
Etienne Deneuve
Mar 10, 2024 · 6 min read

Pipelines Templatization

Side view worker wearing gloves

Introduction

Templatization of pipelines is a powerful feature that enables the reuse of pipeline configurations across multiple pipelines and even projects, ensuring consistency, security and efficiency in the CI/CD process. This approach is supported by various CI/CD tools especially Azure DevOps, allowing teams to define standard pipeline step configurations that can be used across all pipelines in an organization.

The DRY (Don’t Repeat Yourself) principle

The DRY (Don’t Repeat Yourself) principle is a fundamental concept in software development that emphasizes the importance of avoiding redundancy by creating reusable and modular components. This principle is highly applicable to CI/CD pipelines.

In the context of pipelines, the DRY principle advocates for the creation of templates that encapsulate common configurations and workflows. By adhering to this principle, development teams can eliminate redundancy, reduce errors, and enhance the maintainability of their CI/CD processes.

Parameters and Variables in Templates

The essence of the DRY principle in pipeline templatization lies in the creation of reusable configurations using parameters. These parameters serve as dynamic inputs that allow customization while maintaining a standardized structure.

Parameters

Parameters are the values that you can pass into a template to customize its behavior. They can be used to control the execution of steps, jobs, or stages within a template. Parameters can be of various types, including strings, booleans, and objects, and they can have default values. Let’s see it with an example :

templates/node-step.yml
parameters:
- name: nodeVersion
default: '18.X'
steps:
- task: UseNode@1
displayName: Use Node version ${{ parameters.nodeVersion }}
inputs:
version: ${{ parameters.nodeVersion }}

This template accepts the nodeVErsion as a parameter and uses ‘18.X’ as the default when the parameter is not provided.

Variables

Variables in pipelines especially in Azure DevOps are a powerful feature that allows to dynamically assign values to parts of the pipeline configuration. They can be defined at various scopes pipeline, stage and job levels, making them highly flexible.

User-Defined Variables

variables:
myVariable: 'Hello World'
steps:
- script: echo $(myVariable)

System Variables

Azure DevOps provides a set of predefined system variables that are automatically available in the pipeline. These variables provide information about the pipeline, agent, and environment.

steps:
- script: echo $(Build.BuildId)

This step prints the ID of the current build, using the Build.BuildIdsystem variable.

Types of templates

As it is known, the common YAML pipeline in Azure DevOps is composed of stages, jobs and steps as shown in this example:

trigger:
- main
stages:
- stage: Build
displayName: 'Build Stage'
pool:
vmImage: ubuntu-latest
jobs:
- job: BuildJob
displayName: 'Build Job'
steps:
- script: echo Building the application...
displayName: 'Build Application'
- script: echo Running tests...
displayName: 'Run Tests'

So the same for types of templates:

  • Stage templates: Stage templates allow the definition of one or more stages that can be reused across multiple pipelines. For example, you might have a common stage for building, testing and deploying some applications.
templates/build-test-deploy.yml
parameters:
- name: buildJobName
stages:
- stage: Build
displayName: 'Build Stage'
jobs:
- job: Build
displayName: 'Build Job'
steps:
- script: echo Building...
- stage: Test
displayName: 'Test Stage'
jobs:
- job: Test
displayName: 'Test Job'
steps:
- script: echo Testing...
- stage: Deploy
displayName: 'Deploy Stage'
jobs:
- job: Deploy
displayName: 'Deploy Job'
steps:
- script: echo Deploying...

To use this stage template in a pipeline with buildJobName as a parameter:

azure-pipelines.yml
trigger:
- main
pool: 'ubuntu-latest'
stages:
- template: templates/build-test-deploy.yml
parameters:
buildJobName: 'Build Job'
  • Job Templates: Job templates allow defining one or more jobs that can be reused across different stages within pipelines. Example of job template:
templates/test.yml
jobs:
- job: Test
displayName: 'Test Job'
steps:
- script: echo Testing...

To use this job template in a stage:

azure-pipelines.yml
trigger:
- main
pool: 'ubuntu-latest'
stages:
- stage: Test
displayName: 'Test Stage'
jobs:
- template: templates/test.yml
  • Step Templates: Step templates allow the definition of one or more steps that can be reused across different jobs within multiple pipelines. This is useful for defining common tasks, such as running linting checks and installing Node which are frequently used.
templates/npm-install-step.yml
parameters:
- name: nodeVersion
steps:
- task: UseNode@1
displayName: Use Node version ${{ parameters.nodeVersion }}
inputs:
version: ${{ parameters.nodeVersion }}
- task: Cache@2
inputs:
key: 'npm | "$(Agent.OS)" | package-lock.json'
restoreKeys: |
npm | "$(Agent.OS)"
path: $(npm_config_cache)
displayName: Cache npm
- task: Bash@3
displayName: Install NodeJS Dependencies
inputs:
targetType: inline
script: |
npm ci
workingDirectory: $(System.DefaultWorkingDirectory)

To use this steps template in the main pipeline:

azure-pipelines.yml
trigger:
- main
pool: 'ubuntu-latest'
stages:
- stage: BuildAndTest
displayName: 'Build and Test Stage'
jobs:
- job: NpmInstall
displayName: 'Npm Install'
steps:
- template: templates/npm-install-step.yml
parameters:
nodeVersion: '20.X'
  • Variables Template: The variables template can be defined by specifying the variables and their values in a separate YAML file. For example:
templates/variables.yml
variables:
- name: nodeVersion
value: '18.X'

and it can be used like this:

azure-pipelines.yml
variables:
- template: 'templates/variables.yml'
trigger:
- main
pool: 'ubuntu-latest'
stages:
- stage: BuildAndTest
displayName: 'Build and Test Stage'
jobs:
- job: NpmInstall
displayName: 'Npm Install'
steps:
- template: templates/npm-install-step.yml
parameters:
nodeVersion: ${{ variables.nodeVersion }}

Benefits of Pipeline Templatization

  • Consistency and Standardization: Templatization ensures that all pipelines within an organization follow the same structure and conventions. This consistency is crucial for maintaining quality and reducing the risk of errors.
  • Reduced Duplication: By using templates, the pipelines are cleaner and easier to manage but also reduce the likelihood of errors.
  • Enhanced Maintainability: When changes need to be made, such as updating a step or adding a new parameter, you only need to update the template.
  • Flexibility and Customization: Templates can be customized with parameters, allowing the adaptation of the pipeline’s behavior to the specific needs of each project or stage.

In summary, the templatization of pipelines in the context of CI/CD processes, offers a multitude of benefits that enhance efficiency, sustainability, and effectiveness.

Templates Pipelines CI-CD

Related articles