YAML Mastery for Azure DevOps Pipelines

Unlock the power of declarative CI/CD with Azure Pipelines YAML

Introduction to YAML Pipelines

Azure Pipelines allows you to define your Continuous Integration (CI) and Continuous Deployment (CD) workflows using YAML files. This approach offers several advantages:

This tutorial will guide you through the essentials of mastering YAML for your Azure DevOps pipelines.

Core Concepts of Azure Pipelines YAML

Understanding the fundamental building blocks of a YAML pipeline is crucial:

1. Triggers

Triggers define when a pipeline should run. The most common trigger is on code changes.

trigger: branches: include: - main - release/* paths: include: - src/* exclude: - README.md - docs/*

2. Stages, Jobs, and Steps

Pipelines are organized hierarchically:

stages: - stage: Build jobs: - job: BuildApp pool: vmImage: 'ubuntu-latest' steps: - script: echo Building the application... displayName: 'Run Build Script' - task: CmdLine@2 inputs: script: 'dotnet build --configuration Release' displayName: 'dotnet build' - task: PublishBuildArtifacts@1 inputs: pathToPublish: '$(Build.ArtifactStagingDirectory)' artifactName: 'drop' displayName: 'Publish Artifacts' - stage: Deploy dependsOn: Build jobs: - deployment: DeployToDev environment: 'Development' pool: vmImage: 'windows-latest' strategy: runOnce: deploy: steps: - script: echo Deploying to development environment... displayName: 'Deployment Script'

3. Variables

Variables allow you to parameterize your pipeline, making it more reusable and maintainable.

variables: buildConfiguration: 'Release' vmImage: 'ubuntu-latest' stages: - stage: Build jobs: - job: BuildApp pool: vmImage: $(vmImage) steps: - script: echo Building with configuration $(buildConfiguration)... displayName: 'Build with Variables'

4. Templates

Templates promote reuse by allowing you to define common pipeline logic that can be included in multiple pipelines.

Template Example (template.yml):

# template.yml parameters: - name: vmImage type: string default: 'ubuntu-latest' jobs: - job: GenericJob pool: vmImage: ${{ parameters.vmImage }} steps: - script: echo This is a reusable job! displayName: 'Reusable Step'

Using the Template:

resources: repositories: - repository: self type: git ref: refs/heads/main trigger: - main stages: - template: template.yml@self # Path to template in the same repo parameters: vmImage: 'windows-latest'

5. Service Connections

Service connections allow your pipeline to authenticate with external services (e.g., Azure subscriptions, Docker registries).

Note: Service connection names are typically defined in the Azure DevOps project settings and referenced here.

stages: - stage: DeployToAzure jobs: - deployment: DeployWebApp environment: 'Production' pool: vmImage: 'ubuntu-latest' strategy: runOnce: deploy: steps: - task: AzureWebApp@1 inputs: azureSubscription: 'MyAzureServiceConnection' # Name of your service connection appName: 'my-production-app' package: '$(Pipeline.Workspace)/drop/**/*.zip' displayName: 'Deploy to Azure Web App'

Advanced Techniques

Putting It All Together: A Simple CI/CD Example

This example shows a basic pipeline that builds a .NET Core application and deploys it to a hypothetical environment.

# azure-pipelines.yml trigger: - main variables: buildConfiguration: 'Release' projectPath: '**/MyProject.csproj' # Path to your project file buildPlatform: 'Any CPU' stages: - stage: Build displayName: 'Build Stage' jobs: - job: BuildJob displayName: 'Build .NET Core App' pool: vmImage: 'windows-latest' # Or 'ubuntu-latest' steps: - task: UseDotNet@2 displayName: 'Use .NET SDK 6.0' inputs: version: '6.0.x' - task: NuGetToolInstaller@1 displayName: 'Install NuGet' - task: NuGetCommand@2 displayName: 'Restore NuGet Packages' inputs: restoreSolution: '$(projectPath)' - task: VSBuild@1 displayName: 'Build Solution' inputs: solution: '$(projectPath)' msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactstagingdirectory)/WebApp.zip" /p:DeployIisAppPath="Default Web Site/myapp"' platform: '$(buildPlatform)' configuration: '$(buildConfiguration)' - task: PublishBuildArtifacts@1 displayName: 'Publish Artifacts' inputs: artifactName: 'drop' pathToPublish: '$(Build.ArtifactStagingDirectory)/WebApp.zip' - stage: Deploy displayName: 'Deploy Stage' dependsOn: Build condition: succeeded('Build') # Only run if Build stage succeeded jobs: - deployment: DeployJob displayName: 'Deploy to Development' environment: 'Development' strategy: runOnce: deploy: steps: - script: echo Starting deployment to Development environment... displayName: 'Pre-Deployment Info' - task: AzureRmWebAppDeployment@4 # Example for Azure Web Apps inputs: ConnectionType: 'AzureRM', azureSubscription: 'YourAzureServiceConnectionName', # Replace with your service connection name appType: 'webApp', WebAppName: 'your-dev-app-name', # Replace with your app name Package: '$(Pipeline.Workspace)/drop/WebApp.zip' displayName: 'Deploy Web App to Dev' - script: echo Deployment to Development complete. displayName: 'Post-Deployment Info'