This is part 8 of a multipart series on getting started with Azure DevOps. Please refer to the below links to access other notes in this series.
Part 1: Getting started with Azure DevOps
Part 2: Getting started with Azure DevOps -work items
Part 3: Getting started with Azure DevOps -add a repo
Part 4: Getting started with Azure DevOps -create a build agent
Part 5: Getting started with Azure DevOps -create a build pipeline -Part 1 (YAML pipeline)
Part 6: Getting started with Azure DevOps -create a build pipeline -Part 2 (Classic Editor)
Part 7: Getting started with Azure DevOps -create a deployment group
Part 8: Getting started with Azure DevOps -create a release definition (this note)
In the previous note (part 7) I provided some information regarding a deployment group. In this note, among other things, I show how to add a deployment group to a release definition. But before I do that, I am going to make some notes about what a release definition is.
In Azure DevOps, a release definition is typically configured to deploy artifacts that are created from a build pipeline definition. I say typically because other tasks can be performed/automated using a release definition without having to do anything with builds or build artifacts.
Depending upon the purpose, there are four main components to a release definition –
-build pipeline artifact/s,
-deployment group/s and
A release definition follows a series of steps mentioned in release tasks using the variables to deploy the build pipeline artifacts to the machines in the deployment group.
We will follow the below steps to create a release definition. There are two prerequisites to this -deployment groups and build pipeline artifacts. We need to have both ready before the creation of a release definition.
Step 1: New pipeline
Navigate to the Pipelines tab under your Azure DevOps project and launch Releases. If this is the first time a release definition is being created in this project, we’ll see a -No release pipeline found image.
Click on New pipeline.
Step 2: Release definition settings
The next window has all the settings that are required to create a release definition.
This view is under the pipeline tab on a release definition. We set two parameters here: artifacts and stages. Artifacts belong to build pipeline definition artifacts and Stages are the set of release tasks and deployment group. This view is grey-ed because we are requested to select a template (a group of release tasks) to apply to a deployment group.
My preference here is to select Empty Job which allows me to select only those steps that are required to successfully deploy the build-pipeline artifacts. After selecting, I can also update the name from Stage 1 to something meaningful like Development which stands for the environment name on which the release tasks are applied and the deployment group tied to that environment.
Step 3: Add an artifact
This artifact is what we’re deploying to the machine/s in the deployment group. More often than not, artifacts are usually build pipeline artifacts. However, as you can see, you can also select contents from your Azure Repos or Github, etc to be deployed. Once selected, click on Add.
Step 4: Click on Tasks tab
Here we see the stage and an agent job.
An agent is a machine with development tools installed. This is a machine (or group of machines) where we compile our code and generate build artifacts. For release definitions, we would not need them and instead require a deployment group.
Click on the ellipsis next to the Stage name (here it is Development) which launches three options, as can be seen. We select a deployment group job.
Step 5: On the deployment group job page you have a few options available to orchestrate deployment. A few details that are required are:
-display name of the deploy group job
-name of deployment group (select from a pre-filled list)
-targets to deploy in parallel
-maximum number of targets to deploy in parallel
Note: Having a deployment group already created is necessary before we create a release definition. The drop-down lists the deployment groups available under our project.
Before I start listing down the rest of the options, let us consider an example. Assume we have 2 environments and say we created 2 deployment groups corresponding to the environments (click here to read about how to create deployment groups). And inside each environment, say we have 4 servers -2 for app and 2 for database; 2 X 4 servers in total.
Let us say, we attempt to create a release definition to deploy application code to the app servers. We would create a release definition and link a build pipeline definition and a deployment group. In this case, the app build pipeline artifacts will be deployed to the machines in the deployment group. But we have 2 machines in the deployment group that have nothing to do with app code, these are the two DB machines.
If I add a deployment group to deploy app code, it will deploy to all the 4 machines, although 2 out of the 4 are database servers. That is unnecessary and can cause release failure. There are two ways to address this -deployment groups and tags.
What are tags? Tags are a unique way to identify various machines in a deployment group. In our example here, we can create two tags in the Development deployment group: app and database and assign them accordingly.
Navigate to deployment group -> select deployment group name -> select Targets. This lists the machines in that deployment group. Towards the right side, we have a column for Tags. We can assign tags to uniquely identify machines in a deployment group.
Going back to the release definition -> deployment group job, we now can update the tags and this will ensure that the app code will be deployed only to the machines that have that particular tag.
Targets to deploy to in parallel: There are times when we do not all the machines in a deployment group to be updated at the same time. Consider a website that is running on two or more machines. If we deploy to all the machines at the same time, the site will be unavailable. Deploying one target at a time addresses that issue.
Maximum number of targets in parallel: Going back to the same example, consider that the website is running on 10 machines. We cannot deploy in parallel (websites become unavailable) but we do not want to deploy one target at a time too. In that case, we can select Multiple in the previous setting and select what % of machines we are comfortable being updated together. If we select 50% then 5 machines get updated and then the next 5 get updated. This step by step approach ensures that the environment is always available and the website does not go down.
Timeout: As the title suggests, this is the maximum time for which a deployment process is allowed to execute on a machine.
Step 6: Add release tasks to a deployment group
Next to the Deployment group job name is a +. Click on that to launch tasks that would be applied to the machines belonging to a deployment group.
This launches lots of options that can be applied. These tasks are also classified under build, utility, test, etc. If there is a task that you’re not able to find, go to Marketplace and check if its there. If you find it, click on Get it free. This will install the extension and the associated tasks will be available under All tab or whichever they belong to -build, utility, test, etc.
I use a Powershell script job to run on a deployment group machine to do a specific job. This Powershell script is part of build pipeline artifact. The sequence of steps is something like:
-unzip contents of build pipeline artifact
-stop particular service -windows IIS app pool or service
-copy files from build artifact location to location where windows service points to
-start a particular service
-review if service has started
-exit out with success
Step 7: Add variables
Variables come in handy when we have multiple stages (environments) where a product is deployed using the same release definition. Variables also come in handy when we need to pass a secret value (next to value field there is a lock -change variable type to secret) that we do not want to be accessible to others reviewing the release definition or via logs. We set the name, value, and scope of the variable (default is Release).
Step 8: Set retention and options
The default value is usually more than enough for retention. Under options, we set the release format. Here too, default is fine.
Once all the options are set, click on save and trigger a release.
PS: Usually with a new user or a new project the first few release definition runs fail. The logs become handy in understanding how Azure DevOps understands the artifacts, the release steps, and the deployment group.