In one input you can only choose either the image or imageRef or choose the customization spec, not both at once 🙁 Then I found out about expressions and functions that can be used from within the vRA8 blueprints.
First create a blueprint
To show the workings of a function in blueprints we just need a simple blueprint to start with. This blueprint is a simple vSphere machine with a CPU and MEM input.
formatVersion: 1
inputs:
cpuCount:
type: integer
description: Number of virtual processors
default: 1
totalMemoryMB:
type: integer
description: Machine virtual memory size in Megabytes
default: 1024
resources:
Cloud_vSphere_Machine_1:
type: Cloud.vSphere.Machine
properties:
imageRef: WIN19-STD-TMP-01
customizationSpec: CustomizationWithAD
cpuCount: '${input.cpuCount}'
totalMemoryMB: '${input.totalMemoryMB}'
As you can see, this blueprint lets the end user specify CPU and MEM as an input and uses this input for the values cpuCount and totalMemoryMB.
It also uses the hardcoded imageRef and customization spec (WIN19-STD-TMP-01 and CustomizationWithAD).
The use case
So let’s pretend we have 2 different Windows templates. The first is configured with all company polices and needs to be added to the Active Directory. The second is more of an unmanaged machine that doesn’t need to be in Active Directory (or in a different one). When we want to adapt the blueprint to handle this there is no way of handeling this in one input. You need to let the end user choose image and customization spec. Or use a custom form to bind these two together. Since custom forms are created at the Service Broker level you first need to release an ‘unfinished’ Cloud Assembly blueprint. This is not ideal and there is a way to do this within the Cloud Assembly blueprint development directly.
Update the blueprint
First we add the new input which we call osBuild. The input section looks like this:
inputs:
cpuCount:
type: integer
description: Number of virtual processors
default: 1
totalMemoryMB:
type: integer
description: Machine virtual memory size in Megabytes
default: 1024
osBuild:
type: string
oneOf:
- title: Windows With AD
const: 'WIN19-STD-TMP-01,CustomizationWithAD'
- title: Windows Without AD
const: 'WIN19-STD-TMP-02,CustomizationWithoutAD'
As you can see we added the osBuild input with two options. The title is just the friendly name the end user sees. The const value is made up of two values separated by a comma. In this case we have two values, but you could add more than that. See this as one long string value.
Next we have to set the values for imageRef and customizationSpec. We remove the hardcoded values so it looks like this:
Cloud_vSphere_Machine_1:
type: Cloud.vSphere.Machine
properties:
imageRef: '${split(input.osBuild,",")[0]}'
customizationSpec: '${split(input.osBuild,",")[1]}'
cpuCount: '${input.cpuCount}'
totalMemoryMB: '${input.totalMemoryMB}'
Here we have changed the imageRef and customizatioSpec in such a way that they use the split function. This basically splits the input based on the comma character and turns it into an array. Finally we lookup the entry in the array with [0] and [1] (remember an array starts counting at 0).
This sets the values for imageRef and customizationSpec to the correct values upon deployment based on one input split into two parts.
To be able to test this, you can deploy the blueprint, but it is also possible to use the test option in Cloud Assembly. This does a mock deployment without actually deploying onto the environment. To also see that the inputs are chosen correctly we can add some debug tags as well. In the properties constraints section add two tags like this:
constraints:
- tag: '${"debug: " + split(input.osBuild,",")[0] + ":soft"}'
- tag: '${"debug: " + split(input.osBuild,",")[1] + ":soft"}'
Make sure to add the :soft in the ‘tags’ otherwise the placement policy will fail because these tags are not defined as a capability tag. The reason we use constraint tags for this debugging (or showing that it actually works) is that these tags show up in the provisioning diagram.
Completed blueprint
Now the blueprint should look like this:
formatVersion: 1
inputs:
cpuCount:
type: integer
description: Number of virtual processors
default: 1
totalMemoryMB:
type: integer
description: Machine virtual memory size in Megabytes
default: 1024
osBuild:
type: string
oneOf:
- title: Windows With AD
const: 'WIN19-STD-TMP-01,CustomizationWithAD'
- title: Windows Without AD
const: 'WIN19-STD-TMP-02,CustomizationWithoutAD'
resources:
Cloud_vSphere_Machine_1:
type: Cloud.vSphere.Machine
properties:
imageRef: '${split(input.osBuild,",")[0]}'
customizationSpec: '${split(input.osBuild,",")[1]}'
cpuCount: '${input.cpuCount}'
totalMemoryMB: '${input.totalMemoryMB}'
constraints:
- tag: '${"debug: " + split(input.osBuild,",")[0] + ":soft"}'
- tag: '${"debug: " + split(input.osBuild,",")[1] + ":soft"}'
Testing the blueprint
Now that we have the blueprint complete we can test it using the test functionality in Cloud Assembly. Remember, the test button sits on the left close to the Deploy button.
After entering the inputs, click test and wait for the test to succeed. Now click on provisioning diagram.
As you can see in the constraints section there are two tags listed that have the values for imageRef and CustomizationSpec. When deploying this for real, this image and spec are used to deploy the vSphere virtual machine.
Conclusion
This use case might not be very common, but I just like the fact that we can use these kinds of functions and expressions in our blueprints. This opens up a lot of possibilities and allows you to develop more complex blueprints.
Leave a Reply