I wanted to test adding approvals to an Azure DevOps YAML pipeline, outside of Environment approvals.
I created a project that contains the following files:
deploy.bicep
– Bicep template that will create a storage account in Azure.validate.ps1
– PowerShell script that mocks a validation stage, could be awhat-if
or some other validation.deploy.ps1
– PowerShell script to deploy the Bicep template to Azure.deploy.yml
– YAML pipeline file.
The repository is located at mattruma/MJR129 (github.com).
I have two branches: main
and develop
.
I have three environments: develop
, staging
and production
.
The PowerShell scripts expect a -Prefix
parameter, which will be different for each environment.
I created three variable groups, one for each environment.
I then added a Prefix
variable to each variable group.
For develop
the Prefix
used dev
as the suffix, e.g. mjr129dev
, for staging
used stg
and for production
used prd
.
I next created three environments in Azure DevOps.
I added a gated approval to the Staging
environment.
The Production
environment did not need a gated approval as it would be triggered off of a commit to the main
branch.
I wanted my workflow to work as such:
- Code changes are committed to the
develop
branch which would then trigger the pipeline at theDevelop
stage. - The pipeline runs the
validate.ps1
script. - After the validation runs an email is sent requesting approval.
- The user approves the request which then runs the
deploy.ps1
script, which in turn deploys the resources to thedevelop
environment in Azure. - Using the gated approval, a notification is sent for approval to
Staging
. - User approves the request which then runs the
validate.ps1
script. - After the validation runs an email is sent requesting approval.
- The user approves the request which then runs the
deploy.ps1
script, which in turn deploys the resources tostaging
environment Azure. - If everything looks good, a pull request is created for the changes in
develop
. - When the pull request is accepted the pipeline is triggered at the
Production
stage. - The pipeline runs the
validate.ps1
script. - After the validation runs an email is sent requesting approval.
- The user approves the request which then runs the
deploy.ps1
script, which in turn deploys the resources to theproduction
environment in Azure.
The Develop
and Staging
stages would be triggered by the develop
branch, while the Production
stage would be triggered by the main
branch.
I was able to accomplish this a combination of AzureCLI@2 and ManualValidation@0 tasks.
The complete Azure YAML Pipeline can be seen at MJR129/deploy.yml at develop · mattruma/MJR129 (github.com).
Some things to call out.
I used conditions
on my stage
to determine what branch would trigger what stage.
1 2 3 4 |
stages: - stage: Develop condition: eq(variables['build.sourceBranch'], 'refs/heads/develop') |
Variable groups were assigned to the appropriate stage.
1 2 |
variables: - group: Production |
Timeouts were required for the job
and the ManualIntervention
task.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- job: StagingWaitingApproval dependsOn: StagingValidate pool: server timeoutInMinutes: 4320 # job times out in 3 days steps: - task: ManualValidation@0 displayName: StagingWaitingApproval timeoutInMinutes: 1440 # task times out in 1 day inputs: notifyUsers: | $(Email) instructions: 'Please validate the build configuration and resume' onTimeout: 'resume' |
Develop
and Staging
deployments happen within the same pipeline run.
The Production
deployment, since it is triggered off the main
branch, happens in a different pipeline run.
Seems to get the job done!
If there is a better way or different way, please share!
Discover more from Matt Ruma
Subscribe to get the latest posts sent to your email.