/azure pipelines

Exploring YAML based Azure Pipelines in Azure Devops

I’ve always curious of the huge variety of options on Azure DevOps & have always wanted to explore and understand the use cases for having so much features. If you are like me and you have been working with Azure DevOps over the past couple of years, you have also had some of the confusions on the below items which we will know more in this article.

The Release pipelines

In our team we have been extensively using Azure DevOps for a quite long time now, using so we have a lot of individual release pipelines that deploy the code to the cloud services like Azure Functions or Azure Web apps.

Being in a .NET world usually any project will always have multiple API services, multiple Azure Functions that takes care of certain things in the project. Eg: If you consider a simple Hotel Management App, there might be multiple API services like

  • Admin
  • Hotels

The app might also have any background jobs for processing of information at a later point of time or any recurring things that needs to be taken care of. In a Hotel Management app, we might have a background job to keep the list of items that are available on any particular hotel & update our inventory based on that.

Now the traditional way of doing this is we have a build pipeline (CI) that builds each things individually and deploys them (CD) to the cloud. Now speaking in terms of Azure words the terms

CI is being referred to Pipeline and CD means Releases. But this is the CLASSIC way or words. Now its just CI/CD together in a single YAML pipeline, but MSFT does not clarify this properly.

If we do a quick Google search of Release pipelines Azure Devops , we end up here Release Pipelines

Azure Release pipeline
Azure Release pipeline

On April 2020, MSFT released this announcement for doing CI/CD using YAML instead of doing it the classic way. Now you might wonder what’s the point of changing my existing pipelines from (Classic) to YAML, & what benefits do I get. Let’s go through the Pro’s / Con’s of it.

YAML

  • It is code, and managed as a source file, so it will go through a standard code review / pull request process
  • Because it is in the repo, when you need to revert the source to an early commit, the pipeline will be reverted together as well
  • Comparing changes is much easier compared to the Classic UI versioning, which means it’s easier to identify root cause if build breaks
  • Azure DevOps does have assistant to help building a YAML file, so it’s not as hard for first time users
  • YAML Templates for resusability.

One of the biggest advantages of going over YAML is we can re-use it to build/deploy multiple things without repeating the same code over & over again. As we discussed earlier a repo might have X number of csproj to build, but the only change in the build logic is their projectName & the projectPath. But if we do build the old fashioned classic pipeline, we will have to repeat the same steps like these in all the pipelines.

  • Use .NETCORE CLI
  • Restore Nuget
  • Build
  • Publish

But here in YAML, we can just build a template like this

parameters:
  projectName: ''
  vmImage: ''
  buildConfiguration: ''
  runtime: ''

stages:
-  stage: 'Build'
   displayName: 'Build'
   pool:
     name: 'Azure Pipelines'
     vmImage: ${{ parameters.vmImage }}
   jobs:
   - job: 'Build'
     steps:
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: |
              ${{ parameters.projectName }}/${{ parameters.projectName }}.csproj
        - task: DotNetCoreCLI@1
          displayName: 'Dotnet Build'
          inputs:
            command: build
            projects: |
              ${{ parameters.projectName }}/${{ parameters.projectName }}.csproj  
        - task: DotNetCoreCLI@2
          displayName: 'Dotnet Publish'
          inputs:
            command: publish
            projects: |
              ${{ parameters.projectName }}/${{ parameters.projectName }}.csproj
            publishWebProjects: true
            arguments: '-c $(buildConfiguration) --runtime $(runtime) --self-contained -o $(Build.ArtifactStagingDirectory)'
        - task: PublishBuildArtifacts@1
          inputs:
            PathtoPublish: '$(Build.ArtifactStagingDirectory)'
            ArtifactName: 'drop'

And when it comes to the actual pipeline, we can just build a variables.yml file for different projects & re-use the build template which we created earlier.

variables:
-  name: projectName
   value: Tailspin.SpaceGame.Web
-  name: vmImage
   value: ubuntu-latest
-  name: buildConfiguration
   value: Release
-  name: runtime
   value: linux-x64
-  name: azureSubscription
   value: AzureAppService
-  name: appType
   value: webAppLinux
-  name: WebAppName
   value: SpaceGame
-  name: RuntimeStack
   value: DOTNETCORE|LTS
-  name: ConnectionType
   value: AzureRM

The actual build pipeline only has the below code now

trigger: 
-  main
-  releases/*

variables:
-  template: webapp-variables.yml

stages:
# Build Stage
-  template: template-build.yml
   parameters: 
     projectName: $(projectName)
     vmImage: $(vmImage)
     buildConfiguration: $(buildConfiguration)
     runtime: $(runtime)

References

In our next blog we will explore the Environments section in Azure Devops. I have always seen it being empty for 3 years, I’m curious to find out what it can do to help with the Devops lifecycle.

HariHaran

HariHaran

Full Stack Developer

Read More