Zero2Hero - Using Aria Automation to Deploy Multiple Machines with Multiple Disks - Part 4



VMware Aria VMware Aria Automation

Published on 7 March 2024 by Christopher Lewis. Words: 1721. Reading Time: 9 mins.

In part four of this five post blog series, we will continue our #Zero2Hero journey in understanding the authoring of Multiple Virtual Machine VMware Cloud Templates. We will continue with working towards the use case for deploy multiple virtual machines (with additional on-demand disk configurations) by looking at the Single Machine - Multiple Disks (with additional on-demand disk configurations) VMware Cloud Template.

As a reminder, the original series will cover the following high level use cases:

  • Creating a Single Virtual Machine Cloud Template (boot disk only) - Part 1
  • Creating a Single Virtual Machine Cloud Template (with additional static disk configuration) - Part 2
  • Creating a Multiple Virtual Machine Cloud Template (with additional static disk configuration) - Part 3
  • Creating a Single Virtual Machine Cloud Template (with additional on-demand disk configurations) - Part 4
  • Creating a Multiple Virtual Machine Cloud Template (with additional on-demand disk configurations) - Part 5

Note: All of the above use cases, and the VMware Cloud Templates described, could be used as standalone templates, but I thought it was important to show incremental development, i.e. we’re going from Zero to Hero.

Note: I did start to write this as a single blog post but the more and more I wrote the post, the more I realized it was a big topic to get right and explain and, therefore, it was best to provide it in smaller posts.

The Requirements (Recap)

We have the following high level requirements when developing the final cloud template:

  1. The consumer must be able to deploy one or more Virtual Machines.
  2. The consumer must be able to choose the operating system (image) for the Virtual Machine.
  3. The consumer must be able to choose the Virtual Machine size (flavor) at request time.
  4. The consumer Must be able to choose to which cloud the Virtual Machine is deployed to (i.e. VMware Cloud or Private Cloud)
  5. Each Virtual Machine must have identical disk configuration.
  6. The disk configuration must support one to five additional disks.
  7. The disk configuration must be chosen at request time.

The Development Process

In the previous post, we introduced a way to deploy a set of clustered resource objects (Virtual Machines) using the count property. In this post, we’re going to take a slight side step and look at how we can configure a single machine to have multiple disks that are configured at request time. We want to do this because, this is a valid use case and it is the combination of this and the previous VMware Cloud Template that will help us complete our journey in Part 5 of the series.

So let’s get started.

Creating a Single Virtual Machine (with additional dynamic disk configuration)

Inputs

The majority of inputs of the VMware Cloud Template have remained the same, but we have removed the disk1_size and disk2_Size in favour of a new input type called diskConfigs. The diskConfigs input introduces two new input types we have not see before in this series, the array and the object.

  • The array is just like any other array, it is a list of integers, strings, or (as in our example) objects.
  • An object is a pretty flexible input type, it can be used to reference a VMware Aria Orchestrator Workflow, a VMware Aria Automation Property Group or (as we are using it) an list of different inputs.

Note: We can call any input anything we like, its just meta-data. It just has to conform to to the naming standards. It is definitely worth making it relevant and representative though.

Let us examine the diskConfigs input in more detail:

  • type: array - this is declaring the input is an array.
  • minItems: 0 - this is the minimum number of items in the object array. In our instance 0.
  • maxItems: 5 - this is the maximum number of items in the object array. In our instance 5.
  • items - is the list of objects in the array. As mentioned before, we are just using an object that contains multiple inputs.
  • type: object - this is saying that each element of the array is in fact an object that contains multiple inputs.

The we can see the individual inputs of the object that, as we will see later, correlate to the inputs required for the Cloud.vSphere.Disk Resource Object:

  • controller - this is a string input that corresponds to the SCSI controller that we should attach the disk to. We use an enumeration (enum) of static strings here to reduce the likelihood of inputting the wrong value.
  • unit - this is an integer input that corresponds to the Unit Number on the SCSI controller that we should attach the disk object to.
  • size - this is a number input that corresponds to the required disk capacity in GB.
  • drive - this is an optional string input that could be used to assign a mountpoint or drive letter in the operating system (using extensibility).
  • label - this is an optional string input that could be used to assign a label to the disk in the operating system (using extensibility).

If, during request time, the consumer added two disks, the values within the diskConfig array would look like this:

item controller unit size drive label
0 SCSI_Controller_1 1 100 d apps
1 SCSI_Controller_2 2 200 e data

Note: There is no logic or check to stop the consumer selecting the wrong input here because the inputs have no state. The Unit Number on each SCSI Controller can only be assigned to a single disk. Therefore, for example, if the consumer adds two disks on the same SCSI Controller and Unit Number then the deployment will just fail.

Resources

Using the same scenario as in Part 2 of the series, we have requested 1 Virtual Machine with Virtual Machine has 2 disks. So now let us explore what happens in the VMware Cloud Template.

Cloud.vSphere.Machine

Most of the properties of the Cloud.vSphere.Machine resource remain unchanged.

Note: If we were comparing it to the VMware Cloud Template in Part 3 , then one of the first things to notice is we have removed the allocatePerInstance:true Resource Flag from the Cloud.vSphere.Machine resource.

To support this multi-disk deployment we again need to update the Cloud.vSphere.Machine resource. This time we make a subtle change to the expression on the attachedDisks property to cater for the dynamic nature of the number of disks being requested.

attachedDisks: ${map_to_object(resource.disk[*].id, "source")}

Let us try and break that down (with the example) to make it easier to understand:

  • resource.disk[*] is an array of Cloud.vSphere.Disks objects. As we have 1 Virtual Machines x 2 disks, then there will be 2 elements in this array, i.e. resource.disk[0] and resource.disk[1].
  • resource.disk[*].id is an array of the id’s for the resource.disk resource objects. As we have 2 disks, then there will be 2 resource id’s in this array, i.e. resource.disk[0].id and resource.disk[1].id.
  • map_to_object(resource.disk[*].id, "source") returns the elements of the resource.disk[*].id array to the attachedDisks property using the key field called source.

Therefore if we could visualize the expanded expression syntax to see what the YAML would actually look like, we would see:

For vm, this expands to:

  vm:
    type: Cloud.vSphere.Machine
    properties:
      image: windows
      flavor: small
      constraints:
        - tag: cloud:vmc
      attachedDisks:
        - source: ${resource.disk[0].id}
        - source: ${resource.disk[1].id}
Cloud.vSphere.Disk

Whilst only a small amount changed in the Cloud.vSphere.Machine resource object from the Part 2 VMware Cloud Template, a lot has changed in the Cloud.vSphere.Disk resource. So let us break that down for the important properties of the Cloud.vSphere.Disk object!

Firstly we need to introduce a new Resource Flag for the Cloud.vSphere.Disk object:

  • allocatePerInstance - This is used so that VMware Aria Automation know to allow resource allocation to be customized for each object rather than once for all objects.

For more detailed information on Expression Syntax, checkout VMware Aria Automation Assembler Expression Syntax on the VMware Documentation site.

  • count is the number of Cloud.vSphere.Disk resource objects to create.
  • capacityGb is the size of the new disk in Gigabytes and not Gigabits (thank you camel case).
  • SCSIController is the name of the SCSI Controller to attach the disk to on the Virtual Machine.
  • unitNumber is the Unit Number on the SCSI Controller where the disk is attached.

So how do we extract the data from the diskConfig input array? Let us break that down:

  • count: ${length(input.diskConfig)} as we only have a single Virtual Machine resource, this is the length of the number of items in the diskConfig array.
  • capacityGb: ${input.diskConfig[count.index].size} - As we are using the allocatePerInstance Resource Flag, we need to iterate through the diskConfig array for each of the disks we configured at request time. In our example, we have added 2 disks, and therefore following will happen:
  • On the first iteration, count.index = 0, therefore ${input.diskConfig[0].size} is used.
  • On the second iteration, count.index = 1, therefore ${input.diskConfig[1].size} is used.

We use the same process to get the other values out of the input objects, including:

  • capacityGb: ${input.diskConfig[count.index].size} -
  • SCSIController: ${input.diskConfig[count.index].controller}
  • unitNumber: ${to_string(input.diskConfig[count.index].unit)}
  • drive: ${to_string(input.diskConfig[count.index].drive)}
  • drive(label: ${to_string(input.diskConfig[count.index].label)}

Note: We decided to use integers on the form and we can transform those values, where needed, to strings using the to_string() function. On hindsight, for unit we could of used a string input with an enum of values from 1-4 and this would have given the end user a drop down to select from like we did for the SCSI Controller.

Now, if we were to expand the code for the Cloud.vSphere.Disk array, we would expect to see something like:

  disk[0]:
    type: Cloud.vSphere.Disk
    properties:
        capacityGb: ${input.diskConfig[0].size}
        SCSIController: ${input.diskConfig[0].controller}
        unitNumber: ${input.diskConfig[0].unit}
        drive: ${input.diskConfig[0].drive}
        label: ${input.diskConfig[0].label}
  disk[1]:
    type: Cloud.vSphere.Disk
    properties:
        capacityGb: ${input.diskConfig[1].size}
        SCSIController: ${input.diskConfig[1].controller}
        unitNumber: ${input.diskConfig[1].unit}
        drive: ${input.diskConfig[1].drive}
        label: ${input.diskConfig[1].label}

Template Code

Adding that all in together and we get the following VMware Cloud Template YAML code:


Wrapping It All Up

As a recap, in part 4 we have taken a slight diagonal step towards our goal! We still have evolved our original VMware Cloud Template from deploying just a single Virtual Machine to being able to deploy a single machine with multiple disks with a dynamic disk configuration. If we think about our requirements we listed at the start of the post, we have actually met #2, #3, #4, #5, #6 and #7!

In the next, and final, post in the series, we will review our final VMware Cloud Template where we will meet all the requirements!

Published on 7 March 2024 by Christopher Lewis. Words: 1721. Reading Time: 9 mins.