vRealize Orchestrator: Standardising Modules & Actions

Managing your code base in vRealize Orchestrator can be quite challenging and complex. Often, you won’t realise this until you’ve reached a point where it becomes difficult and time consuming to both organise or locate existing code that you have written. In this post, I am going to suggest ways to help you organise your code better, using methods that I have adopted with my time using vRO.

I am not suggesting this be the perfect solution, but it should provide a working standard to adopt to your own needs. I would also argue that the extra time spent getting this in place on the outset, will lead to time saved later on.

Just for reference, from this point on, I am going to refer to ‘code base‘ and ‘actions‘ interchangeably, because your vRO actions ARE your code base. Almost every single line of code you write in vRO should be in an action (I will discuss this in more detail in a later post which I will link here).


Modules are quite a simple topic but it’s important to get them right as they are almost impossible to change later. Modules are used to organise or group a collection of actions together by a common function.

Here are some general principles I like to follow when creating modules: As a general rule, modules should:

  • Conform to a standard naming convention;
  • Allow developers to easily find existing actions or where to create new actions. Failure to address this point will result in developers re-inventing the wheel by writing new actions for which may already exist;
  • Always be lower case alphabetical characters using dot notation;
  • Always have a utility module for storing general ‘helper’ actions i.e. an action that returns a unique array of items

So generally, if you follow a standard naming convention for your module names then you’ll be set. I have found that the following naming convention works well:



[company] = company name as a single word

[component] = Examples are: NSX, vCAC, Infoblox, Activedirectory

[interface] – Examples are: REST, SOAP, PS (this is not needed if using a plugin)

[objects] = Parent object branch of the component, i.e. Edges, Entities, Networks, Groups

[object] = A property or object branch of the parent objects. These can contain actions that target a single object (singular)

Here is an example of what (some) of my Zerto Rest API code library looks like:

You could just create a module where the branch stops at [interface] or [objects], but what you’ll find is that it will become a dumping ground for dozens of actions, which will become difficult to maintain. Adding additional branches helps break the modules up.

The strategy around creating these branches usually goes in line with the interface/API’s, which helps align your modules quite nicely. A good module branching strategy can also provide execution performance enhancements by calling the module once for a smaller number of required actions.


Here are some general principles I like to follow when creating actions: As a general rule, actions should:

  • Contain small, manageable chunks of code that perform a specific task. Actions are just functions and just like any function, it should contain code that performs a specific task. If your action is doing many different tasks, then consider breaking these down into multiple, smaller actions.
  • Validate inputs. I appreciate that some may debate this idea, but actions are not ‘private functions’. They are public code where you can never guarantee that the action ‘caller’ is properly validating its inputs. This is the nature of vRO, it is a ‘hub’ that has many different uses cases and scenarios for executing the same actions. I have seen dozens of cases where developers and support engineers have wasted time tracking unexpected errors;
  • Be named appropriate to the task they perform. I generally like to use verbs in my action names, like, ‘getVirtualMachineNames’, ‘getVirtualMachineNetworks’ or ‘setCustomProperty’. Actions named this way will make it easier for other developers to identify what they are used for;
  • Have variables declared in a single block. This will just make it easier to see what variables are being used. The data type can also be defined, but is not always necessary or as important;
  • Provide consistent logging throughout. Make it so, the action almost tells the story of what is happening. Don’t go overboard, but generally a before, during and after style to logging works quite well;
  • Nesting actions within an action is generally ‘OK’ but keep it to a minimum if possible. Too many nested actions can create depth that may be more difficult to maintain and troubleshoot later on. Typical use cases are ‘helper’ or ‘utility’ actions (you’ll be completely forgiven with actions used for workflow presentation as these are a pain);
  • Perform singular tasks. Don’t write actions that perform plural tasks. Write the singular version first, then use a looping mechanism that re-uses the singular action (there are also ways this can be achieved with performance in mind in vRO). This way you’ll only have 1 version of the code;
  • Be based on a user-defined template. Yup, I’m not crazy. Have a defined template (aka boilerplate) set out on how an action should generally look and have the team follow this. It will make code reviews far easier;
  • Always be camel cased alphabetical characters (no dots);

If you adopt the above principles, you’ll have actions that will be much easier to understand, maintain and troubleshoot and everyone will be a happy bunny.

Action Example

Here is a working example of an action that has been based on a template.

Action Template

And here is the template:

If you’re wondering about the ‘logger‘ action, you can read my post here.

I hope this helps provides some standards around your vRO code base. If you have suggestions, comments, etc. then please let me know as I’ll be glad to hear them and value every bit of feedback.

1 thought on “vRealize Orchestrator: Standardising Modules & Actions

Leave a Reply

Your email address will not be published. Required fields are marked *