loading...

Azure DevOps CI/CD: YAML pipeline stages

rajikaimal profile image Rajika Imal ・3 min read

Azure DevOps provides two ways to create CI pipelines and CD (release) pipelines. Classic editor and YAML. Classic editor provides a UI to create pipelines and this requires two steps.

  • Build pipeline
  • Release pipeline

Classic editor was the default way of creating pipelines and releases before YAML was introduced. However with classic editor creating separate release pipeline for each project is a tedious task compared to the single pipeline in YAML.

Alt Text

With YAML both CI and CD tasks can be version controlled unlike with the classic editor.

Using YAML is the new approach of creating pipelines where we can include both CI/CD steps in one YAML file.

By default YAML pipelines are created when creating a build pipeline. We can include CD steps by adding stages.

A simple pipeline with build, test and publish to staging looks like this, (focus only on number of stages, specifics in tasks doesn't matter in this context)

trigger:
- master

variables:
  debug: true
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  iISDeploymentType: 'IISWebsite'

stages:
- stage: Build
  jobs:
    - job: Build
      pool:
        vmImage: 'windows-latest'

      steps:
      - task: NuGetToolInstaller@1

      - task: NuGetCommand@2
        inputs:
          restoreSolution: '$(solution)'

      - task: VSBuild@1
        inputs:
          solution: '$(solution)'
          msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
          platform: '$(buildPlatform)'
          configuration: '$(buildConfiguration)'

      - task: VSTest@2
        inputs:
          platform: '$(buildPlatform)'
          configuration: '$(buildConfiguration)'

      - task: PublishPipelineArtifact@1
        inputs:
          targetPath: '$(build.artifactStagingDirectory)\Test.Web.zip'
          artifact: 'drop'

- stage: DeployStaging
  displayName: 'Deploy to staging'
  dependsOn: 'Build'
  condition: succeeded()
  jobs:
  - deployment: DeployWeb
    displayName: Deploy Test API
    pool:
      vmImage: 'windows-latest'
    environment:
      name: test-stg
      resourceType: VirtualMachine
      tags: web
    strategy:
      runOnce:
        deploy:
          steps:
          - task: DownloadPipelineArtifact@2
            inputs:
              path: '$(System.ArtifactsDirectory)'
              artifactName: 'drop'

          - task: IISWebAppManagementOnMachineGroup@0
            displayName: 'IIS Web App Manage'
            inputs:
              IISDeploymentType: 'IISWebsite'
              ActionIISWebsite: 'CreateOrUpdateWebsite'
              WebsiteName: 'TestCloudTestDemo'
              websitePhysicalPath: '%SystemDrive%\inetpub\wwwroot'
              websitePhysicalPathAuth: 'WebsiteUserPassThrough'
              AddBinding: true
              protocol: 'http'
              iPAddress: 'All Unassigned'
              port: '85'
              Bindings:
              CreateOrUpdateAppPoolForWebsite: true
              AppPoolNameForWebsite: 'TestCloudTestDemo'
              ParentWebsiteNameForVD: '$(Parameters.WebsiteName)'
              virtualPathForVD:
              physicalPathForVD: '%SystemDrive%\inetpub\wwwroot'
              ParentWebsiteNameForApplication: '$(Parameters.WebsiteName)'
              VirtualPathForApplication: '$(Parameters.VirtualPathForApplication)'
              AppPoolName: '$(Parameters.AppPoolName)'
              appPoolNameForApplication:
              dotNetVersionForApplication: 'v4.0'
              pipeLineModeForApplication: 'Integrated'
              appPoolIdentityForApplication: 'ApplicationPoolIdentity'

          - task: IISWebAppDeploymentOnMachineGroup@0
            displayName: 'IIS Web App Deploy'
            inputs:
              WebSiteName: 'TestCloudTestDemo'
              package: '$(System.ArtifactsDirectory)\**\*.zip'
              XmlVariableSubstitution: True
Enter fullscreen mode Exit fullscreen mode

This pipeline has two stages. Build stage builds, tests and publishes the artifact to next stage. This is quite important. Otherwise the next stage cannot access the build artifact, since it's going to deploy (CD stage) the artifact to the staging environment.

The DeployStaging stage downloads the build artifact from earlier stage and runs two tasks to deploy the artifact to IIS. Notice how condition is used in the last stage. Conditions can be used to control the execution of each stage in pipeline. For instance if we have 3 stages (test, staging and prod) and we need to only up to staging, conditions can be used to control the execution.

condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
Enter fullscreen mode Exit fullscreen mode

This condition refers to the branch on which the commit was made. Only if it was the master branch, this stage will get executed.

References:
https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/pipelines-get-started?view=azure-devops

https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema

Discussion

pic
Editor guide