Over the past several weeks I was working on a project that required the ability to use custom resources in vRealize Automation to manage the lifecycle of resources other than Virtual Machines. In all of the research performed it appeared as though the Dynamic Types Plug-In in vRealize Orchestrator may be able to do the trick but getting it to do exactly what I needed it to do was problematic for several reasons. The documentation from the vendor is quite literally non-existent. There is a brief mention of the plug-in in the vRO 5.5 documentation, but nothing more surrounding the actual implementation and/or use of the plug-in, it simply states that the plug-in exists and tells you the workflows included in the plug-in. There is a decent write-up of using an older version of the plug-in here, but the presentation of the workflows are entirely different than what the workflows look like in the version supplied with vRA/vRO 7.3, and the older version of the plug-in appears to only allow dynamic types creation using REST workflows, where one of the objects I required the ability to use did not have REST available, but the product did have a vRO plug-in from where I could pull data from. There is a set of good write-ups located here and here, where I got a lot of my information from, but it still didn’t complete my understanding of the plug-in, and it wasn’t until I was able to work with the plug in for some time that I fully understood it’s implementation. All of that being said, this post will attempt to hit the very basics of the dynamic types plug-in. How to set it up, create a hierarchical structure to organize your objects and insert data in to each object. If time allows, I will do a follow up post of what vRA can do with a dynamic types object using Custom Resources at a later date.
I wish I would have run across the following post prior to beginning my research on Dynamic Types, but I figured it would be worth a mention, things are laid out in a much more eloquent fashion using a real-world example:
According to the limited mention of the Dynamic Types Plug-In in the vRO documentation:
The Orchestrator plug-in lets you define dynamic types, create objects of these types, and set relations between them.
For example, the VMware Hands On Labs HOL-1721-USE-2 lab has a sample Dynamic Type built in to the lab. If you want to see more advanced implementation examples you can log in to this lab and check things out. Under the inventory tab in vRO (after selecting the “Design” view from the drop-down) you can expand the Dynamic Types plug-in to view the inventory. The “Type Hierarchy” folder contains all of the types that have been defined in the Dynamic Types plug-in and their relationships to other types. Any other objects located directly under the Dynamic Types Plug-in are called namespaces (“CLM” in the screenshot). A namespace is a way to organize multiple dynamic types in to different overarching categories.
Why would we need to create a Dynamic Type? The specific use case I found myself up against was when using the Horizon plug-in, I needed a way to manage desktop pool entitlements, App Volume assignments and App Volume writable volumes. In vRA, you can use Custom Resources to provision anything and include it in the vRA inventory, but to become a Custom Resource, there must first be a corresponding type in vRealize Orchestrator. As you can see in the following screenshot, the Horizon plug-in is very limited in the number of types that are made available.
Creating Dynamic Types
To simplify things, I am going to use a fictional example just demonstrating how to structure a Dynamic Types namespace. I will be statically coding the elements themselves, but, as the name implies, these elements work best when dynamically created from an external source. I would also recommend taking time to diagram out the desired end state of your custom namespace as well. For this sample, I want the end state to look like the following:
For the end state to look like the above, I need to understand how to implement this solution using the Dynamic Types Plug-In. The Plug-In will require that I define a namespace, each of the types above, and their relationships to one another. Hopefully the diagram below helps clarify the relationships.
Create the Namespace
The first thing we need to do is to create the namespace (“Zoo”). Under the Workflows tab, navigate to Library > Dynamic Types > Configuration. Run the “Define Namespace” workflow. Input the name of the new namespace and select “Submit”.
Now you can navigate to the inventory tab and you should see your newly created namespace.
Create the Folder Types
Before we can create the types, you will need to create a workflow folder to store the generated workflows in. I created mine under the Dynamic Types folder:
Now we need to create the root level folders. Run the “Define Type” workflow. Select the namespace we created earlier, give the Type a name, select an Icon Resource (there are lots of images already built in to vRO, I just searched for folder, and a folder icon is already included, but you can also upload custom icons to the Resources tab in Design view), and we are leaving Custom Properties as not set for the folders (we will use these for the objects inside of the folders).
When you use the Dynamic Types plugin, there are 4 workflows created that must be configured in order to populate the plug-in data in your namespace. There are multiple ways to address this, you can allow the “Define Type” workflow to generate the workflows, you can create your own workflows as long as they have the appropriate input and output types, or you can create actions to populate the data. I would not recommend using actions (at least at first) because it is difficult to debug because you do not see the executions of the actions. By selecting “Yes” below we are allowing the workflow to generate the new workflows for us.
Now that our first type has been created, we can go to the Inventory tab and see what has been added. Now you should see the new type AnimalsFolder:
Under the Zoo folder in the Workflows tab, you should now see the 4 workflows that were generated.
Then, I went back and created all of the other “folder” types: ExhibitsFolder, TurtlesFolder, ElephantsFolder using the settings shown in the following screenshots for each. The big difference here is that you select “No” for “Generate workflow stubs for finder methods”, and instead point at each of the four workflows created when the first type was created. I am only showing the type creation for the “ExhibitsFolder” type below, but I also ran the same for the other two types. Of course, you could allow the workflow to generate new workflows for each type, but I have found that it is easier to have one set of workflows than to have to manage a large set of workflows.
Create the Object Types
The folder types we created earlier did not have any additional properties beyond the default name and id added to their types, but the Elephant, Turtle, and Exhibit types will all three have different properties added to each. Run the define type workflow again for each of these three types (adding the appropriate properties for each), and again point to the four workflows under the zoo folder
Create the Relationships
Now we need to tell the Plug-In all of the hierarchical relationships so that the objects appear in inventory as desired. Run the Define Relation workflow.
Next I submitted the following relationships:
|Parent Type||Child Type||Relation Name|
Once all of the relations have been submitted, the types should now show in the correct hierarchical order under the “Type Hierarchy” folder.
Edit the Workflows
Once all of your types and relationships have been defined you need to edit the workflows to return the correct objects. I would highly suggest authoring these workflows in the order they are presented below. You may not be able to see everything correctly in the inventory tab until you are finished editing the workflows.
Has Children In Relation Workflow:
This workflow returns a Boolean value, which will show an arrow next to your objects in the inventory if true (denoting that there are children beneath the object, and that it can be expanded). The inputs for this workflow are parentType (Zoo.ExhibitsFolder), parentId(Exhibits), relationName (Exhibits-Exhibit). The type inputs for all four workflows will always show up as namespace.type (Zoo.Exhibits).
You can code this workflow to return true or false depending on any scenario you would like, but for this example, I am going to force the workflow to always return true, unless the parentType is one of the three object types (Turtle, Elephant, or Exhibit).
Find Relation Workflow:
The Find Relation workflow is the first workflow that will start to work with the actual objects that are returned for the types.
When the plug-in creates the workflows, it will assign them with the type that you created as the output. Instead, change the output parameter type to “Array/DynamicTypes:DynamicObject”.
The first element that the workflow gets to is the namespace-children element. Any items that are located directly under the namespace (Animals and Exhibits in our example) will be given the namespace-children relation designation. This is built in to the Dynamic Types plug-in and cannot be changed.
When the relation submitted is the namespace-children relation, the parentId is the equivalent of the type that we are looking for, so we set the type variable to it. This will catch both the Animals and Exhibits folders.
Namespace Children element:
In the next Custom Decision element we want to search for the remaining items.
We need to find the child type for the relation in this case.
Set Type Element:
You will need to add your “Find All” workflow to the canvas, and then we take the type attribute and bind it to the “Find All Zoo” workflow’s input and bind the output to resultObjs.
What this workflow is doing from beginning to end is taking an input of a relationName along with the parentId and parentType and returning the array of all objects that are found in the relation. So, for example, for the Turtles-Turtle relation, the workflow will return all of the objects that are of the type “Turtle”. The following screenshot will only work once all four workflows have been completed.
Find All Workflow:
The Find All workflow returns all objects for a given type.
Again, change the resultObjs output parameter to the “Array\DynamicTypes:DynamicObject” type.
Since I used the string “Folder” in the name for all of my types that should appear as a folder, I can check for the string Folder in the input type and address the folders differently than the objects.
To create Dynamic Types objects, you use the DynamicTypesManager.makeObject() method. For each object, you need to specify the namespace and type, as well as a unique ID for your object and a name. On a side note, you can also install the Dynamic Types plug-in generator package from here which has a makeDynamicObjectFromProperties() action included that validates your inputs. If you require the ability to create a plug-in that solely uses REST to generate your types, this package is a good place to start.
Create Folders Element:
After we have created all of the desired folders, we need to determine which type the object is, and switch element helps to simplify that (rather than having 3 Custom decision elements).
The code for the following three elements is similar for all of the object types we are creating (Turtle, Elephant, Exhibit). We still use the makeObject() method as before, but this time we are adding the custom properties for each object using the setProperty() method on the objects for each property that needs to be added.
Find By ID Workflow:
This workflow is very similar to the Find All workflow, but instead of finding all of the objects of a given type, we want to find a specific (singular) object and return it.
Change the resultObj output type to “DynamicTypes:DynamicObject”:
The Final Plug-In Inventory
You can see below that the plugin now shows our inventory with the objects that we had created.
When viewing each object, you can also see the differing custom properties we added for each.
After you navigate your inventory, you should see that workflow runs have been kicked off. You want to be sure that you aren’t seeing any failed runs and that the runs are actually returning the expected results.
Issues Experienced Working with the Dynamic Types Plug-In
I would say that 95% of the issues when working with Dynamic Types end up being due to syntax errors somewhere in the workflows. I’m pretty certain that the other 5% are due to someone feeding a Mogwai after midnight…
The Find By ID workflow seems to be the culprit when you aren’t seeing any objects returned in your workflow runs. I have had some cases where the plug-in inventory actually showed the objects that I was looking for, but the runs themselves showed that resultObjs was Not Set. As far as I can tell, the Find By ID workflow is executed every time you view an object, so when you look at the variables tab of a workflow run, you can actually see the Find By ID workflow kick-off to actually show the object in the viewer. Double check your syntax and that you are seeing the expected object returns in the Find By ID workflow if you are having issues seeing objects in your workflow runs.
The best way I have found to troubleshoot the Dynamic Types plug-in is simply by viewing the workflow runs that are kicked off when viewing the inventory. Most of the time syntax errors will show up as a failed workflow run, but if not, click through the runs to be sure that each of them is outputting the expected result.