AZ-400: Designing and Implementing Microsoft DevOps Solutions
Implementing an Orchestration Automation Solution
YAML Templates
In this lesson, we'll explore YAML basics and how to leverage YAML templates in Azure DevOps. Whether you're an experienced DevOps engineer, a developer transitioning into operations, or coming from a systems administration background, this guide will help you master essential CI/CD skills. By the end of this lesson, you'll be comfortable writing efficient YAML pipelines and using templates to streamline your build, test, and deployment processes.
Example YAML Pipeline for an ASP.NET Project
Below is a comprehensive YAML pipeline example configured for an ASP.NET project. This pipeline installs necessary tools, restores packages, builds the solution, and runs tests:
# ASP.NET
# Build and test ASP.NET projects.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4
trigger:
- master
pool:
vmImage: 'windows-latest'
name: 'Default'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller@1
- task: NuGetCommand@2
inputs:
restoreSolution: '$(solution)'
- task: VSBuild@1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)\\"'
configuration: '$(buildConfiguration)'
- task: VSTest@2
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
YAML is both machine-readable and human-friendly. Azure DevOps uses YAML files to define pipelines, which are structured using key-value pairs, lists, and nested elements. In the ASP.NET example above, you can see the following components:
- Trigger: Executes the pipeline when changes are pushed to the master branch.
- Pool: Specifies the build agent, here using a Windows environment.
- Variables: Holds common values such as the solution file pattern, build platform, and configuration.
- Steps: Executes a series of tasks like installing NuGet, building the solution, and running tests.
Note
Think of YAML as a structured way to describe your process. It improves clarity, reusability, and maintainability of your pipelines.
Starter Pipeline Example
For new pipelines in Azure Repos Git, the Starter Pipeline is an excellent minimal template that you can customize. The simple template below makes it easy to set up a build process without relying on pre-packaged templates:
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: ubuntu-latest
name: 'Default'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
When you run this pipeline, the logs might display output similar to:
"C:\Windows\system32\cmd.exe" /D /E:ON /V:OFF /S /C "CALL \"C:\Users\jeremy\Downloads\agent_work_temp\66f121fab-641c-447d-80b9-3fce56d64c57.cmd\""
Hello, world!
Understanding the YAML Structure
YAML is constructed using three fundamental constructs:
Key-Value Pairs:
These are used for settings such astrigger
,pool
, andvariables
.Lists:
Lists are denoted by a dash (-
). They allow multiple items such as defining multiple branches to trigger the pipeline or multiple steps within the pipeline. For example:trigger: - master - develop
Nested Structures:
Indentation defines hierarchy. For example, additional properties can be nested within the pool configuration:pool: vmImage: 'ubuntu-latest' name: 'Default' fruits: - Apple - Banana - Cherry
Additionally, YAML supports nested dictionaries. For example, defining a person object can look like:
person:
name: Jeremy Morgan
age: 47
occupation: trainer
You can also reference variables in your pipelines. For instance:
person:
name: $(PipelineRunnerName)
age: $(PipelineRunnerAge)
occupation: trainer
This way, you can override variable values during runtime without changing the YAML file.
Variables and Best Practices
Variables enhance reusability and help you follow the DRY (Don't Repeat Yourself) principle. Instead of hardcoding values like "Jeremy Morgan" in multiple locations, you can define a variable once and reference it throughout your YAML file:
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
A best practice is to document your YAML files with comments. This aids future maintainers while keeping the file readable and concise.
Using Templates to Avoid Duplication
Azure DevOps supports breaking your pipeline into reusable templates. This modular approach prevents duplication of common tasks, such as installing NuGet and restoring solutions. Templates in Azure DevOps come in three types:
- Include templates
- Extend templates
- Parameter templates
For example, you can extract common tasks into a separate file named nuget.yml
:
# nuget.yml
steps:
- task: NuGetToolInstaller@1
- task: NuGetCommand@2
inputs:
command: 'restore'
restoreSolution: '$(solution)'
Then, in your main pipeline file, you can reference multiple templates for build and testing tasks:
trigger:
- master
pool:
vmImage: ubuntu-latest
name: 'Default'
person:
name: $(PipelineRunnerName)
age: $(PipelineRunnerAge)
occupation: trainer
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- script: echo $(PipelineRunnerName)
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
- template: nuget.yml
- template: build.yml
- template: test.yml
This method of dividing your pipeline into smaller templates offers the following benefits:
Template | Use Case | Description |
---|---|---|
nuget.yml | NuGet installation and package restore | Contains tasks for installing and restoring NuGet dependencies |
build.yml | Building the solution | Compiles the solution using designated parameters |
test.yml | Running tests | Executes unit or integration tests for the solution |
After committing your changes, you'll see a clear breakdown of steps in your pipeline. For instance, the Azure DevOps final view displays a summary of tasks, such as running scripts, NuGet installation, compilation, and tests.
Later, when reviewing the pipeline execution details, you'll observe each task executed in the defined order:
And upon inspecting the job details, each step's execution is clearly laid out:
Warning
Always maintain consistency in indentation and structure in YAML files. A small indentation error can lead to unpredictable pipeline behavior.
In Summary
This lesson has provided you with a detailed understanding of YAML pipelines in Azure DevOps, including key-value pairs, lists, and nested structures. We explored best practices for using variables and demonstrated how to create reusable templates to avoid code duplication. With these strategies, you can develop maintainable and scalable CI/CD pipelines that simplify automation and enhance development workflow.
Happy coding and best of luck building your CI/CD pipelines!
Watch Video
Watch video content