Azure CI CD Pipeline Setup: A Production YAML Guide

The Reality of Azure DevOps Pipelines

When you move beyond clicking around the Azure DevOps classic UI editor, you land in the world of multi-stage YAML pipelines. If you are managing standard web apps, microservices, or even containerized backend stacks, building a repeatable Azure CI CD pipeline setup saves your team from drift, manual errors, and deployment anxiety.

Over the years, I've seen teams struggle with hardcoded secrets, overly complex template hierarchies, and slow build agents. This guide cuts through the noise. We will build a production-grade YAML pipeline that compiles code, runs automated tests, builds a Docker image, pushes it to Azure Container Registry (ACR), and deploys it safely to Azure App Service or Azure Kubernetes Service (AKS).

Prerequisites and Architecture

Before writing any YAML, ensure you have the following in place within your Azure subscription:

  • An Azure DevOps Organization and Project.
  • An Azure Container Registry (ACR) for storing container images.
  • A target compute resource (e.g., Azure App Service or AKS cluster).
  • A Service Connection configured with your Azure subscription (prefer Workload Identity federation over long-lived secrets where possible).

For a broader look at how we structure application delivery, you can explore our services or read our insights on the blog.

Step 1: The Continuous Integration (CI) Stage

The CI stage is responsible for validating code quality, running unit tests, and packaging artifacts. Here is a robust YAML snippet for a Node.js or general containerized service.

Create an azure-pipelines.yml file in the root of your repository:

trigger:
  branches:
    include:
      - main
      - develop

pool:
  vmImage: 'ubuntu-latest'

variables:
  tag: '$(Build.BuildId)'
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: 'Build and Test Stage'
  jobs:
  - job: BuildJob
    displayName: 'Run Tests and Build Artifacts'
    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '20.x'
      displayName: 'Install Node.js'

    - script: |
        npm ci
        npm run test:ci
      displayName: 'Run Unit Tests'

    - task: Docker@2
      displayName: 'Build and push Docker image'
      inputs:
        command: 'buildAndPush'
        repository: 'my-app-service'
        dockerfile: 'Dockerfile'
        containerRegistry: 'my-acr-service-connection'
        tags: |
          $(tag)
          latest

Step 2: The Continuous Deployment (CD) Stage

Once the CI stage successfully pushes an image to ACR, the CD stage takes over. In a production environment, you should always gate your deployments using environments and approval checks.

Add the deployment stage to your azure-pipelines.yml:

- stage: Deploy
  displayName: 'Deploy to Production'
  dependsOn: Build
  condition: succeeded()
  pool:
    vmImage: 'ubuntu-latest'
  environment: 'production'
  jobs:
  - deployment: DeployToAppService
    displayName: 'Deploy Container to Azure App Service'
    environment: 'production'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureWebAppContainer@1
            displayName: 'Azure Web App Container Deploy'
            inputs:
              azureSubscription: 'azure-subscription-service-connection'
              appName: 'my-prod-app-service'
              imageName: 'myacr.azurecr.io/my-app-service:$(tag)'

If you are scaling infrastructure or rethinking your deployment targets—whether moving toward containers or managing cloud costs—you might find our guide on migrating a small SaaS to Kubernetes helpful.

Step 3: Managing Secrets and Variables Securely

Never hardcode database connection strings, API keys, or client secrets in your YAML files. Instead, use Azure DevOps Variable Groups linked to Azure Key Vault.

  1. In Azure DevOps, go to Pipelines > Library > Variable groups.
  2. Create a group named prod-secrets.
  3. Link secrets from your Azure Key Vault instance.
  4. Consume them in your pipeline like this:
variables:
  - group: 'prod-secrets'

steps:
- script: echo "Deploying with secure DB host: $(DatabaseHost)"
  displayName: 'Verify Secrets Integration'

Handling Failures and Rollbacks

A pipeline is only as good as its failure handling. If your deployment fails, your CD stage should fail fast. For zero-downtime deployments on Kubernetes, use rolling updates or blue-green strategies. If you need dedicated architectural guidance or want to assess your team's current delivery bottlenecks, feel free to contact us or learn more about us.

Conclusion

A clean Azure CI CD pipeline setup separates build logic from deployment targets, uses immutable container tags, and leverages service connections securely. By codifying your build and release processes into YAML, you ensure that every environment—from staging to production—follows the exact same automated path.

FAQ

Should I use YAML pipelines or classic pipelines in Azure DevOps?

You should always use YAML pipelines. YAML pipelines provide pipeline-as-code capabilities, allowing your build and release definitions to be version-controlled, reviewed via pull requests, and easily replicated across projects.

How do I securely pass secrets into an Azure DevOps pipeline?

The best practice is to use Azure DevOps Variable Groups backed by Azure Key Vault. This keeps sensitive credentials out of your source control repository and centralizes secret rotation.

How can I trigger an Azure pipeline on pull requests?

You can configure PR triggers in your YAML file under the trigger block or via branch policies in Azure DevOps to automatically run build and test validation before code is merged.

Related reading

[
  {
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "headline": "Azure CI CD Pipeline Setup: A Production YAML Guide",
    "author": {
      "@type": "Person",
      "name": "Muhammad Ramzan"
    },
    "publisher": {
      "@type": "Organization",
      "name": "Techsolss"
    },
    "datePublished": "2026-08-09",
    "mainEntityOfPage": "https://techsolss.online/posts/azure-ci-cd-pipeline-setup-a-production-yaml-guide.html"
  },
  {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {
        "@type": "Question",
        "name": "Should I use YAML pipelines or classic pipelines in Azure DevOps?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "You should always use YAML pipelines. YAML pipelines provide pipeline-as-code capabilities, allowing your build and release definitions to be version-controlled, reviewed via pull requests, and easily replicated across projects."
        }
      },
      {
        "@type": "Question",
        "name": "How do I securely pass secrets into an Azure DevOps pipeline?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "The best practice is to use Azure DevOps Variable Groups backed by Azure Key Vault. This keeps sensitive credentials out of your source control repository and centralizes secret rotation."
        }
      },
      {
        "@type": "Question",
        "name": "How can I trigger an Azure pipeline on pull requests?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "You can configure PR triggers in your YAML file under the trigger block or via branch policies in Azure DevOps to automatically run build and test validation before code is merged."
        }
      }
    ]
  }
]

Need senior DevOps, MLOps, or Cloud Architecture expertise?

We help startups and fast-shipping teams build rock-solid cloud infrastructure, automate deployments, and deploy production AI pipelines without full-time agency overhead. Let's discuss your architecture on a free 20-minute strategy call.

Book a free 20-min call