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
| Service | Purpose |
|---|---|
| Repos | Git repositories (like GitHub) |
| Boards | Work items, sprints, backlogs (like Jira) |
| Pipelines | CI/CD automation (like GitHub Actions) |
| Artifacts | Package registry β npm, NuGet, Maven, PyPI |
| Test Plans | Manual 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
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 branchestrigger: branches: include: [main, release/*] exclude: [experimental/*]
# Disable CI trigger (manual only)trigger: none
# Scheduled triggerschedules: - cron: '0 2 * * *' # 2am UTC daily displayName: 'Nightly build' branches: include: [main] always: true # run even if no code changesVariables & 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 continuesSelf-Hosted Agents
pool: name: 'MyAgentPool' # self-hosted pool name demands: - Agent.OS -equals Linux - docker # agent must have docker installedSelf-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:
# Clone a repogit clone https://dev.azure.com/myorg/myproject/_git/myrepo
# Set up authenticationgit config --global credential.helper manager-core# Then use PAT (Personal Access Token) as passwordPR workflow:
- Create feature branch
- Push and open PR in Azure DevOps
- Reviewers added automatically (via branch policies)
- Pipeline runs on PR (status shown in PR)
- 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 Type | Purpose |
|---|---|
| Epic | Large feature (months) |
| Feature | Subset of Epic (weeks) |
| User Story | Specific functionality from user perspective |
| Task | Technical work within a story (hours) |
| Bug | Defect to fix |
Linking work items to code:
- Commit message:
Fixed AB#1234links commit to work item 1234 - PR description:
Resolves AB#1234closes work item on merge
Comparison: GitHub Actions vs Azure Pipelines
| Feature | GitHub Actions | Azure Pipelines |
|---|---|---|
| Syntax | YAML | YAML |
| Triggers | on: | trigger: / pr: |
| Jobs/Steps | jobs.*.steps | stages.jobs.steps |
| Reusable workflows | workflow_call | Templates (template:) |
| Secret storage | Repository/org secrets | Variable groups / Key Vault |
| Environment gates | Environments + required reviewers | Environments + approval checks |
| Artifact sharing | upload-artifact / download-artifact | PublishPipelineArtifact / DownloadPipelineArtifact |
| Hosted runners | ubuntu/windows/macos | ubuntu/windows/macos |
| Self-hosted | GitHub runners | Azure agents |
| Marketplace | GitHub Marketplace (Actions) | Azure DevOps Marketplace (Tasks) |
| Integration | Best with GitHub | Best with Azure |
| Pricing | Free minutes + per-minute | Free + 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.ymlparameters: - name: imageName type: string
steps: - task: Docker@2 inputs: repository: ${{ parameters.imageName }}
# Reference template in pipelinestages: - template: templates/docker-build.yml parameters: imageName: myappWhen 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