devops

Azure DevOps β€” Enterprise Awareness

Why enterprises use it, pipelines YAML, Repos and Boards basics, comparison with GitHub Actions


Why Enterprises Use Azure DevOps

Azure DevOps (formerly VSTS / TFS) is Microsoft’s all-in-one DevOps platform. You’ll encounter it in any enterprise that uses Microsoft’s ecosystem (Azure, Office 365, Active Directory).

Why it persists in enterprises:

  • Deep Active Directory / Azure AD integration (SSO, RBAC out of the box)
  • Azure Boards for Agile tracking integrated with code and pipelines
  • On-premises option (Azure DevOps Server) for compliance requirements
  • Native Azure service connections (no separate credential management)
  • Long track record β€” many teams have years of pipelines and artifacts

Azure DevOps Services Overview

ServicePurpose
ReposGit repositories (like GitHub)
BoardsWork items, sprints, backlogs (like Jira)
PipelinesCI/CD automation (like GitHub Actions)
ArtifactsPackage registry β€” npm, NuGet, Maven, PyPI
Test PlansManual and exploratory testing management

Pipelines β€” YAML Overview

Azure Pipelines supports both YAML (pipeline-as-code) and classic UI pipelines. Always use YAML for new pipelines.

Basic Structure

azure-pipelines.yml
trigger:
branches:
include:
- main
- develop
paths:
exclude:
- docs/**
- '*.md'
pr:
branches:
include:
- main
variables:
dockerRegistry: 'myregistry.azurecr.io'
imageName: 'myapp'
tag: '$(Build.BuildId)'
pool:
vmImage: 'ubuntu-latest' # Microsoft-hosted agent
stages:
- stage: Build
displayName: 'Build and Test'
jobs:
- job: BuildJob
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
displayName: 'Install Node.js'
- script: npm ci
displayName: 'Install dependencies'
- script: npm test -- --coverage
displayName: 'Run tests'
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/test-results.xml'
- task: PublishCodeCoverageResults@2
inputs:
summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml'
- stage: Docker
displayName: 'Build Docker Image'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- job: DockerBuild
steps:
- task: Docker@2
displayName: 'Build and push image'
inputs:
containerRegistry: 'MyACRServiceConnection'
repository: '$(imageName)'
command: 'buildAndPush'
tags: |
$(tag)
latest
- stage: DeployStaging
displayName: 'Deploy to Staging'
dependsOn: Docker
environment: 'staging' # creates deployment record + approval gate
jobs:
- deployment: DeployToStaging
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest@1
inputs:
action: 'deploy'
kubernetesServiceConnection: 'staging-k8s'
manifests: 'k8s/*.yaml'
containers: '$(dockerRegistry)/$(imageName):$(tag)'

Key Concepts

Triggers

# Trigger on branches
trigger:
branches:
include: [main, release/*]
exclude: [experimental/*]
# Disable CI trigger (manual only)
trigger: none
# Scheduled trigger
schedules:
- cron: '0 2 * * *' # 2am UTC daily
displayName: 'Nightly build'
branches:
include: [main]
always: true # run even if no code changes

Variables & Variable Groups

variables:
# Inline variable
buildConfiguration: 'Release'
# Variable group (secrets stored in Azure DevOps / Key Vault)
- group: production-secrets
# Reference: $(variableName)
- script: echo "Building $(buildConfiguration)"
# Runtime expression: $[variables['variableName']]
condition: eq($[variables['Deploy']], 'true')

Service Connections

Service connections are Azure DevOps’ way of storing external credentials securely. You reference them by name in YAML.

Common service connections:

  • Azure Resource Manager β€” deploy to Azure services
  • Docker Registry β€” push/pull from ACR, Docker Hub
  • Kubernetes β€” deploy to AKS clusters
  • GitHub β€” access GitHub repos

Environments & Approval Gates

environment: 'production' # requires approval if configured
# Configure approvals in Azure DevOps UI:
# Environments β†’ production β†’ Approvals and checks β†’ Add approval
# Then specific users/groups must approve before pipeline continues

Self-Hosted Agents

pool:
name: 'MyAgentPool' # self-hosted pool name
demands:
- Agent.OS -equals Linux
- docker # agent must have docker installed

Self-hosted agents are needed when:

  • Accessing private network resources
  • Need custom software installed
  • Microsoft-hosted agents are too slow/expensive at scale

Repos + Boards Basics

Repos

Azure Repos is Git hosting with PR workflow similar to GitHub:

Terminal window
# Clone a repo
git clone https://dev.azure.com/myorg/myproject/_git/myrepo
# Set up authentication
git config --global credential.helper manager-core
# Then use PAT (Personal Access Token) as password

PR workflow:

  1. Create feature branch
  2. Push and open PR in Azure DevOps
  3. Reviewers added automatically (via branch policies)
  4. Pipeline runs on PR (status shown in PR)
  5. Merge after approvals + passing pipeline

Branch policies (enforce in Settings β†’ Repos β†’ Branches):

  • Minimum number of reviewers
  • Linked work items (boards integration)
  • Successful build required before merge
  • Comment resolution required

Boards

Azure Boards provides Agile project management:

Item TypePurpose
EpicLarge feature (months)
FeatureSubset of Epic (weeks)
User StorySpecific functionality from user perspective
TaskTechnical work within a story (hours)
BugDefect to fix

Linking work items to code:

  • Commit message: Fixed AB#1234 links commit to work item 1234
  • PR description: Resolves AB#1234 closes work item on merge

Comparison: GitHub Actions vs Azure Pipelines

FeatureGitHub ActionsAzure Pipelines
SyntaxYAMLYAML
Triggerson:trigger: / pr:
Jobs/Stepsjobs.*.stepsstages.jobs.steps
Reusable workflowsworkflow_callTemplates (template:)
Secret storageRepository/org secretsVariable groups / Key Vault
Environment gatesEnvironments + required reviewersEnvironments + approval checks
Artifact sharingupload-artifact / download-artifactPublishPipelineArtifact / DownloadPipelineArtifact
Hosted runnersubuntu/windows/macosubuntu/windows/macos
Self-hostedGitHub runnersAzure agents
MarketplaceGitHub Marketplace (Actions)Azure DevOps Marketplace (Tasks)
IntegrationBest with GitHubBest with Azure
PricingFree minutes + per-minuteFree + parallel job pricing

Template vs Action Concept

# GitHub Actions β€” reusable workflow
# .github/workflows/docker-build.yml (reusable)
on:
workflow_call:
inputs:
image-name:
required: true
type: string
# Azure Pipelines β€” template
# templates/docker-build.yml
parameters:
- name: imageName
type: string
steps:
- task: Docker@2
inputs:
repository: ${{ parameters.imageName }}
# Reference template in pipeline
stages:
- template: templates/docker-build.yml
parameters:
imageName: myapp

When to Choose Which

Choose GitHub Actions when:

  • Code is on GitHub
  • Open source project
  • Need broad ecosystem of community actions
  • Team is familiar with GitHub

Choose Azure Pipelines when:

  • Enterprise environment with Azure services
  • Need Active Directory / Azure AD integration
  • Compliance requirements (Azure DevOps Server on-prem)
  • Team uses Azure Boards and wants tight integration
  • Existing investment in Azure DevOps