Azure DevOps (ADO) Release

Orchestrated Component Deploy

The Application Stack in this example deploys two components, static content and an API.

graph TD

  Agent["🌐"] 

  subgraph vm1["☁️ CloudFlare"]
    content["Static Content"]
    API
  end

  Agent --> content
  Agent --> API

classDef external fill:lightblue
class Agent external

classDef dashed stroke-dasharray: 5, 5
class vm1,vm2,vm3,vm4 dashed
 
classDef dotted stroke-dasharray: 2, 2
class vm1-pod-1,vm1-pod-2,vm2-pod-1,vm2-pod-2,vm3-pod-1,vm3-pod-2,vm4-pod-1,vm4-pod-2 dotted

Each component publishes a self-contained release package to the Azure DevOps (ADO) artefact store. The ADO Release orchestrates these package deployments for each environment, ensuring the complete stack is promoted through each environment with aligned package versions.


graph LR

  subgraph static["Static Content"]
    Sbuild["Build"] -->
    Stest["Test"] -->
    Spublish["Publish"]
  end
  subgraph API
    Abuild["Build"] -->
    Atest["Test"] -->
    Apublish["Publish"]
  end

  subgraph Release
    TEST
    PROD
  end

  store[(ADO Store)]

  Apublish --> store
  Spublish --> store
  store --> TEST
  TEST --> PROD

classDef release fill:lightgreen
class TEST,PROD release

Subsections of Azure DevOps (ADO) Release

Component CI

Autonomous Component Build & Test

Each component contains both application code and deployment automation. The development team can imperatively deploy to the dev environment, i.e. the API and Vue application can be deployed separately, with no assurance of version alignment.

Example Vue properties.cm file, the deployment tool used is Wrangler.

context    target  pages_app_project  fqdn                 api_url
container  DEV     petstore-dev       vue-dev.example.com  api-dev.example.com

container  TEST    petstore-tst       vue-tst.example.com  api-tst.example.com
container  PROD    petstore-prd       vue.example.com      api.example.com

Example API properties.cm file, the deployment tool used is Terraform.

context    target tf_work_space  pages_suffix
container  DEV    PetStack-Dev   dev
container  TEST   PetStack-Test  tst
container  PROD   PetStack-Prod  prd

Due to the loose-coupling principle of CDAF, the same pipeline template is used for both components, even though the code and deployment automation are different (see orchestration templates in GitHub for Windows and Linux).

note that Jest for Vue and Checkov for Terraform have both been configured to output results in JUnit XML format.

jobs:
  - job: Build
    displayName: Build and Package
    pool:
      vmImage: windows-latest
    steps:
      - task: PowerShell@2
        displayName: CDAF Release Build
        inputs:
          targetType: 'inline'
          script: |
            . { iwr -useb https://cdaf.io/static/app/downloads/cdaf.ps1 } | iex
            .\automation\entry.ps1 $(Build.BuildNumber) $(Build.SourceBranch) staging@$(Build.ArtifactStagingDirectory)
      - task: PublishTestResults@2
        condition: succeededOrFailed()
        inputs:
          testResultsFormat: 'JUnit'
          testResultsFiles: '**/test-results/*.xml' 
      - task: PublishBuildArtifacts@1

The resulting ADO component pipelines are independent

alt text alt text

Next, autonomous deploy…

Component CD

Autonomous Component Deploy

By using the feature-branch.properties capability of CDAF, branches containing the string dev will deploy to the development environment. This feature allows imperative deployment by the development team, without manipulating the pipeline, and therefore avoiding drift.

vue

# Feature Branch name match mapping to environment
dev=DEV

API

# Feature Branch name "contains" mapping to environment
dev=DEV release 'apply --auto-approve'

In the feature branch, where dev is in the branch name, CDAF will detect and execute a deployment, using the mapping above to invoke a release to DEV.

alt text alt text

The trunk based pipeline will only push a release artefact from the main branch, with a stand-up/tear-down integration test of the production build.

alt text alt text

Next, publication…

Component Publish

Autonomous Component Publication

the final stage of the main pipeline is publication. This pushes the release package to the artefact registry.

alt text alt text

Each component publishes their release package, so although they use different technologies, they are now available as consistent packages, using the CDAF package process, which outputs a self-extract release.ps1 (of release.sh for linux) file.

alt text alt text

Next, Release…

Release

Full Stack Release

The ADO Release function is used to create a release, and promote it through the environments. The release obtains the components from the artefact store

alt text alt text

The Release is defined in order of dependency, i.e. the CloudFlare infrastructure is created/updated and configured with the API, then the front-end is deployed to the infrastructure.

The release itself includes to deployment logic, it simply invokes the packages provided by the component development team.

alt text alt text

When a new release is created, the latest versions are defaulted, and this defines the manifest for the release, i.e. different versions cannot be deployed to different environments. This ensures the stack is consistency promoted.

The latest versions do not have to selected, but whatever is selected is static for that release instance.

alt text alt text

When the release is promoted, no manual intervention is required, except for approval gates, which can be approved by business or product owners, and does not require any further development effort.

alt text alt text