Azure DevOps CI/CD pipelines let you automate the build, test, and deployment of your code, transforming raw commits into live applications with minimal human intervention.

Let’s see this in action. Imagine we’re building a simple Node.js web app.

Azure Pipelines YAML Configuration (.azure-pipelines.yml):

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: NodeTool@0
  inputs:
    versionSpec: '18.x'
  displayName: 'Install Node.js'

- script: |
    npm install
    npm run build
  displayName: 'Install dependencies and build'

- task: ArchiveFiles@2
  inputs:
    rootFolderOrFile: '$(System.DefaultWorkingDirectory)/dist'
    includeRootFolder: false
    archiveType: 'zip'
    archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
  displayName: 'Archive build output'

- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
    artifactName: 'drop'
  displayName: 'Publish artifact'

When code is pushed to the main branch, this pipeline automatically kicks off.

  1. trigger: - main: This specifies that the pipeline should run whenever changes are pushed to the main branch.
  2. pool: vmImage: 'ubuntu-latest': This defines the environment where the pipeline will execute. Here, it’s a fresh Ubuntu Linux agent.
  3. steps:: This section lists the individual tasks to be performed in sequence.
    • NodeTool@0: This task ensures a specific version of Node.js (18.x in this case) is installed on the agent.
    • script:: This runs shell commands. npm install downloads project dependencies, and npm run build executes the build script defined in your package.json (e.g., transpiling TypeScript, bundling JavaScript).
    • ArchiveFiles@2: This takes the output of the build (assumed to be in a dist folder) and compresses it into a .zip file. $(Build.ArtifactStagingDirectory) is a special predefined variable pointing to a temporary location for artifacts.
    • PublishBuildArtifacts@1: This makes the zipped artifact available for subsequent stages (like deployment) or for download. artifactName: 'drop' is a common convention for the primary build output.

The problem this solves is the manual, error-prone process of building, packaging, and staging your application for deployment. Pipelines codify this process, making it repeatable and auditable. Internally, Azure DevOps orchestrates these tasks on agents (Microsoft-hosted or self-hosted). You control the flow through the YAML, defining triggers, agent pools, and the sequence and configuration of tasks.

The most surprising thing to many is how granularly you can control the agent environment and task execution. For instance, you can specify exactly which version of a tool like Node.js, Python, or .NET to use, ensuring consistent builds across different runs. You can also inject environment variables, secrets from Azure Key Vault, and even run custom scripts that interact with cloud services or databases before or after your main build steps. This level of control is what makes pipelines powerful for complex application lifecycles.

The next concept you’ll likely encounter is setting up release pipelines for automated deployments to various environments.

Want structured learning?

Take the full Azure course →