DevOps Pipelines
Pipeline Structure
trigger:
branches:
include:
- main
- release/*
paths:
exclude:
- docs/**
- '*.md'
pr:
branches:
include: [main]
variables:
- group: my-variable-group
- name: buildConfiguration
value: Release
- name: imageTag
value: $(Build.BuildId)
pool:
vmImage: ubuntu-latest
stages:
- stage: Build
jobs:
- job: BuildAndTest
steps: [...]
- stage: Deploy
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs: [...]
Build Job Example
jobs:
- job: Build
displayName: 'Build and Test'
pool:
vmImage: ubuntu-latest
steps:
- checkout: self
fetchDepth: 0
- task: NodeTool@0
inputs:
versionSpec: '20.x'
- script: |
npm ci
npm run build
npm test
displayName: 'Install, build, test'
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: JUnit
testResultsFiles: '**/test-results.xml'
- task: Docker@2
inputs:
containerRegistry: myACRServiceConnection
repository: myapp
command: buildAndPush
tags: |
$(imageTag)
latest
Variables & Variable Groups
# pipeline variables
variables:
- name: APP_NAME
value: myapp
- name: DOCKER_REGISTRY
value: myregistry.azurecr.io
# Variable group (referenced from Library)
- group: prod-secrets # contains DB_PASSWORD, API_KEY
# Scoped to stage
stages:
- stage: Prod
variables:
- name: ENV
value: production
# Runtime parameters (user input at queue time)
parameters:
- name: runIntegrationTests
type: boolean
default: false
steps:
- script: npm run test:integration
condition: eq('${{ parameters.runIntegrationTests }}', 'true')
# Built-in predefined variables:
# $(Build.BuildId) - unique build ID
# $(Build.SourceBranch) - refs/heads/main
# $(Build.Repository.Name) - repo name
# $(System.TeamProject) - project name
Deployment Jobs & Environments
stages:
- stage: DeployProd
jobs:
- deployment: DeployToAKS
displayName: 'Deploy to AKS'
environment: 'production.default' # environment:namespace
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest@0
inputs:
action: deploy
kubernetesServiceConnection: aks-prod
manifests: k8s/*.yaml
containers: myregistry.azurecr.io/myapp:$(imageTag)
# Rolling deployment
- deployment: DeployRolling
environment: production
strategy:
rolling:
maxParallel: 25%
deploy:
steps:
- script: echo "Deploying batch"
Reusable Templates
# templates/build-steps.yml
parameters:
- name: nodeVersion
type: string
default: '20.x'
steps:
- task: NodeTool@0
inputs:
versionSpec: ${{ parameters.nodeVersion }}
- script: npm ci && npm run build
- script: npm test
# Main pipeline using template
stages:
- stage: Build
jobs:
- job: Build
steps:
- template: templates/build-steps.yml
parameters:
nodeVersion: '20.x'
Service Connections
| Connection Type | Usage |
|---|---|
| Docker Registry | Push/pull images (ACR, Docker Hub) |
| Kubernetes | Deploy to AKS clusters |
| Azure Resource Manager | Deploy to Azure services |
| GitHub | Checkout from GitHub repos |
| SSH | Deploy to remote servers |
| Maven/NuGet | Artifact feeds |