Back to Blog

End-to-End CI/CD with Azure Pipelines

Complete DevOps tutorial on Azure DevOps. Learn YAML pipelines, stages, jobs, tasks, triggers, approvals.

End-to-End CI/CD with Azure Pipelines

End-to-End CI/CD with Azure Pipelines

Introduction

Continuous Integration and Continuous Deployment (CI/CD) is a fundamental practice in DevOps that enables teams to deliver high-quality software faster and more reliably. Azure Pipelines, part of the Azure DevOps suite, provides a robust solution for automating the building, testing, and deployment of applications. With Azure Pipelines, teams can implement YAML-based pipelines that define the CI/CD process in a declarative way, making it easy to version control and share.

This tutorial will guide you through the process of setting up an end-to-end CI/CD pipeline using Azure Pipelines. We will explore key concepts such as stages, jobs, tasks, triggers, and approvals. By the end, you will have a comprehensive understanding of how to leverage Azure Pipelines to streamline your development workflow and ensure a seamless transition from code to production. This is crucial for DevOps/SREs, as it allows for faster feedback, improved collaboration, and higher software quality.

Prerequisites

Before you begin, ensure you have the following:

  • Azure DevOps Account: Sign up for a free Azure DevOps account at Azure DevOps.
  • A Project: Create a new project within Azure DevOps.
  • Git Repository: Have a Git repository set up within your Azure DevOps project.
  • Azure CLI: Installed on your local machine for interacting with Azure resources.
  • Basic Knowledge of YAML: Familiarity with YAML syntax will be beneficial.

Core Concepts

Definitions

  • CI/CD: Continuous Integration and Continuous Deployment is a practice that involves automatically testing and deploying code changes.
  • Azure Pipelines: A cloud service that allows you to automatically build, test, and deploy your code.
  • YAML Pipelines: Pipelines defined using YAML syntax that is version-controlled and can be used to define the CI/CD process.

Architecture

Azure Pipelines consists of the following elements:

  • Stages: Phases in the pipeline representing different parts of the workflow (e.g., Build, Test, Deploy).
  • Jobs: Units of work within a stage that can run sequentially or in parallel.
  • Tasks: Individual actions that are executed within jobs (e.g., running scripts, deploying applications).
  • Triggers: Events that start the pipeline (e.g., code push, pull requests).
  • Approvals: Gates that require manual intervention before proceeding to the next stage.

When to Use

Azure Pipelines is useful when:

  • You need to automate the build, test, and deployment processes.
  • You work in a team and need to ensure consistent practices.
  • You want to integrate with various cloud services and platforms.

Limitations

  • Azure Pipelines has limits on free-tier CI/CD minutes and artifacts storage.
  • Some advanced features may require a paid subscription.

Pricing Notes

Azure Pipelines offers a free tier that includes:

  • Up to 1,800 minutes of CI/CD per month for public repositories.
  • 1 free Microsoft-hosted agent for private repositories.

Syntax/Configuration

Here’s a basic structure of a YAML pipeline:

trigger:
- main

stages:
- stage: Build
  jobs:
  - job: BuildJob
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - script: echo Building...
      displayName: 'Build Step'

- stage: Deploy
  jobs:
  - job: DeployJob
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - script: echo Deploying...
      displayName: 'Deploy Step'

Parameter Table

Parameter Description
trigger Defines the branches that trigger the pipeline.
stages Lists the stages in the pipeline.
jobs Defines the jobs that run within a stage.
steps Specifies the tasks to execute in each job.

Practical Examples

Example 1: Simple CI Pipeline

Create a basic CI pipeline that builds a .NET application.

trigger:
- main

pool:
  vmImage: 'windows-latest'

steps:
- task: DotNetCoreCLI@2
  inputs:
    command: 'build'
    projects: '**/*.csproj'

Example 2: Adding Tests

Extend the pipeline to include unit tests.

steps:
- task: DotNetCoreCLI@2
  inputs:
    command: 'test'
    projects: '**/*Tests.csproj'

Example 3: Publish Artifacts

Publish the build artifacts for deployment.

steps:
- script: dotnet publish -c Release -o $(Build.ArtifactStagingDirectory)
  displayName: 'Publish Artifacts'

- publish: $(Build.ArtifactStagingDirectory)
  artifact: drop

Example 4: Multi-Stage Pipeline

Create a multi-stage pipeline with build and deploy stages.

stages:
- stage: Build
  jobs:
  - job: BuildJob
    steps:
    - script: echo Building...

- stage: Deploy
  jobs:
  - job: DeployJob
    dependsOn: Build
    steps:
    - script: echo Deploying...

Example 5: Conditional Execution

Run a job conditionally based on the outcome of another job.

jobs:
- job: BuildJob
  steps:
  - script: echo Building...

- job: DeployJob
  dependsOn: BuildJob
  condition: succeeded()  # Only run if BuildJob succeeded
  steps:
  - script: echo Deploying...

Example 6: Manual Approvals

Add approval gates before deploying to production.

stages:
- stage: Deploy
  jobs:
  - job: DeployJob
    steps:
    - script: echo Deploying...
  approvals:
    - approver: 'user@example.com'

Example 7: Scheduled Triggers

Set up a pipeline to run on a schedule.

schedules:
- cron: "0 0 * * *"  # Runs daily at midnight
  displayName: Daily midnight build
  branches:
    include:
    - main

Example 8: Environment Deployment

Deploy to an Azure environment using a service connection.

resources:
  environments:
  - name: production
    resourceType: VirtualMachine

jobs:
- deployment: DeployToProduction
  environment: production
  strategy:
    runOnce:
      deploy:
        steps:
        - script: echo Deploying to Production

Real-World Scenarios

Scenario 1: Microservices Deployment

In a microservices architecture, multiple services can be deployed independently. Use Azure Pipelines to manage CI/CD for each service in its repository, ensuring that changes don’t affect other services.

Scenario 2: Infrastructure as Code

Leverage Azure Pipelines to deploy infrastructure using tools like Terraform or Azure Resource Manager (ARM) templates. Automate the provisioning of resources required for your application.

Scenario 3: Multi-Environment Deployments

Setup separate pipelines for different environments (Dev, Test, Prod). Use approvals and environment checks in your pipeline to ensure that deployments are safe and controlled.

Best Practices

  1. Use YAML Pipelines: Version control your pipeline definitions for better traceability and collaboration. ✅
  2. Implement Testing Early: Include unit and integration tests in your CI process to catch issues early. 💡
  3. Automate Approvals: Use approval gates judiciously to minimize delays while ensuring governance. ⚠️
  4. Monitor Pipeline Performance: Regularly review pipeline success rates and execution times to identify bottlenecks. 🔧
  5. Secure Secrets: Use Azure Key Vault or pipeline secrets to manage sensitive information securely. 🔒

Common Errors

Error 1: Pipeline not found

Cause: The specified pipeline name is incorrect.

Fix: Check the spelling and ensure the pipeline exists in your Azure DevOps project.

Error 2: Job failed due to timeout

Cause: The job exceeded its allowed execution time.

Fix: Increase the timeout settings in the job configuration.

Error 3: Access Denied

Cause: Insufficient permissions to access resources.

Fix: Ensure that the service connection has the necessary permissions to access the resources.

Error 4: Build failed: MSBuild failed

Cause: A build error in the application code.

Fix: Review the build logs for specific errors and address them in your code.

Related Services/Tools

Tool/Service Description
GitHub Actions CI/CD automation directly in GitHub repositories.
Jenkins Open-source automation server with extensive plugins.
CircleCI Continuous integration and delivery platform.
GitLab CI/CD Built-in CI/CD capabilities in GitLab.

Automation Script

Here’s a simple Bash script to automate the creation of a basic Azure Pipeline:

#!/bin/bash

# Create a new Azure Pipeline
az devops pipeline create --name "MyPipeline" --yml-path "azure-pipelines.yml" --project "MyProject"

echo "Pipeline created successfully!"

Conclusion

In this tutorial, we covered the essentials of setting up an end-to-end CI/CD pipeline using Azure Pipelines. By understanding key concepts like stages, jobs, tasks, triggers, and approvals, you can automate your software delivery processes effectively. As you explore further, consider integrating testing frameworks and infrastructure as code to enhance your CI/CD practices.

For next steps, explore the official Azure Pipelines documentation and consider setting up more complex workflows with automated testing and multi-environment deployments.

References