Azure
AzureIntermediate

Azure DevOps Pipeline: Complete CI/CD Implementation Guide

DevHub Team
4 min read
Azure DevOpsCI/CDPipelineDevOps

TL;DR

A comprehensive guide to implementing CI/CD pipelines using Azure DevOps, including best practices, templates, and advanced deployment strategies

Azure DevOps Pipeline: Complete CI/CD Implementation Guide

Azure DevOps Pipelines provides a robust platform for implementing continuous integration and continuous delivery (CI/CD) workflows. This guide explores how to build efficient, secure, and scalable pipelines for your applications.

$1

``mermaid

graph TB

subgraph "Source Control"

A["Git Repository"]

B["Branch Policies"]

C["Pull Requests"]

end

subgraph "Build Pipeline"

D["Build Agent"]

E["Build Steps"]

F["Artifacts"]

end

subgraph "Release Pipeline"

G["Environments"]

H["Approvals"]

I["Deployment"]

end

A --> D

B --> D

C --> D

D --> E

E --> F

F --> G

G --> H

H --> I

classDef azure fill:#0078D4,stroke:#fff,color:#fff

class A,B,C,D,E,F,G,H,I azure

`

$1

Component Description Purpose
Triggers Event-based pipeline initiation Automation
Stages Logical grouping of jobs Organization
Jobs Series of steps Execution
Steps Individual tasks Implementation

$1

$1

`yaml

azure-pipelines.yml

trigger:

branches:

include:

- main

- develop

paths:

exclude:

- docs/*

- '*.md'

variables:

solution: '*/.sln'

buildPlatform: 'Any CPU'

buildConfiguration: 'Release'

stages:

  • stage: Build
  • jobs:

    - job: BuildJob

    pool:

    vmImage: 'ubuntu-latest'

    steps:

    - task: DotNetCoreCLI@2

    inputs:

    command: 'restore'

    projects: '$(solution)'

    - task: DotNetCoreCLI@2

    inputs:

    command: 'build'

    projects: '$(solution)'

    arguments: '--configuration $(buildConfiguration)'

    - task: DotNetCoreCLI@2

    inputs:

    command: 'test'

    projects: '*/*Tests/.csproj'

    arguments: '--configuration $(buildConfiguration)'

    - task: DotNetCoreCLI@2

    inputs:

    command: 'publish'

    publishWebProjects: true

    arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'

    - task: PublishBuildArtifacts@1

    inputs:

    pathtoPublish: '$(Build.ArtifactStagingDirectory)'

    artifactName: 'drop'

    `

    $1

    `yaml

    container-pipeline.yml

    trigger:

    branches:

    include:

    - main

    variables:

    dockerRegistry: 'myregistry.azurecr.io'

    imageName: 'myapp'

    tag: '$(Build.BuildId)'

    stages:

  • stage: Build
  • jobs:

    - job: BuildJob

    pool:

    vmImage: 'ubuntu-latest'

    steps:

    - task: Docker@2

    inputs:

    containerRegistry: 'ACR'

    repository: '$(imageName)'

    command: 'buildAndPush'

    Dockerfile: '/Dockerfile'

    tags: |

    $(tag)

    latest

    `

    $1

    $1

    Environment Approval Type Deployment Strategy
    Development Automated Direct
    Staging Manual Blue-Green
    Production Gated Canary

    $1

    `yaml

    deployment-strategies.yml

    stages:

  • stage: Deploy
  • jobs:

    - deployment: BlueGreen

    environment: staging

    strategy:

    blueGreen:

    deploy:

    steps:

    - task: AzureWebApp@1

    inputs:

    azureSubscription: 'Azure'

    appName: '$(webAppName)-staging'

    package: '$(Pipeline.Workspace)/drop/*/.zip'

    routeTraffic:

    steps:

    - task: AzureAppServiceManage@0

    inputs:

    azureSubscription: 'Azure'

    action: 'Swap Slots'

    webAppName: '$(webAppName)'

    sourceSlot: 'staging'

    targetSlot: 'production'

    postRouteTraffic:

    steps:

    - task: AppInsightsAlerts@0

    inputs:

    applicationInsightsWebTestId: '$(webTestId)'

    alertRule: 'Availability < 99%'

    `

    $1

    $1

    `yaml

    security-pipeline.yml

    trigger:

    branches:

    include:

    - main

    variables:

    sonarQubeProject: 'myproject'

    steps:

  • task: SonarQubePrepare@4
  • inputs:

    SonarQube: 'SonarQube'

    scannerMode: 'MSBuild'

    projectKey: '$(sonarQubeProject)'

  • task: DotNetCoreCLI@2
  • inputs:

    command: 'build'

  • task: SonarQubeAnalyze@4
  • task: WhiteSource@21
  • inputs:

    cwd: '$(System.DefaultWorkingDirectory)'

  • task: AzureKeyVault@1
  • inputs:

    azureSubscription: 'Azure'

    KeyVaultName: '$(keyVaultName)'

    SecretsFilter: '*'

    `

    $1

    Check Type Tool Purpose
    Code Quality SonarQube Static Analysis
    Security WhiteSource Dependency Scanning
    Compliance Azure Policy Policy Enforcement

    $1

    $1

    `typescript

    const analyticsConfig = {

    metrics: {

    pipeline: {

    successRate: 'percentage',

    duration: 'minutes',

    frequency: 'daily'

    },

    quality: {

    coverage: 'percentage',

    bugs: 'count',

    vulnerabilities: 'count'

    },

    performance: {

    buildTime: 'minutes',

    deploymentTime: 'minutes',

    failureRate: 'percentage'

    }

    },

    alerts: [

    {

    name: 'PipelineFailure',

    condition: 'successRate < 80%',

    severity: 'high'

    },

    {

    name: 'LongDuration',

    condition: 'duration > 60',

    severity: 'medium'

    }

    ]

    };

    `

    $1

    Metric Target Action if Exceeded
    Build Time < 10 minutes Optimize build steps
    Deployment Time < 5 minutes Review deployment strategy
    Success Rate > 95% Investigate failures

    $1

    $1

    1. Template Usage

    `yaml

    # template.yml

    parameters:

    environment: ''

    serviceConnection: ''

    steps:

    - task: AzureWebApp@1

    inputs:

    azureSubscription: ${{ parameters.serviceConnection }}

    appName: '$(webAppName)'

    deployToSlotOrASE: true

    resourceGroupName: '$(resourceGroup)'

    slotName: ${{ parameters.environment }}

    `

    2. Variable Management

    `yaml

    variables:

    - group: common-vars

    - group: ${{ parameters.environment }}-vars

    - name: buildConfiguration

    value: 'Release'

    - name: solution

    value: '*/.sln'

    ``

    $1

    $1

    Issue Cause Solution
    Build Failures Dependencies Update packages
    Deployment Errors Permissions Check service connections
    Test Failures Environment issues Verify test configuration

    $1

    1. [Azure DevOps Documentation](https://docs.microsoft.com/azure/devops)

    2. [YAML Schema Reference](https://docs.microsoft.com/azure/devops/pipelines/yaml-schema)

    3. [Pipeline Best Practices](https://docs.microsoft.com/azure/devops/pipelines/best-practices)

    4. [Security and Compliance](https://docs.microsoft.com/azure/devops/pipelines/security)

    5. [Pipeline Analytics](https://docs.microsoft.com/azure/devops/pipelines/reports)

    6. [Deployment Strategies](https://docs.microsoft.com/azure/devops/pipelines/release)

  • [Azure Container Apps](/posts/azure/container-apps) - Deploy containerized apps
  • [Azure OpenAI Service](/posts/azure/openai-service) - AI integration
  • [Azure Kubernetes Service Cost](/posts/azure/aks-cost) - Container orchestration
  • [Azure Functions v4](/posts/azure/functions-v4) - Serverless deployments
  • Why This Matters

    Understanding the business and technical context helps you make informed decisions rather than blindly following patterns.

    Trade-offs to Consider

    Every architectural decision involves trade-offs. Consider your specific requirements, team expertise, and scale when evaluating options.

    When NOT to Use This

    Knowing when a solution doesn't apply is as valuable as knowing when it does. Consider alternatives for your specific situation.

    Decision Framework

    Use this framework to evaluate whether this approach is right for your use case based on your specific constraints and requirements.