I'm working on a YAML pipeline to build a deploy a project and could not figure out how to selectively deploy to 1 or more Dev/Test/Prods servers.
Resources: There are 3 Test resources and multiple Prod resources.
Requirement: A given build can be independently deployed any or all of the Test resources. Similarly, it can be independently deployed to any or all of the Prod resources.
Can this be done? If so, please point me to the right direction. All the examples and documentations I have found so far only showed the deployment sequence to 1 Dev resource, 1 Test resource, and 1 Prod resource.
Thank you in advance for your help.
Snippet of my pipeline. Deploying to Test1, Test2 and Test3 stages are in sequence, and that's not what I need.
stages:
- stage: Build
jobs:
- job: BuildProject
# steps to build and publish
- stage: Test1
# deploy to Test1 resource
- stage: Test2
# deploy to Test2 resource
- stage: Test3
# deploy to Test3 resource
It sounds like you are asking how to deploy to your different environments in parallel.
If not specified, a stage will depend on the previously defined stage in the yaml. If you want stages to run in parallel, you can add dependsOn: []
onto each of your stages to set it so the stages do not depend on each other, and will run in parallel.
Since you have your build and deployment in the same pipeline, then your deploy stages will need to depend on your Build stage.
Example snippet:
stages:
- stage: Build
jobs:
- job: BuildProject
# steps to build and publish
- stage: Test1
dependsOn: Build
# deploy to Test1 resource
- stage: Test2
dependsOn: Build
# deploy to Test2 resource
- stage: Test3
dependsOn: Build
# deploy to Test3 resource
Keep in mind that you will need an available agent for each stage/job in your pipeline.
Recommended reading:
When I do build #1, I just wanted to deploy to Test2. So, I would need to skip Test1 and Test3 stages. There is no way for me to deploy build #1 to Test1 or Test3 later on. How would I go about doing that?
There are quite a few ways to go about designing a solution based on your requirements, each with there own quirks. I am not going to elaborate too much any one of these, do some experimentation and come back to ask a new question that details a specific problem.
I'll suggest three options that may meet your use case.
The Environments feature in Azure DevOps lets you define target environments, and then add approval gates that will stop a stage from progressing until it has been approved. If used for your deployment stages, your build stage will start and finish automatically, then each of your deploy environment stages will be on a waiting for approval state. Unfortunately, if any of the stages are 'denied', that pipeline stage will be marked as failed which looks ugly in my opinion.
Docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/environments?view=azure-devops
Your yaml will need to be tweaked slightly for environments like so:
stages:
- stage: Build
jobs:
- job: BuildProject
steps:
- checkout: self
- stage: Test1
dependsOn: Build
jobs:
- deployment: DeployEnvironmentA
environment: EnvironmentA
strategy:
runOnce:
deploy:
steps:
- checkout: self
- stage: Test2
dependsOn: Build
jobs:
- deployment: DeployEnvironmentB
environment: EnvironmentB
strategy:
runOnce:
deploy:
steps:
- checkout: self
- stage: Test3
dependsOn: Build
jobs:
- deployment: DeployEnvironmentC
environment: EnvironmentC
strategy:
runOnce:
deploy:
steps:
- checkout: self
If you cannot determine at trigger time of a pipeline which environments will be deployed, you can split your pipeline into multiple pieces.
Create a seperate pipeline that builds your application and publishes artifacts that will be used to publish.
Edit your existing pipeline so that it only deploys one environment, and you parse in a parameter to determine which environment will be deployed. You can link to the build pipeline using the resources
yaml keyword to easily download the artifacts from your build pipeline. Then each of your pipeline runs will target a single environment, and you trigger the pipeline whenever that environment needs to be deployed too.
When manually triggering a multi-stage pipeline, you can select the advanced option Stages to run
to toggle which stages will run. Using this, you can disable which environments you want to deploy too.
It is possible to create similar behaviour with parameters/variables using yaml expressions.
Docs: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops