Unlock the power of declarative CI/CD with Azure Pipelines YAML
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.
Understanding the fundamental building blocks of a YAML pipeline is crucial:
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/*
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'
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'
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'
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'
$(Build.BuildId)
, $(System.TeamFoundationCollectionUri)
.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'