Reputation: 97
We would like to deploy components of our application to developer's local machines and want it to be easy enough for our co-workers to use and easy enough for us to maintain. These are virtual machines with a certain naming convention, for instance: VM001, VM002, and so on.
I can define these machines, and use the value later on in the pipeline, in a parameter in YAML like this:
parameters:
- name: stage
displayName: Stage
type: string
values:
- VM001
- VM002
- And so on...
I then only have to maintain one stage, because the only thing that really differs is the stage name:
stages:
- stage: ${{ parameters.stage }}
displayName: Deploy on ${{ parameters.stage }}
- jobs:
...
The idea behind defining the machines in the parameters like this is that developers can choose their virtual machine from the 'Stage' dropdown when they want to deploy to their own virtual machine. By setting the value of the parameter to the virtual machine, the stage is named and the correct library groups will also be linked up to the deployment (each developer has their own library groups where we store variables such as accounts and secrets).
However, we have multiple components that we deploy through multiple pipelines. So each component gets its own YAML pipeline and for each pipeline we will have to enter and maintain the same list of virtual machines.
We already use variable and job templates for reusability. I want to find a way to create a template with the list of machines and pass it to the parameter value. This way, we only need to maintain one template so whenever someone new joins the team or someone leaves, we only need to update one file instead of updating all the pipelines.
I've tried to pass the template to the parameter value using an expression like this:
variables:
- name: VirtualMachinesList
value: VirtualMachinesList.yml
parameters:
- name: stage
displayName: Stage
type: string
values:
- ${{ variables.VirtualMachinesList }}
The VirtualMachinesList.yml looks like this:
variables:
- name: VM001
value: VM001
- name: VM002
value: VM002
- And so on...
This gives the following error when I try to run the pipeline: A template expression is not allowed in this context
I've also tried changing the parameter type to object. This results in a text field with a list of all the virtual machines and you can select the ones you don't want to deploy to and remove them. This isn't very user-friendly and also very error-prone, so not a very desirable solution.
Is there a way to pass the list of virtual machines to the parameter value from a single location, so that developers can choose their own virtual machine to deploy to?
Upvotes: 3
Views: 5613
Reputation: 30313
I know you want to maintain the list of virtual machines in one place, and also keep the function that developers can choose the vm from the dropdown to deploy to. But i am afraid it cannot be done currently. Runtime parameters doesnot support template yet. You can submit a user voice here regarding this issue.
Currently you can keep only one function, either maintain the vms in one place or developer can choose their vm from the dropdown.
1, To maintain the virtual machines in one place. You can define a variable template to hold the virtual machines. And make the developer to type their vm to deploy to. See below:
Define an empty runtime parameter to let the developer to type in.
parameters:
- name: vm
type: string
default:
Define the variable template to hold the VMS
#variable.yml template
variables:
vm1: vm1
vm2: vm2
...
Then in the pipeline define a variable to refer to the vm variable in the variables template. See below
variables:
- template: variables.yml
- name: vmname
value: $[variables.${{parameters.vm}}]
steps:
- powerhsell: echo $(vmname)
2, To make the developer have the convenience to choose their vm from the dropdown. You have to define these machines parameters in all pipeline.
Upvotes: 3
Reputation: 1336
You're really close. You'll want to update how you're consuming your variable template to:
variables:
- template: variable-template.yml
Here's a working example (assuming both the variable template and consuming pipeline are within the same directory of a repository):
variable-template.yml:
variables:
- name: VM001
value: VM001
- name: VM002
value: VM002
example-pipeline.yml:
name: Stackoverflow-Example-Variables
trigger:
- none
variables:
- template: variable-template.yml
stages:
- stage: StageA
displayName: "Stage A"
jobs:
- job: output_message_job
displayName: "Output Message Job"
pool:
vmImage: "ubuntu-latest"
steps:
- powershell: |
Write-Host "Root Variable: $(VM001), $(VM002)"
For reference, here's the MS documentation on variable template usage:
Upvotes: 0