vRealize Automation 8 expressions and functions advanced blueprint techniques

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

Your email address will not be published.