Workflow Design Series · Part 4 of 4

Workflow Design: Composition & Building a Library

Actions are the infrastructure; workflows are the wiring. How to build a vRO action library that compounds over time, and why the magic is in the bindings.

Author
vrodocs
Published
June 2026
Version
1.0
Tags
vRO Architecture Best Practices Composition
Contents
  1. The Hard Way
  2. Actions Are the Infrastructure
  3. What Shared Infrastructure Actually Looks Like
  4. The Magic Is in the Bindings
  5. The Payoff
01

The Hard Way

There is a version of vRO that works and a version that compounds.

The working version gets the job done. Workflows run, tickets close, servers get provisioned and decommissioned. But every new workflow is roughly as much work as the last one. Logic gets duplicated because it is faster to copy than to find. A change to an auth endpoint becomes a search-and-fix across six workflows instead of one. The environment grows and so does the maintenance surface.

Most engineers spend years in that version without realizing there is another one.

The compounding version feels different. New workflows come together faster because the pieces already exist. A fix in one place stays fixed. Five different workflows can behave consistently under the hood because they are all calling the same actions.

The difference is not a feature. It is a discipline, and it starts with one idea.

02

Actions Are the Infrastructure

Think about five decommission scenarios: physical servers, virtual machines, cloud instances, dev environments, DMZ hosts. Each one has different logic, different branching, different edge cases. Five workflows, built separately, maintained separately.

Now think about what they all have in common: fetching DNS records, deleting DNS records, checking for snapshots, stopping a VM, removing a monitoring target. The same operations, repeated across all five scenarios.

If those operations live inside each workflow, you maintain five copies. If they live in shared actions, you maintain one. The workflows call into the library and handle what makes each scenario unique. The foundational work is done once.

The Core PrincipleActions are the infrastructure. Workflows and scriptable tasks are the wiring. Infrastructure is never built for a single use case.

The moment you write an action, ask yourself: could any other workflow call this? If the answer is yes, build it like shared infrastructure from the start.

03

What Shared Infrastructure Actually Looks Like

An action that can be called by any workflow makes no assumptions about where it is being called from. Every input arrives as an explicit parameter. The output is clean and typed. It does one thing completely.

The name is a reliable signal. GetVMPowerState belongs to the library. GetVMStateForDecommission was written for one workflow and will probably never leave it. If the workflow context is in the name, the action was built for one caller.

Module structure matters more than most engineers expect. Actions grouped by domain (com.company.vsphere, com.company.dns) get found by the next person who needs them. Actions grouped by the workflow that first needed them get duplicated. Most duplication is not laziness; it is a navigation failure. An engineer who cannot find the action writes it again.

Scriptable tasks complete the picture. They are workflow-specific wiring: unpacking action results, setting Decision flags, binding variables between calls. They belong to the workflow and should stay there. They are not candidates for extraction. Knowing the boundary between a scriptable task and an action, before you write it, is what keeps the library clean over time.

04

The Magic Is in the Bindings

This is the part most engineers underestimate.

You can name your actions correctly, group them into the right modules, keep them single-responsibility, and still end up with actions that cannot be reused. The reason is almost always the same: the inputs and outputs were designed around one specific workflow, not around the operation itself.

An action with universal bindings accepts what any workflow can provide and returns what any workflow can use. A VM name. A hostname. An IP address. A status string. A boolean. These are the currencies of a vRO library. Every workflow has them. Every workflow can pass them.

An action with workflow-specific bindings accepts a Properties object packed by the calling workflow, or returns a structure that only makes sense if you know how the first workflow happened to need the data laid out. The next workflow has to adapt to it, work around it, or rewrite it.

The Reusability TestCan you drop this action into a workflow you have never seen before, wire the inputs and outputs, and have it work? If yes, the bindings are universal. If you need to know something about the calling workflow to wire it correctly, they are not.

This is where reusability actually lives. Not in the module structure, not in the naming conventions. In the contract that the action's inputs and outputs represent. Get the bindings right and the action plugs into anything. Get them wrong and the action is coupled to its origin, no matter how well everything else is designed.

When you are writing a new action, define the inputs and outputs before you write a single line of logic. Ask what the simplest, most portable representation of each input is. Ask what the cleanest, most universally useful form of the output is. That decision, made before the implementation, is what determines whether the action joins the library or just lives in one workflow forever.

05

The Payoff

The compounding effect is not obvious at first. The first few workflows built this way do not feel dramatically different. The discipline costs a little extra thought upfront.

It shows up later. A new requirement arrives that would have taken a week and takes a day, because GetVMSnapshots already exists, StopVM already exists, the DNS actions already exist. The new workflow is mostly assembly. The logic was already written, already tested, already trusted.

That is what vRO looks like when it is working the way it was designed to. Not a collection of independent automations, each carrying its own copy of the same logic. A library of shared actions that workflows assemble into whatever the next requirement happens to need.

You do not build that in a day. You build it one well-written action at a time, across every workflow, consistently. The engineers who have it did not set out to build something special. They just stopped writing actions for the workflow in front of them and started writing them for everything that came after.

Series CompleteThis is the final part of the Workflow Design Series. Parts 1 through 4 cover Actions and Structure, IN/OUT Bindings and Decision Elements, Error Handling and Resilience, and Composition and Building a Library.

If you are working through this in your own environment, figuring out where to start or what to pull out first, the path is clearer than it looks. The foundation is already there.