[VSTS] Using Process Parameters in Release Definitions

Building some release pipelines for my current project, I was faced with an inconvenience. When using a lot of Azure related tasks, in my case “Azure Resource Group Deployment” tasks, each of those tasks require a connection to your Azure subscription to function. Now you could just configure the connection for each task and be done with it. But I really HATE dislike repetitive work and also didn’t fancy the maintenance effort when I would need to change anything in the future. So I went looking for a better way to do this.

What I wanted to achieve: define the Azure subscription connection once per environment so that I can still have difference subscriptions for Test, Acceptance and Production; but not having to specify it for each task individually.

On first sight, it seems like there’s no way to get this done. You cannot simply use a variable for the connection or anything like that. But then I used one of the release templates that VSTS provides for deploying a Web App and switching the deployment slot. And what the H; there suddenly were “Process Parameters” defined on the environment level which are re-used in the tasks.

 

Defining Process Parameters

So how does one create a new parameter? Well, one doesn’t simply do that it seems. The UI doesn’t support creating these babies (yet…) so I needed to find another way to do this. I exported the release definition from VSTS, which comes in JSON form. You can open that file using VS Code and as a tip I would install one of the JSON extensions in order to prettify / minify the file (I used “JSON Tools”). Within the definition file, search for the “processParameters” section. Here you’ll find the variables defined like this:

"inputs": [
    {
        "aliases": [],
        "options": {},
        "properties": {},
        "name": "ConnectedServiceName",
        "label": "Azure subscription",
        "defaultValue": "",
        "required": true,
        "type": "connectedService:AzureRM",
        "helpMarkDown": "Select the Azure Resource Manager subscription for the deployment.",
        "visibleRule": "",
        "groupName": ""
    }
]

Nothing too complicated, they have a name, a type and some other descriptive metadata. Most of the properties aren’t even filled in. The variables are linked to the tasks within the release process. That done like this:

"workflowTasks": [
    {
        "taskId": "497d490f-eea7-4f2b-ab94-48d9c1acdcb1",
        ...
        "overrideInputs": {},
        "condition": "succeeded()",
        "inputs": {
            "ConnectedServiceName": "$(Parameters.ConnectedServiceName)",
            "WebAppKind": "$(Parameters.WebAppKind)",
            "WebAppName": "$(Parameters.WebAppName)"
        },
        ...
   }
   ...
]

So using the $(Parameters.ParameterName) syntax you can reference any of these parameters in the inputs of your tasks.

There is another section of importance, which is named dataSourceBindings. These bindings appear to link the variables together, ensuring that all of the Azure related variables depend on the subscription being selected first. That looks like this:

"dataSourceBindings": [
    {
        "dataSourceName": "AzureRMWebAppNamesByType",
        "parameters": {
            "WebAppKind": "$(WebAppKind)"
        },
        "endpointId": "$(ConnectedServiceName)",
        "target": "WebAppName"
    },
    {
        "dataSourceName": "AzureRMWebAppResourceGroup",
        "parameters": {
            "WebAppName": "$(WebAppName)"
        },
        "endpointId": "$(ConnectedServiceName)",
        "target": "ResourceGroupName"
    },
    ....
]

Note how the endpointId part in both cases points to the connected service name variable (which is the subscription).

 

Using parameters in your own release definition

So how do you now reuse the same approach within your own definition? Copy/paste FTW! In my case the variables I needed were exactly the ones used in the release template I downloaded, so did the following:

  • Copy the processParameters section to your definition, you’ll need to make sure you paste it in the correct Environment section since they’re linked per environment (repeat when you need them in multiple environments). There should be an empty one already present, so overwrite it.
  • Copy the dataSourceBindings section to your definition file, simply goes below the processParameters section. This section isn’t there by default it seems (but check to be sure).
  • Within the workflow sections (which define the Tasks), replace the correct inputs with the process variables as needed.
  • For safety reasons, rename your definition. The name is stored in the “name” variable all the way at the top.

Now go to the Release Definitions section in VSTS and import your modified file. I found that it won’t overwrite the existing definition but create a copy instead, so you do not run the risk of overwriting a good definition with a broken one. That said, this does mean that with a new definition you lose the history of your existing definition which is kinda crappy. Since release definitions have version control as well I don’t really see why they wouldn’t overwrite existing ones, but there’s probably a good reason for that somewhere.

If you’ve copy/pasted everything correctly, you should now see the process variables linked to the environment and linked to the tasks where you used them. That means you can now define your Azure subscription once and reuse it in all steps. Super nice!

,

Related posts

Long Term Support… or not?

Building some release pipelines for my current project, I was faced with an inconvenience. When using a lot of Azure related tasks, in my case "Azure Resource Group Deployment" tasks, each of those tasks require a connection to your Azure subscription to function. Now you could just configure the connection for each task and be done with it. But I really HATE dislike repetitive work and also didn't fancy the maintenance effort when I would need to change anything in the future. So I went looking for a better way to do this.

What I wanted to achieve: define the Azure subscription connection once per environment so that I can still have difference subscriptions for Test, Acceptance and Production; but not having to specify it for each task individually.

[DevOps] Should you migrate onto YAML release pipelines?

Building some release pipelines for my current project, I was faced with an inconvenience. When using a lot of Azure related tasks, in my case "Azure Resource Group Deployment" tasks, each of those tasks require a connection to your Azure subscription to function. Now you could just configure the connection for each task and be done with it. But I really HATE dislike repetitive work and also didn't fancy the maintenance effort when I would need to change anything in the future. So I went looking for a better way to do this.

What I wanted to achieve: define the Azure subscription connection once per environment so that I can still have difference subscriptions for Test, Acceptance and Production; but not having to specify it for each task individually.

Latest posts

Long Term Support… or not?

Building some release pipelines for my current project, I was faced with an inconvenience. When using a lot of Azure related tasks, in my case "Azure Resource Group Deployment" tasks, each of those tasks require a connection to your Azure subscription to function. Now you could just configure the connection for each task and be done with it. But I really HATE dislike repetitive work and also didn't fancy the maintenance effort when I would need to change anything in the future. So I went looking for a better way to do this.

What I wanted to achieve: define the Azure subscription connection once per environment so that I can still have difference subscriptions for Test, Acceptance and Production; but not having to specify it for each task individually.

[DevOps] Should you migrate onto YAML release pipelines?

Building some release pipelines for my current project, I was faced with an inconvenience. When using a lot of Azure related tasks, in my case "Azure Resource Group Deployment" tasks, each of those tasks require a connection to your Azure subscription to function. Now you could just configure the connection for each task and be done with it. But I really HATE dislike repetitive work and also didn't fancy the maintenance effort when I would need to change anything in the future. So I went looking for a better way to do this.

What I wanted to achieve: define the Azure subscription connection once per environment so that I can still have difference subscriptions for Test, Acceptance and Production; but not having to specify it for each task individually.

Leave a Comment

Leave a Reply

Your email address will not be published. Required fields are marked *