As organizations continue to embrace DevOps practices to accelerate software delivery and improve collaboration, Azure DevOps has emerged as a leading platform supporting these goals. Whether you are a developer, tester, project manager, or DevOps engineer, understanding Azure DevOps is essential for many technical roles today. This article covers the most important Azure DevOps interview questions and answers for 2026, helping you prepare effectively for your next job interview.
Understanding Azure DevOps: An Overview
Azure DevOps is a comprehensive suite of development tools provided by Microsoft that supports the entire software development lifecycle. It enables teams to plan, develop, test, deliver, and maintain software efficiently. The platform offers integrated services for source control, continuous integration and continuous deployment (CI/CD), agile project management, artifact management, and testing.
One of the key strengths of Azure DevOps is its flexibility and extensibility. It integrates seamlessly with Git, the popular open-source distributed version control system, and also supports Team Foundation Version Control (TFVC), a centralized version control system. Additionally, Azure DevOps has a vast marketplace of extensions, allowing teams to customize their workflows and tools to suit specific DevOps lifecycle requirements. This adaptability is particularly beneficial in today’s fast-paced development environment, where teams must respond quickly to changing requirements and technologies.
Moreover, Azure DevOps fosters a culture of collaboration and transparency within teams. With features like pull requests, code reviews, and built-in dashboards, team members can easily share insights and feedback, leading to better code quality and more efficient problem-solving. The platform also supports integration with popular communication tools like Microsoft Teams and Slack, further enhancing collaboration across teams, regardless of their geographical locations.
Why Azure DevOps is Popular in 2026
In the evolving DevOps landscape, Azure DevOps stands out due to its end-to-end capabilities and ease of integration with other tools. Organizations benefit from its cloud-based infrastructure, which supports collaboration across distributed teams and automates many manual processes. The platform’s support for agile methodologies and its rich set of features make it a preferred choice for enterprises aiming to improve software quality and speed up delivery cycles. Additionally, the robust analytics and reporting capabilities of Azure DevOps allow teams to gain insights into their development processes, helping them make data-driven decisions that enhance productivity and efficiency.
As businesses increasingly adopt cloud-native architectures and microservices, Azure DevOps provides the necessary tools to facilitate these modern development practices. Its support for containerization technologies such as Docker and orchestration platforms like Kubernetes enables teams to build, deploy, and manage applications in a scalable and efficient manner. This adaptability to new technologies is crucial for organizations looking to stay competitive in an ever-evolving market landscape.
Core Services Offered by Azure DevOps
Azure DevOps provides several core services that cover different aspects of the software development lifecycle:
- Azure Repos: Provides Git repositories or TFVC for source control and versioning.
- Azure Pipelines: Enables CI/CD pipelines to automate building, testing, and deploying applications.
- Azure Boards: Supports agile project management with work items, backlogs, sprints, and dashboards.
- Azure Artifacts: Manages packages and dependencies used in development.
- Azure Test Plans: Offers tools for manual and automated testing to ensure software quality.
Each of these services is designed to work seamlessly together, providing a cohesive experience for development teams. For instance, Azure Pipelines can be directly linked to Azure Repos, allowing for automatic triggering of builds and deployments whenever changes are pushed to the repository. This integration not only streamlines the development process but also minimizes the risk of errors that can occur when managing multiple tools separately. Furthermore, Azure Boards enhances visibility into project progress, enabling teams to track their work effectively and adapt to changes in real time.
Common Azure DevOps Interview Questions and Detailed Answers
Now that we’ve covered the fundamental components of Azure DevOps and why it’s essential in 2026, let’s dive into the specific questions you’re likely to encounter in interviews. The following questions range from foundational concepts to practical applications, helping you demonstrate both theoretical knowledge and hands-on experience.
1. What is Azure DevOps and what are its main components?
Azure DevOps is a cloud-based platform by Microsoft that provides a suite of services to support the entire software development lifecycle. Its main components include Azure Repos for source control, Azure Pipelines for CI/CD, Azure Boards for project tracking, Azure Artifacts for package management, and Azure Test Plans for testing.

This integrated approach allows teams to collaborate efficiently, automate workflows, and deliver high-quality software faster.
2. How does Azure DevOps support version control?
Azure DevOps supports two types of version control systems: Git and Team Foundation Version Control (TFVC). Git is a distributed version control system widely used in the industry, allowing multiple developers to work on code simultaneously with local repositories. TFVC is a centralized version control system where developers check in code to a central server.
Using Azure Repos, teams can manage and track code changes effectively, enabling collaboration and maintaining a history of modifications for auditing and rollback purposes.
3. Can you explain the concept of CI/CD in Azure DevOps?
Continuous Integration (CI) and Continuous Deployment (CD) are key DevOps practices that Azure DevOps facilitates through Azure Pipelines. CI involves automatically building and testing code changes as they are committed to the repository, ensuring that new code integrates well with the existing codebase.
CD extends this by automating the deployment of validated code to production or staging environments. Azure Pipelines supports multiple languages and platforms, enabling teams to create robust workflows that reduce manual errors and accelerate delivery.
4. What are Azure Boards and how do they help in project management?
Azure Boards is a service within Azure DevOps that supports agile project management. It provides tools like work items, backlogs, sprint planning boards, and dashboards to track tasks, bugs, features, and user stories.
By using Azure Boards, teams can visualize their progress, prioritize work, and maintain transparency, which is crucial for iterative development and continuous improvement.
5. How does Azure DevOps integrate with Git and other tools?
Azure DevOps has native integration with Git, allowing users to create repositories, manage branches, and perform pull requests directly within the platform. Its extensible architecture supports integration with a wide range of third-party tools and services through a large marketplace of extensions.
This flexibility enables teams to customize their DevOps lifecycle, incorporating tools for code quality, security scanning, containerization, and more.
Advanced Azure DevOps Interview Questions
These foundational questions establish your understanding of Azure DevOps basics. However, interviewers often probe deeper to assess your practical experience and problem-solving abilities. The following advanced questions will help you demonstrate expertise in complex scenarios and architectural decisions.
6. What is the difference between Git and TFVC in Azure DevOps?
Git is a distributed version control system where each developer has a full copy of the repository, enabling offline work and multiple workflows like branching and merging. TFVC is centralized, with a single server repository where developers check in changes.
Git is generally preferred for its flexibility and support for modern development workflows, while TFVC may be used in scenarios requiring centralized control.
| Feature | Git (Distributed) | TFVC (Centralized) |
|---|---|---|
| Repository Model | Each developer has full repository copy | Single server-side repository |
| Offline Work | Full functionality offline | Limited offline capabilities |
| Branching | Lightweight, encourages feature branches | Heavier, path-based branching |
| Merging | Advanced merge algorithms | More complex merge process |
| Performance | Fast local operations | Network-dependent operations |
| Workflow Flexibility | Multiple workflows (Gitflow, trunk-based) | Linear workflow |
| File Locking | Not natively supported | Built-in file locking |
| History | Complete local history | Server-based history |
| Learning Curve | Steeper initial learning | Easier for beginners |
| Large Files | Requires Git LFS | Handles large files natively |
| Best For | Modern distributed teams, microservices | Legacy systems, strict centralized control |
7. How do you implement branching strategies in Azure DevOps?
Branching strategies in Azure DevOps depend on the team’s workflow and project requirements. Common strategies include:
- Feature branching: Developers create branches for new features and merge them back after completion.
- Gitflow: Uses dedicated branches for features, releases, and hotfixes to manage releases systematically.
- Mainline development: Focuses on a single main branch with short-lived feature branches.
Azure Repos supports all these strategies, and pull requests facilitate code reviews before merging.
8. What are Azure Artifacts and how do they benefit DevOps teams?
Azure Artifacts is a service that manages packages and dependencies used in software development. It supports multiple package types such as NuGet, npm, Maven, and Python.
By centralizing package management, Azure Artifacts helps teams share libraries securely, control versions, and reduce build times by caching dependencies.
9. How do you ensure quality and testing in Azure DevOps?
Azure DevOps provides Azure Test Plans, which includes tools for manual testing, exploratory testing, and automated test execution. Test cases can be linked to requirements and bugs, ensuring traceability.
Additionally, Azure Pipelines can integrate automated testing frameworks into CI/CD workflows, enabling continuous quality checks and faster feedback loops.
10. How do you manage secrets and sensitive data in Azure Pipelines?
Azure DevOps provides multiple approaches for managing secrets:
Variable Groups with Secret Variables: Store sensitive data as secret variables in Variable Groups, which are encrypted at rest and masked in logs. These can be linked to Azure Key Vault for centralized secret management.
Azure Key Vault Integration: The recommended approach is integrating Azure Pipelines with Azure Key Vault. Create a service connection to Key Vault, then reference secrets directly in your pipeline:
- task: AzureKeyVault@2 inputs: azureSubscription: 'MyServiceConnection' KeyVaultName: 'mykeyvault' SecretsFilter: '*' RunAsPreJob: true
Best Practices: Never hardcode secrets in YAML files or source code, use secret variables for pipeline-specific secrets, rotate secrets regularly, and limit access using Azure RBAC.
11. What are Service Connections and how do you secure them?
Service Connections are secure endpoints that allow Azure Pipelines to connect to external services like Azure subscriptions, Docker registries, Kubernetes clusters, or other cloud providers.
Security Best Practices:
- Use Workload Identity Federation instead of secrets where possible
- Apply least-privilege principles with specific resource group or resource-level permissions
- Enable “Approve for pipeline use” to prevent unauthorized pipeline access
- Regularly audit service connection usage and permissions
- Use separate service connections for different environments (dev, staging, production)
Service connections should be managed at the project level and protected using pipeline permissions and checks.
Security & Secrets Management
10. How do you manage secrets and sensitive data in Azure Pipelines?
Azure DevOps provides multiple approaches for managing secrets:
Variable Groups with Secret Variables: Store sensitive data as secret variables in Variable Groups, which are encrypted at rest and masked in logs. These can be linked to Azure Key Vault for centralized secret management.
Azure Key Vault Integration: The recommended approach is integrating Azure Pipelines with Azure Key Vault. Create a service connection to Key Vault, then reference secrets directly in your pipeline:
- task: AzureKeyVault@2
inputs:
azureSubscription: 'MyServiceConnection'
KeyVaultName: 'mykeyvault'
SecretsFilter: '*'
RunAsPreJob: true
Best Practices: Never hardcode secrets in YAML files or source code, use secret variables for pipeline-specific secrets, rotate secrets regularly, and limit access using Azure RBAC.
11. What are Service Connections and how do you secure them?
Service Connections are secure endpoints that allow Azure Pipelines to connect to external services like Azure subscriptions, Docker registries, Kubernetes clusters, or other cloud providers.
Security Best Practices:
- Use Workload Identity Federation instead of secrets where possible
- Apply least-privilege principles with specific resource group or resource-level permissions
- Enable “Approve for pipeline use” to prevent unauthorized pipeline access
- Regularly audit service connection usage and permissions
- Use separate service connections for different environments (dev, staging, production)
Service connections should be managed at the project level and protected using pipeline permissions and checks.
Containers & Kubernetes
12. How do you build and deploy Docker containers using Azure Pipelines?
Azure Pipelines provides native support for containerized applications through built-in tasks:
Building Docker Images:
- task: Docker@2
displayName: 'Build Docker Image'
inputs:
command: build
repository: 'myapp'
dockerfile: '$(Build.SourcesDirectory)/Dockerfile'
tags: |
$(Build.BuildId)
latest
Pushing to Container Registry:
- task: Docker@2
displayName: 'Push to ACR'
inputs:
command: push
repository: 'myapp'
containerRegistry: 'myACRServiceConnection'
tags: |
$(Build.BuildId)
latest
The pipeline can integrate with Azure Container Registry (ACR), Docker Hub, or other registries through service connections. Multi-stage builds optimize image size and security.
13. Explain how to deploy applications to Azure Kubernetes Service (AKS) using Azure DevOps.
Deploying to AKS involves several steps in Azure Pipelines:
1. Build and Push Container: Build Docker image and push to container registry 2. Update Kubernetes Manifests: Update deployment YAML with new image tag 3. Deploy to AKS: Use Kubernetes tasks to apply manifests
- task: Kubernetes@1
displayName: 'Deploy to AKS'
inputs:
connectionType: 'Azure Resource Manager'
azureSubscriptionEndpoint: 'MyAzureConnection'
azureResourceGroup: 'myResourceGroup'
kubernetesCluster: 'myAKSCluster'
command: 'apply'
arguments: '-f $(Build.SourcesDirectory)/k8s/'
Advanced Approach: Use Helm charts for templated deployments:
- task: HelmDeploy@0
inputs:
connectionType: 'Azure Resource Manager'
azureSubscription: 'MyAzureConnection'
azureResourceGroup: 'myResourceGroup'
kubernetesCluster: 'myAKSCluster'
command: 'upgrade'
chartType: 'FilePath'
chartPath: '$(Build.SourcesDirectory)/helm/myapp'
releaseName: 'myapp'
overrideValues: 'image.tag=$(Build.BuildId)'
For production, implement deployment strategies like blue-green or canary deployments using AKS features or service meshes.
YAML Pipelines & Multi-Stage
14. What is the difference between stages, jobs, and steps in Azure Pipelines?
Azure Pipelines has a hierarchical structure:
Stages: Logical boundaries in your pipeline representing phases like Build, Test, Deploy-Dev, Deploy-Prod. Stages run sequentially by default but can run in parallel. Each stage can have dependencies and conditions.
Jobs: Units of work that run on an agent. Multiple jobs within a stage run in parallel by default. Jobs can run on different agent pools or platforms (Windows, Linux, macOS).
Steps: Individual tasks within a job that run sequentially. These are the actual commands or tasks that perform work (build, test, deploy).
Example Structure:
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- script: echo "Building application"
- task: DotNetCoreCLI@2
- stage: Deploy
dependsOn: Build
jobs:
- job: DeployJob
steps:
- task: AzureWebApp@1
This hierarchy enables complex workflows with proper separation of concerns and parallel execution where appropriate.
15. How do you implement manual approvals and gates in Azure Pipelines?
Azure Pipelines supports approvals and checks at the environment level for deployment control:
Environments: Create environments in Azure DevOps (e.g., Production, Staging) Approvals: Configure approvals on environments requiring human validation before deployment Checks: Automated validations like Azure Function checks, REST API calls, or Azure Monitor queries
Pipeline Configuration:
stages:
- stage: DeployProduction
jobs:
- deployment: DeployWeb
environment: 'Production' # This environment has approvals configured
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
In the UI: Navigate to Environments → Select Environment → Approvals and checks → Add approval with specific users or groups.
Benefits: Ensures compliance, prevents accidental production deployments, and creates an audit trail of who approved what deployment.
16. Explain YAML pipeline templates and how they promote reusability.
YAML templates allow you to define reusable pipeline logic that can be shared across multiple pipelines:
Template Types:
- Stage templates: Reusable stages
- Job templates: Reusable jobs
- Step templates: Reusable steps
- Variable templates: Shared variables
Example Step Template (templates/build-steps.yml):
parameters:
- name: buildConfiguration
type: string
default: 'Release'
steps:
- task: DotNetCoreCLI@2
inputs:
command: 'restore'
- task: DotNetCoreCLI@2
inputs:
command: 'build'
arguments: '--configuration ${{ parameters.buildConfiguration }}'
Using the Template:
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- template: templates/build-steps.yml
parameters:
buildConfiguration: 'Release'
Benefits: Reduces code duplication, ensures consistency across pipelines, simplifies maintenance, and enables organization-wide standards.
Infrastructure as Code
17. How does Azure DevOps support Infrastructure as Code (IaC)?
Azure DevOps integrates with multiple IaC tools for infrastructure automation:
ARM Templates: Native Azure support using Azure Resource Group Deployment tasks:
- task: AzureResourceManagerTemplateDeployment@3
inputs:
deploymentScope: 'Resource Group'
azureResourceManagerConnection: 'MyServiceConnection'
resourceGroupName: 'myResourceGroup'
location: 'East US'
templateLocation: 'Linked artifact'
cstrTemplateFilePath: '$(Build.SourcesDirectory)/infrastructure/template.json'
cstrParametersFilePath: '$(Build.SourcesDirectory)/infrastructure/parameters.json'
Terraform: Using the Terraform task from marketplace:
- task: TerraformTaskV3@3
inputs:
provider: 'azurerm'
command: 'init'
backendServiceArm: 'MyServiceConnection'
- task: TerraformTaskV3@3
inputs:
provider: 'azurerm'
command: 'apply'
environmentServiceNameAzureRM: 'MyServiceConnection'
Bicep: Microsoft’s DSL for Azure resources, compiled to ARM templates Pulumi: Code-based infrastructure using familiar programming languages
IaC in pipelines enables version control, peer review, automated testing, and consistent deployments across environments.
Monitoring & Troubleshooting
18. How do you troubleshoot failed pipeline runs in Azure DevOps?
Systematic troubleshooting approach:
1. Check Pipeline Logs: Review detailed logs for each step, looking for error messages and exit codes 2. Enable System Diagnostics: Add variable system.debug = true for verbose logging 3. Review Pipeline Variables: Verify all required variables are defined and accessible 4. Check Service Connections: Ensure service connections have valid credentials and permissions 5. Agent Availability: Verify agents are online and have capacity 6. Dependency Issues: Check if dependencies (packages, tools) are accessible
Common Issues:
- Authentication failures: Expired service principals or permissions issues
- Agent timeout: Increase job timeout or optimize build steps
- Variable resolution: Secret variables not available in certain contexts
- Artifact publishing: Path issues or storage capacity
Debugging Techniques:
- script: |
echo "Debug: Build.SourcesDirectory = $(Build.SourcesDirectory)"
echo "Debug: Build.ArtifactStagingDirectory = $(Build.ArtifactStagingDirectory)"
ls -la $(Build.SourcesDirectory)
displayName: 'Debug filesystem'
19. What are pipeline analytics and how do they help improve DevOps processes?
Azure DevOps provides built-in analytics to measure and improve pipeline performance:
Key Metrics:
- Pass rate: Percentage of successful runs
- Duration: Average and trend of pipeline execution time
- Test pass rate: Quality metrics from automated tests
- Deployment frequency: How often code reaches production
- Lead time: Time from commit to production
Analytics Reports Available:
- Pipeline duration report (identifies bottlenecks)
- Pipeline pass rate report (quality trends)
- Test analytics (flaky tests, failure patterns)
- Deployment analytics (success rates by environment)
Using Insights: Navigate to Pipelines → Analytics to view reports and identify:
- Slow stages that need optimization
- Frequently failing tests requiring attention
- Agents with performance issues
- Deployment success patterns
These metrics support continuous improvement and data-driven decisions about DevOps process optimization.
Advanced Git & Branching
20. How do you handle merge conflicts in Azure Repos?
Merge conflicts occur when concurrent changes affect the same code lines:
Prevention Strategies:
- Keep branches short-lived (merge frequently)
- Pull latest changes before starting new work
- Use clear branching strategies with defined ownership
- Implement code ownership (CODEOWNERS file)
Resolution Process:
- Pull latest changes:
git pull origin main - Identify conflicts: Git marks conflicts in files with
<<<<<<<,=======,>>>>>>> - Resolve conflicts: Edit files to choose correct version or merge both changes
- Test thoroughly: Run builds and tests after resolution
- Commit resolution:
git add .thengit commit
In Azure DevOps PR:
- Conflicts shown in PR interface
- Can resolve simple conflicts directly in browser
- Complex conflicts require local resolution
Best Practices: Communicate with team members when resolving conflicts, understand both sets of changes, and never just accept “ours” or “theirs” without review.
21. Explain Branch Policies in Azure Repos and their importance.
Branch policies enforce quality standards and govern how code enters protected branches:
Common Policy Types:
Require Pull Requests: Direct pushes to main/master are blocked; all changes must go through PR review
Minimum Number of Reviewers: Enforce peer review (e.g., require 2 approvers)
Check for Linked Work Items: Ensure traceability by requiring work item association
Build Validation: Require successful build before PR completion
# Build validation policy triggers this pipeline
trigger: none # Explicit PR trigger only
pr:
branches:
include:
- main
Status Checks: Require external service checks to pass (security scans, code quality)
Comment Resolution: All PR comments must be resolved before merge
Configuration: Repository Settings → Policies → Branch Policies → Select branch
Benefits:
- Prevents broken code from reaching main branch
- Ensures code review and knowledge sharing
- Maintains audit trail
- Enforces compliance requirements
- Improves code quality through automated checks
Performance & Optimization
22. How do you optimize Azure Pipeline execution time?
Multiple strategies can reduce pipeline duration:
1. Parallel Jobs: Run independent jobs simultaneously
jobs:
- job: TestWindows
pool:
vmImage: 'windows-latest'
- job: TestLinux
pool:
vmImage: 'ubuntu-latest'
2. Caching Dependencies: Cache package downloads between runs
- task: Cache@2
inputs:
key: 'npm | "$(Agent.OS)" | package-lock.json'
path: $(npm_config_cache)
restoreKeys: |
npm | "$(Agent.OS)"
3. Incremental Builds: Build only changed components
4. Matrix Strategy: Test multiple configurations efficiently
strategy:
matrix:
Python38:
python.version: '3.8'
Python39:
python.version: '3.9'
Python310:
python.version: '3.10'
5. Self-Hosted Agents: Use dedicated agents with pre-installed tools and better performance
6. Conditional Execution: Skip unnecessary steps
- script: echo "Run only on main"
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
7. Artifact Optimization: Minimize artifact size and use artifact caching
Measurement: Use Pipeline Analytics to identify bottlenecks and measure improvement impact.
Permissions & Access Control
23. Explain the permission model in Azure DevOps.
Azure DevOps uses a hierarchical permission model with multiple levels:
Organization Level:
- Create projects
- Manage billing
- Install extensions
- Manage policies
Project Level:
- Create repositories
- Manage pipelines
- Edit project information
- Manage teams
Repository Level:
- Contribute (push code)
- Create branches
- Manage permissions
- Bypass policies
Pipeline Level:
- Queue builds
- Edit pipeline
- Manage pipeline
- View build
Security Groups:
- Readers: View-only access
- Contributors: Read and contribute
- Build Administrators: Manage pipelines
- Project Administrators: Full project control
Best Practices:
- Apply least-privilege principle
- Use groups instead of individual permissions
- Regularly audit access
- Separate production pipeline permissions
- Use service connections for automation (not personal accounts)
- Enable conditional access policies for sensitive projects
Configuration: Project Settings → Permissions → Select security group → Set permissions
Real-World Scenarios
24. Design a CI/CD pipeline for a microservices application with multiple services.
Architecture: A microservices application typically has 5-10+ services requiring coordinated deployment:
Pipeline Strategy:
1. Repository Structure: Mono-repo or multi-repo approach
- Mono-repo: Single repository with all services, using path filters
- Multi-repo: Separate repositories per service with orchestration pipeline
2. Build Pipeline (per service):
trigger:
branches:
include:
- main
paths:
include:
- services/user-service/*
stages:
- stage: Build
jobs:
- job: BuildUserService
steps:
- task: Docker@2
inputs:
command: build
repository: 'myapp/user-service'
dockerfile: 'services/user-service/Dockerfile'
tags: $(Build.BuildId)
- task: Docker@2
inputs:
command: push
repository: 'myapp/user-service'
containerRegistry: 'myACR'
3. Integration Testing: Test service interactions
4. Deployment Pipeline:
- stage: DeployDev
jobs:
- deployment: DeployServices
environment: Development
strategy:
runOnce:
deploy:
steps:
- task: HelmDeploy@0
inputs:
command: upgrade
chartPath: './helm/user-service'
releaseName: 'user-service'
- stage: DeployProd
dependsOn: DeployDev
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployProduction
environment: Production # With manual approval
Considerations:
- Service versioning and compatibility
- Database migration coordination
- Feature flags for gradual rollout
- Monitoring and alerting integration
- Rollback strategy per service
- API gateway configuration updates
25. How would you implement blue-green deployment using Azure DevOps?
Blue-green deployment maintains two identical production environments for zero-downtime releases:
Azure App Service Approach:
1. Setup: Create deployment slots (Blue = production, Green = staging)
2. Pipeline Configuration:
stages:
- stage: DeployToGreen
jobs:
- job: DeployGreenSlot
steps:
- task: AzureWebApp@1
inputs:
azureSubscription: 'MyServiceConnection'
appName: 'myapp'
deployToSlotOrASE: true
resourceGroupName: 'myResourceGroup'
slotName: 'staging' # Green environment
package: '$(Pipeline.Workspace)/**/*.zip'
- task: AzureAppServiceManage@0
displayName: 'Run smoke tests on Green'
inputs:
azureSubscription: 'MyServiceConnection'
action: 'Start Azure App Service'
- stage: SwapSlots
dependsOn: DeployToGreen
jobs:
- job: SwapToProduction
steps:
- task: AzureAppServiceManage@0
inputs:
azureSubscription: 'MyServiceConnection'
action: 'Swap Slots'
webAppName: 'myapp'
resourceGroupName: 'myResourceGroup'
sourceSlot: 'staging' # Swap Green to Blue
Kubernetes/AKS Approach:
- Use service selectors to switch between blue and green deployments
- Implement with Helm or Kubernetes manifests
- Update service to point to new deployment
Benefits: Instant rollback (swap back), testing in production-like environment, zero downtime Challenges: Database migrations, increased resource costs, session management
26. Describe how you would set up a complete DevOps workflow for a team transitioning from manual deployments.
Phase 1: Foundation (Weeks 1-2)
Version Control:
- Migrate code to Azure Repos (Git)
- Establish branching strategy (e.g., Gitflow or trunk-based)
- Configure branch policies (require PR, minimum reviewers)
- Train team on Git workflows
Project Setup:
- Create Azure DevOps project
- Set up teams and areas in Azure Boards
- Configure work item types (User Stories, Tasks, Bugs)
- Link repos to work items for traceability
Phase 2: Continuous Integration (Weeks 3-4)
Build Pipeline:
trigger:
- main
- develop
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UseDotNet@2
inputs:
version: '8.x'
- script: dotnet restore
- script: dotnet build --configuration Release
- task: DotNetCoreCLI@2
inputs:
command: test
projects: '**/*Tests.csproj'
arguments: '--configuration Release --logger trx'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '**/*.trx'
Quality Gates:
- Automated unit tests
- Code coverage requirements
- Static code analysis (SonarQube extension)
- Build status badges in README
Phase 3: Continuous Deployment (Weeks 5-6)
Environment Setup:
- Create Dev, Staging, Production environments
- Configure approvals for Staging and Production
- Set up service connections to Azure/cloud resources
Release Pipeline:
stages:
- stage: Dev
jobs:
- deployment: DeployDev
environment: Development
- stage: Staging
dependsOn: Dev
jobs:
- deployment: DeployStaging
environment: Staging # Requires approval
- stage: Production
dependsOn: Staging
jobs:
- deployment: DeployProduction
environment: Production # Requires approval
Phase 4: Monitoring & Improvement (Weeks 7-8)
Observability:
- Integrate Application Insights
- Set up dashboard in Azure DevOps
- Configure deployment notifications (Teams/Slack)
- Implement health checks
Continuous Improvement:
- Review pipeline analytics weekly
- Collect team feedback
- Iterate on process based on metrics
- Document runbooks and troubleshooting guides
Success Metrics:
- Deployment frequency increases from monthly to weekly/daily
- Lead time reduces from days to hours
- Failed deployment rate below 10%
- Mean time to recovery (MTTR) under 1 hour
Integration & Extensions
27. How does Azure DevOps integrate with GitHub?
Azure DevOps has deep integration with GitHub for organizations using both platforms:
Integration Capabilities:
1. GitHub Repos in Azure Pipelines:
trigger:
branches:
include:
- main
resources:
repositories:
- repository: MyGitHubRepo
type: github
endpoint: GitHubServiceConnection
name: myorg/myrepo
steps:
- checkout: MyGitHubRepo
2. Service Connection: Create GitHub service connection using OAuth or PAT
3. PR Validation: Azure Pipelines can validate GitHub pull requests automatically
4. Status Checks: Pipeline results appear as GitHub commit status checks
5. GitHub Actions Integration: Can trigger Azure Pipelines from GitHub Actions
6. Azure Boards + GitHub: Link GitHub commits, PRs, and issues to Azure Boards work items using AB#workitemID in commit messages
Use Cases:
- Open-source projects on GitHub using Azure Pipelines for free
- Organizations transitioning between platforms
- Leveraging both GitHub’s social coding and Azure’s enterprise features
Configuration: Project Settings → Service connections → New service connection → GitHub
CODE EXAMPLES
Complete Multi-Stage Production Pipeline Example
# azure-pipelines.yml - Complete production-ready example
trigger:
branches:
include:
- main
- develop
paths:
exclude:
- docs/*
- README.md
variables:
buildConfiguration: 'Release'
dockerRegistryServiceConnection: 'myACRConnection'
imageRepository: 'myapp'
containerRegistry: 'myregistry.azurecr.io'
dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
tag: '$(Build.BuildId)'
vmImageName: 'ubuntu-latest'
stages:
# ============================================
# BUILD STAGE
# ============================================
- stage: Build
displayName: 'Build and Test'
jobs:
- job: Build
displayName: 'Build Job'
pool:
vmImage: $(vmImageName)
steps:
# Restore dependencies from cache
- task: Cache@2
inputs:
key: 'npm | "$(Agent.OS)" | package-lock.json'
restoreKeys: |
npm | "$(Agent.OS)"
path: $(npm_config_cache)
displayName: 'Cache npm packages'
# Install dependencies
- script: npm ci
displayName: 'Install dependencies'
# Run linting
- script: npm run lint
displayName: 'Run ESLint'
# Run unit tests
- script: npm test -- --coverage --ci
displayName: 'Run unit tests'
# Publish test results
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/junit.xml'
mergeTestResults: true
testRunTitle: 'Unit Tests'
# Publish code coverage
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml'
# Build Docker image
- task: Docker@2
displayName: 'Build Docker image'
inputs:
command: build
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
latest
# Scan Docker image for vulnerabilities
- task: AzureContainerImageScanTask@0
displayName: 'Scan Docker image'
inputs:
image: '$(containerRegistry)/$(imageRepository):$(tag)'
# Push Docker image
- task: Docker@2
displayName: 'Push Docker image'
inputs:
command: push
repository: $(imageRepository)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
latest
# Publish Kubernetes manifests as artifact
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Build.SourcesDirectory)/k8s'
artifact: 'manifests'
publishLocation: 'pipeline'
# ============================================
# DEPLOY TO DEVELOPMENT
# ============================================
- stage: DeployDev
displayName: 'Deploy to Development'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: DeployDevelopment
displayName: 'Deploy to Dev Environment'
environment: 'Development'
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
# Download artifacts
- download: current
artifact: manifests
# Replace tokens in manifests
- task: qetza.replacetokens.replacetokens-task.replacetokens@3
displayName: 'Replace tokens in k8s manifests'
inputs:
targetFiles: '$(Pipeline.Workspace)/manifests/*.yml'
encoding: 'auto'
tokenPattern: 'default'
# Deploy to AKS
- task: Kubernetes@1
displayName: 'Deploy to AKS Dev'
inputs:
connectionType: 'Azure Resource Manager'
azureSubscriptionEndpoint: 'MyAzureConnection'
azureResourceGroup: 'myapp-dev-rg'
kubernetesCluster: 'myapp-dev-aks'
command: 'apply'
arguments: '-f $(Pipeline.Workspace)/manifests/'
# Wait for deployment to stabilize
- task: Kubernetes@1
displayName: 'Wait for deployment'
inputs:
connectionType: 'Azure Resource Manager'
azureSubscriptionEndpoint: 'MyAzureConnection'
azureResourceGroup: 'myapp-dev-rg'
kubernetesCluster: 'myapp-dev-aks'
command: 'rollout'
arguments: 'status deployment/myapp -n development'
# Run smoke tests
- script: |
echo "Running smoke tests..."
curl -f https://myapp-dev.example.com/health || exit 1
displayName: 'Run smoke tests'
# ============================================
# DEPLOY TO STAGING
# ============================================
- stage: DeployStaging
displayName: 'Deploy to Staging'
dependsOn: DeployDev
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployStaging
displayName: 'Deploy to Staging Environment'
environment: 'Staging' # Requires approval in Azure DevOps
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: manifests
# Get secrets from Key Vault
- task: AzureKeyVault@2
inputs:
azureSubscription: 'MyAzureConnection'
KeyVaultName: 'myapp-staging-kv'
SecretsFilter: '*'
RunAsPreJob: true
- task: qetza.replacetokens.replacetokens-task.replacetokens@3
displayName: 'Replace tokens'
inputs:
targetFiles: '$(Pipeline.Workspace)/manifests/*.yml'
- task: Kubernetes@1
displayName: 'Deploy to AKS Staging'
inputs:
connectionType: 'Azure Resource Manager'
azureSubscriptionEndpoint: 'MyAzureConnection'
azureResourceGroup: 'myapp-staging-rg'
kubernetesCluster: 'myapp-staging-aks'
command: 'apply'
arguments: '-f $(Pipeline.Workspace)/manifests/'
# Run integration tests
- script: npm run test:integration
displayName: 'Run integration tests'
env:
API_URL: 'https://myapp-staging.example.com'
# ============================================
# DEPLOY TO PRODUCTION
# ============================================
- stage: DeployProduction
displayName: 'Deploy to Production'
dependsOn: DeployStaging
condition: succeeded()
jobs:
- deployment: DeployProduction
displayName: 'Deploy to Production Environment'
environment: 'Production' # Requires approval from multiple approvers
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: manifests
# Get production secrets
- task: AzureKeyVault@2
inputs:
azureSubscription: 'MyAzureConnection'
KeyVaultName: 'myapp-prod-kv'
SecretsFilter: '*'
RunAsPreJob: true
- task: qetza.replacetokens.replacetokens-task.replacetokens@3
inputs:
targetFiles: '$(Pipeline.Workspace)/manifests/*.yml'
# Blue-Green deployment using labels
- task: Kubernetes@1
displayName: 'Deploy new version (Green)'
inputs:
connectionType: 'Azure Resource Manager'
azureSubscriptionEndpoint: 'MyAzureConnection'
azureResourceGroup: 'myapp-prod-rg'
kubernetesCluster: 'myapp-prod-aks'
command: 'apply'
arguments: '-f $(Pipeline.Workspace)/manifests/'
# Health check before traffic switch
- script: |
for i in {1..30}; do
if kubectl rollout status deployment/myapp -n production; then
echo "Deployment healthy"
exit 0
fi
sleep 10
done
echo "Deployment failed health check"
exit 1
displayName: 'Health check before traffic switch'
# Switch traffic to new version
- task: Kubernetes@1
displayName: 'Switch traffic to Green'
inputs:
connectionType: 'Azure Resource Manager'
azureSubscriptionEndpoint: 'MyAzureConnection'
azureResourceGroup: 'myapp-prod-rg'
kubernetesCluster: 'myapp-prod-aks'
command: 'patch'
arguments: 'service myapp -p ''{"spec":{"selector":{"version":"green"}}}'''
# Post-deployment validation
- script: |
echo "Running production smoke tests..."
for i in {1..10}; do
response=$(curl -s -o /dev/null -w "%{http_code}" https://myapp.example.com/health)
if [ $response -eq 200 ]; then
echo "Health check passed"
else
echo "Health check failed with status: $response"
exit 1
fi
sleep 5
done
displayName: 'Post-deployment validation'
Terraform Integration Example
# terraform-pipeline.yml - Infrastructure as Code deployment
trigger:
branches:
include:
- main
paths:
include:
- infrastructure/*
variables:
terraformVersion: '1.5.0'
workingDirectory: '$(System.DefaultWorkingDirectory)/infrastructure'
backendResourceGroup: 'terraform-state-rg'
backendStorageAccount: 'tfstatestorage'
backendContainerName: 'tfstate'
stages:
- stage: Validate
displayName: 'Terraform Validate'
jobs:
- job: Validate
pool:
vmImage: 'ubuntu-latest'
steps:
# Install Terraform
- task: TerraformInstaller@0
displayName: 'Install Terraform'
inputs:
terraformVersion: $(terraformVersion)
# Terraform Init
- task: TerraformTaskV3@3
displayName: 'Terraform Init'
inputs:
provider: 'azurerm'
command: 'init'
workingDirectory: $(workingDirectory)
backendServiceArm: 'MyAzureConnection'
backendAzureRmResourceGroupName: $(backendResourceGroup)
backendAzureRmStorageAccountName: $(backendStorageAccount)
backendAzureRmContainerName: $(backendContainerName)
backendAzureRmKey: 'prod.terraform.tfstate'
# Terraform Validate
- task: TerraformTaskV3@3
displayName: 'Terraform Validate'
inputs:
provider: 'azurerm'
command: 'validate'
workingDirectory: $(workingDirectory)
# Terraform Format Check
- script: |
terraform fmt -check -recursive
displayName: 'Check Terraform formatting'
workingDirectory: $(workingDirectory)
# Security Scan with Checkov
- script: |
pip install checkov
checkov -d $(workingDirectory) --output junitxml --output-file-path $(Build.ArtifactStagingDirectory)
displayName: 'Run Checkov security scan'
continueOnError: true
# Publish security scan results
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '$(Build.ArtifactStagingDirectory)/*.xml'
testRunTitle: 'Terraform Security Scan'
- stage: Plan
displayName: 'Terraform Plan'
dependsOn: Validate
condition: succeeded()
jobs:
- job: Plan
pool:
vmImage: 'ubuntu-latest'
steps:
- task: TerraformInstaller@0
inputs:
terraformVersion: $(terraformVersion)
- task: TerraformTaskV3@3
displayName: 'Terraform Init'
inputs:
provider: 'azurerm'
command: 'init'
workingDirectory: $(workingDirectory)
backendServiceArm: 'MyAzureConnection'
backendAzureRmResourceGroupName: $(backendResourceGroup)
backendAzureRmStorageAccountName: $(backendStorageAccount)
backendAzureRmContainerName: $(backendContainerName)
backendAzureRmKey: 'prod.terraform.tfstate'
# Terraform Plan
- task: TerraformTaskV3@3
displayName: 'Terraform Plan'
inputs:
provider: 'azurerm'
command: 'plan'
workingDirectory: $(workingDirectory)
environmentServiceNameAzureRM: 'MyAzureConnection'
commandOptions: '-out=tfplan'
# Publish plan as artifact
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(workingDirectory)/tfplan'
artifact: 'terraform-plan'
publishLocation: 'pipeline'
- stage: Apply
displayName: 'Terraform Apply'
dependsOn: Plan
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: ApplyInfrastructure
displayName: 'Apply Infrastructure Changes'
environment: 'Production-Infrastructure' # Requires approval
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- checkout: self
- task: TerraformInstaller@0
inputs:
terraformVersion: $(terraformVersion)
- task: TerraformTaskV3@3
displayName: 'Terraform Init'
inputs:
provider: 'azurerm'
command: 'init'
workingDirectory: $(workingDirectory)
backendServiceArm: 'MyAzureConnection'
backendAzureRmResourceGroupName: $(backendResourceGroup)
backendAzureRmStorageAccountName: $(backendStorageAccount)
backendAzureRmContainerName: $(backendContainerName)
backendAzureRmKey: 'prod.terraform.tfstate'
# Download the plan
- download: current
artifact: terraform-plan
# Apply the plan
- task: TerraformTaskV3@3
displayName: 'Terraform Apply'
inputs:
provider: 'azurerm'
command: 'apply'
workingDirectory: $(workingDirectory)
environmentServiceNameAzureRM: 'MyAzureConnection'
commandOptions: '$(Pipeline.Workspace)/terraform-plan/tfplan'
Reusable Pipeline Template Examples
Step Template: Build and Test .NET Application
# templates/dotnet-build-test.yml
parameters:
- name: buildConfiguration
type: string
default: 'Release'
- name: dotnetVersion
type: string
default: '8.x'
- name: runTests
type: boolean
default: true
- name: projectPath
type: string
default: '**/*.csproj'
steps:
# Install .NET SDK
- task: UseDotNet@2
displayName: 'Install .NET ${{ parameters.dotnetVersion }}'
inputs:
version: ${{ parameters.dotnetVersion }}
# Restore dependencies
- task: DotNetCoreCLI@2
displayName: 'Restore NuGet packages'
inputs:
command: 'restore'
projects: '${{ parameters.projectPath }}'
# Build application
- task: DotNetCoreCLI@2
displayName: 'Build application'
inputs:
command: 'build'
projects: '${{ parameters.projectPath }}'
arguments: '--configuration ${{ parameters.buildConfiguration }} --no-restore'
# Run tests (conditional)
- ${{ if eq(parameters.runTests, true) }}:
- task: DotNetCoreCLI@2
displayName: 'Run unit tests'
inputs:
command: 'test'
projects: '**/*Tests.csproj'
arguments: '--configuration ${{ parameters.buildConfiguration }} --no-build --collect:"XPlat Code Coverage" --logger trx'
publishTestResults: true
# Publish code coverage
- task: PublishCodeCoverageResults@1
displayName: 'Publish code coverage'
condition: succeededOrFailed()
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'
# Publish build artifacts
- task: DotNetCoreCLI@2
displayName: 'Publish application'
inputs:
command: 'publish'
projects: '${{ parameters.projectPath }}'
arguments: '--configuration ${{ parameters.buildConfiguration }} --output $(Build.ArtifactStagingDirectory) --no-build'
publishWebProjects: false
zipAfterPublish: true
- task: PublishPipelineArtifact@1
displayName: 'Publish pipeline artifact'
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
artifact: 'drop'
publishLocation: 'pipeline'
Using the Template:
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Build
jobs:
- job: BuildAndTest
steps:
- template: templates/dotnet-build-test.yml
parameters:
buildConfiguration: 'Release'
dotnetVersion: '8.x'
runTests: true
projectPath: 'src/**/*.csproj'
Job Template: Deploy to Azure App Service
# templates/deploy-webapp.yml
parameters:
- name: environment
type: string
- name: azureSubscription
type: string
- name: appName
type: string
- name: resourceGroup
type: string
- name: slotName
type: string
default: ''
- name: runSmokeTests
type: boolean
default: true
jobs:
- deployment: Deploy${{ parameters.environment }}
displayName: 'Deploy to ${{ parameters.environment }}'
environment: ${{ parameters.environment }}
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: drop
# Deploy to App Service
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App'
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
appType: 'webAppLinux'
appName: ${{ parameters.appName }}
resourceGroupName: ${{ parameters.resourceGroup }}
package: '$(Pipeline.Workspace)/drop/**/*.zip'
${{ if ne(parameters.slotName, '') }}:
deployToSlotOrASE: true
slotName: ${{ parameters.slotName }}
# Smoke tests (conditional)
- ${{ if eq(parameters.runSmokeTests, true) }}:
- script: |
echo "Running smoke tests for ${{ parameters.environment }}..."
APP_URL="https://${{ parameters.appName }}.azurewebsites.net"
# Wait for app to be ready
for i in {1..30}; do
response=$(curl -s -o /dev/null -w "%{http_code}" $APP_URL/health)
if [ $response -eq 200 ]; then
echo "App is healthy!"
break
fi
echo "Waiting for app to be ready... (attempt $i/30)"
sleep 10
done
# Run basic smoke tests
if [ $(curl -s -o /dev/null -w "%{http_code}" $APP_URL) -eq 200 ]; then
echo "Homepage accessible"
else
echo "Homepage not accessible"
exit 1
fi
displayName: 'Run smoke tests'
# Post-deployment notification
- script: |
echo "Deployment to ${{ parameters.environment }} completed successfully!"
echo "App URL: https://${{ parameters.appName }}.azurewebsites.net"
displayName: 'Deployment summary'
Using the Deployment Template:
# azure-pipelines.yml
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- template: templates/dotnet-build-test.yml
- stage: DeployDev
dependsOn: Build
jobs:
- template: templates/deploy-webapp.yml
parameters:
environment: 'Development'
azureSubscription: 'MyAzureConnection'
appName: 'myapp-dev'
resourceGroup: 'myapp-dev-rg'
runSmokeTests: true
- stage: DeployProd
dependsOn: DeployDev
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- template: templates/deploy-webapp.yml
parameters:
environment: 'Production'
azureSubscription: 'MyAzureConnection'
appName: 'myapp-prod'
resourceGroup: 'myapp-prod-rg'
slotName: 'staging'
runSmokeTests: true
Variable Group Management Example
# Using Variable Groups across environments
variables:
- group: 'common-variables' # Shared across all environments
- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
- group: 'production-variables'
- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/develop') }}:
- group: 'development-variables'
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- script: |
echo "Environment: $(environment)"
echo "API URL: $(apiUrl)"
echo "Build Number: $(Build.BuildNumber)"
displayName: 'Display configuration'
Variable Group Configuration (in Azure DevOps UI):
common-variables:
buildConfiguration: ReleasedockerRegistry: myregistry.azurecr.io
development-variables:
environment: DevelopmentapiUrl: https://api-dev.example.comresourceGroup: myapp-dev-rg
production-variables:
environment: ProductionapiUrl: https://api.example.comresourceGroup: myapp-prod-rgdbConnectionString: (secret, linked to Key Vault)
Matrix Build Strategy Example
# Testing across multiple platforms and versions
trigger:
- main
strategy:
matrix:
Linux_Python38:
imageName: 'ubuntu-latest'
python.version: '3.8'
Linux_Python39:
imageName: 'ubuntu-latest'
python.version: '3.9'
Linux_Python310:
imageName: 'ubuntu-latest'
python.version: '3.10'
Windows_Python39:
imageName: 'windows-latest'
python.version: '3.9'
Mac_Python310:
imageName: 'macOS-latest'
python.version: '3.10'
pool:
vmImage: $(imageName)
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(python.version)'
displayName: 'Use Python $(python.version)'
- script: |
python -m pip install --upgrade pip
pip install -r requirements.txt
displayName: 'Install dependencies'
- script: |
pip install pytest pytest-cov
pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=. --cov-report=xml
displayName: 'Run tests with pytest'
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFiles: '**/test-*.xml'
testRunTitle: 'Python $(python.version) on $(imageName)'
displayName: 'Publish test results'
Conditional Pipeline Execution Example
# azure-pipelines.yml - Smart conditional execution
trigger:
branches:
include:
- main
- develop
- feature/*
paths:
exclude:
- docs/**
- README.md
- '*.md'
variables:
isMainBranch: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
isDevelopBranch: $[eq(variables['Build.SourceBranch'], 'refs/heads/develop')]
isFeatureBranch: $[startsWith(variables['Build.SourceBranch'], 'refs/heads/feature/')]
stages:
# Always run Build stage
- stage: Build
displayName: 'Build Application'
jobs:
- job: BuildJob
steps:
- script: echo "Building application..."
- script: npm install
- script: npm run build
# Run linting only on feature branches
- script: npm run lint
displayName: 'Run ESLint'
condition: eq(variables.isFeatureBranch, true)
# Run tests on all branches
- stage: Test
dependsOn: Build
condition: succeeded()
jobs:
- job: UnitTests
steps:
- script: npm test
displayName: 'Unit Tests'
# Integration tests only for develop and main
- job: IntegrationTests
condition: or(eq(variables.isMainBranch, true), eq(variables.isDevelopBranch, true))
steps:
- script: npm run test:integration
displayName: 'Integration Tests'
# Deploy to Dev - only for develop branch
- stage: DeployDev
dependsOn: Test
condition: and(succeeded(), eq(variables.isDevelopBranch, true))
jobs:
- deployment: DeployToDev
environment: Development
strategy:
runOnce:
deploy:
steps:
- script: echo "Deploying to Development"
# Deploy to Staging - only for main branch
- stage: DeployStaging
dependsOn: Test
condition: and(succeeded(), eq(variables.isMainBranch, true))
jobs:
- deployment: DeployToStaging
environment: Staging
strategy:
runOnce:
deploy:
steps:
- script: echo "Deploying to Staging"
# Deploy to Production - only for main branch with manual approval
- stage: DeployProduction
dependsOn: DeployStaging
condition: and(succeeded(), eq(variables.isMainBranch, true))
jobs:
- deployment: DeployToProduction
environment: Production # Has manual approval configured
strategy:
runOnce:
deploy:
steps:
- script: echo "Deploying to Production"
3. TROUBLESHOOTING SCENARIOS
Scenario 1: Pipeline Fails with “No hosted parallelism has been purchased or granted”
Problem: Pipeline queued but never starts running
Solution:
# Option 1: Use self-hosted agent
pool:
name: 'Default' # Your self-hosted agent pool
# Option 2: Request free tier for public projects
# Go to: https://aka.ms/azpipelines-parallelism-request
# Option 3: Purchase parallel jobs
# Organization Settings → Billing → Change paid parallel jobs
Scenario 2: Docker Build Fails with “denied: requested access to the resource is denied”
Problem: Cannot push Docker image to registry
Diagnosis Steps:
# Add debugging
- script: |
echo "Registry: $(containerRegistry)"
echo "Repository: $(imageRepository)"
echo "Tag: $(tag)"
docker images
displayName: 'Debug Docker configuration'
# Check service connection
- script: |
az acr login --name myregistry
displayName: 'Test ACR login'
Solution:
- Verify service connection has
AcrPushrole - Check repository name format (lowercase only)
- Ensure container registry allows anonymous pull if needed
- Verify firewall rules allow Azure DevOps IPs
Scenario 3: Variables Not Resolving in Pipeline
Problem: Variables showing as $(variableName) instead of actual values
Common Causes & Solutions:
# Issue: Using macro syntax in wrong context
# Wrong:
- script: echo $(myVariable) # Works
- task: SomeTask@1
inputs:
value: $(myVariable) # May not work in all contexts
# Correct: Use runtime expression
- task: SomeTask@1
inputs:
value: $[variables.myVariable]
# Issue: Secret variables in different job
# Variables set in one job aren't available in another
jobs:
- job: JobA
steps:
- script: echo "##vso[task.setvariable variable=myVar;isOutput=true]myValue"
name: setVar
- job: JobB
dependsOn: JobA
variables:
myVar: $[ dependencies.JobA.outputs['setVar.myVar'] ]
steps:
- script: echo $(myVar)
Scenario 4: Kubernetes Deployment Stuck
Problem: Deployment to AKS hangs or times out
Debugging:
- task: Kubernetes@1
displayName: 'Check pod status'
inputs:
command: 'get'
arguments: 'pods -n production'
- task: Kubernetes@1
displayName: 'Describe deployment'
inputs:
command: 'describe'
arguments: 'deployment/myapp -n production'
- task: Kubernetes@1
displayName: 'Check events'
inputs:
command: 'get'
arguments: 'events -n production --sort-by=.metadata.creationTimestamp'
Common Solutions:
- Image pull errors: Check service connection and image name
- Resource limits: Adjust CPU/memory requests
- Liveness probe failures: Increase initialDelaySeconds
- ConfigMap/Secret missing: Verify they exist in namespace
Best Practices and Tips for Azure DevOps Interviews
Preparing for an Azure DevOps interview requires not only understanding the platform’s features but also demonstrating practical knowledge of DevOps principles and workflows. Here are some tips to help you succeed:

Understand the DevOps Culture and Principles
Interviewers often assess your grasp of DevOps beyond tools. Be ready to discuss how Azure DevOps supports collaboration, automation, continuous improvement, and faster delivery.
Demonstrate Hands-on Experience
Practical experience with setting up pipelines, managing repositories, and using Azure Boards can set you apart. Be prepared to explain your approach to solving common challenges like merge conflicts, deployment failures, or test automation.
Stay Updated on New Features
Azure DevOps evolves continuously. Familiarize yourself with recent updates, new extensions, and best practices to show that you keep your skills current.
Prepare for Scenario-Based Questions
Many interviews include scenario questions where you must design or troubleshoot a DevOps pipeline or workflow. Practice articulating your thought process clearly and logically.
Conclusion
Azure DevOps remains a critical platform for organizations adopting DevOps practices in 2026. Its comprehensive suite of tools covering source control, CI/CD, project management, artifact handling, and testing makes it indispensable for modern software development teams.

By mastering the questions outlined in this article, candidates can confidently demonstrate their knowledge and practical skills during interviews. Understanding both the technical capabilities and the cultural aspects of DevOps will help you stand out and secure your desired role. Make sure to also review the top DevOps skills for 2026 to round out your preparation.
For more detailed learning, consider exploring official Microsoft documentation and hands-on labs to deepen your expertise in Azure DevOps. If you want to validate your skills formally, our overview of top Azure DevOps certifications can help you choose the right path.








Leave a Reply