AZ-400: Designing and Implementing Microsoft DevOps Solutions

Implementing an Orchestration Automation Solution

Stages Dependencies and Conditions

In this lesson, we explore how stages, dependencies, and conditions empower you to build and manage robust CI/CD workflows. Understanding these key elements helps you design flexible pipelines that smoothly transition your code from development to production.

Organizing Your Pipeline with Stages

Stages serve as major checkpoints in your YAML pipeline by organizing related jobs into distinct phases—for instance, build, test, and deploy. This logical segmentation provides a clear, structured method for directing your CI/CD workflow.

Controlling Execution Order with Dependencies

By default, stages run in parallel. However, you can use the dependsOn keyword to control the execution order by specifying that a stage should only run after one or more preceding stages have completed. The example below demonstrates how the deploy stage waits for both the build and test stages to finish:

stages:
  - name: Build
    jobs:
      - job: build_app

  - name: Test
    jobs:
      - job: run_tests

  - name: Deploy
    dependsOn:
      - Build
      - Test
    jobs:
      - job: deploy_app

Each stage is composed of jobs that carry out specific tasks, such as building the application, running tests, or deploying your project.

Adding Intelligence with Conditions

Conditions enhance your pipeline by allowing stages, jobs, or individual tasks to execute only when certain criteria are met. For instance, you might configure your pipeline so that deployment occurs only if the current branch is main and all previous stages have succeeded. The snippet below illustrates using the condition keyword:

stages:
  - stage: Build
    jobs:
      - job: BuildJob
        steps:
          - script: echo "Building the project"
            displayName: 'Build'
          - script: echo "Running unit tests"
            displayName: 'Run Tests'
          # Proceed to the deployment stage only if the source branch is main
          - script: echo "Proceeding to deployment stage"
            condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')

Complete Example: Multi-Stage Pipeline with Dependencies and Conditions

The following YAML snippet provides a complete example of a multi-stage pipeline. Here, the build stage handles project compilation and testing. The deploy stage is configured to execute only when the source branch is main:

stages:
  - stage: Build
    jobs:
      - job: BuildJob
        steps:
          - script: echo "Building the project"
            displayName: 'Build'
          - script: echo "Running unit tests"
            displayName: 'Run Tests'
          # This step advances to deployment only if on the main branch
          - script: echo "Proceeding to deployment stage"
            condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')

  - stage: Deploy
    jobs:
      - job: DeployJob
        steps:
          - script: echo "Deploying the application"
            displayName: 'Deploy'
          # Additional deployment steps can be added here

In this example, the deploy stage will execute only if the Build.SourceBranch variable equals refs/heads/main. Otherwise, it will be skipped.

Understanding Dependencies vs. Conditions

Understanding the differences between dependencies and conditions is crucial for effective pipeline design:

ElementPurposeUsage Example
DependenciesControl execution order between stages/jobsStage B runs only after Stage A completes using dependsOn
ConditionsEnable conditional execution based on criteriaExecute deployment only if on the main branch

Key Takeaway

Dependencies enforce a strict order of execution, while conditions allow for dynamic, criteria-based decisions within your pipeline.

The image is a comparison chart highlighting the differences between "DependsOn" and "Condition" in terms of execution management, selective execution, support, and application scope.

CI/CD Pipeline Best Practices

Adopting the following best practices can help you create efficient and maintainable pipelines:

  • Organize your stages to mirror the logical sequence of your CI/CD process.
  • Use conditions strategically to conserve resources by skipping unnecessary stages.
  • Define dependencies carefully to streamline sequential execution without adding maintenance overhead.
  • Avoid overly complex pipeline configurations that may lead to challenges in maintenance and debugging.

The image outlines three best practices: organizing stages logically, using conditions to skip unnecessary runs, and clearly defining dependencies. It features a central thumbs-up icon surrounded by these points.

Important

Remember: Overcomplicating your pipeline structure can lead to maintenance challenges and degraded performance. Keep your pipelines as straightforward as possible.

By following these guidelines and leveraging stages, dependencies, and conditions, you can design CI/CD pipelines that are both efficient and resilient, ensuring smooth code deployment from development to production.

For more insights into CI/CD best practices and pipeline configuration, check out our Kubernetes Documentation and related guides.

Watch Video

Watch video content

Previous
Release Strategies