Workflow Design Series · Part 1 of 4

Workflow Design: Actions, Tasks & Structure

A practical architecture model for building maintainable, reusable vRO workflows — focused on where logic lives, how it's organized, and what a clean workflow skeleton looks like.

Author
vrodocs
Published
May 2026
Version
1.0
Tags
vRO Architecture Best Practices
Contents
  1. Introduction
  2. Actions vs. Scriptable Tasks
  3. Single Responsibility
  4. Standard Workflow Structure
  5. Naming Conventions
  6. Key Takeaways
01

Introduction

A vRO workflow is easy to build. A maintainable vRO workflow takes discipline.

Once you move past the basics — wiring a few scriptable tasks together, calling a REST endpoint, deploying a VM — the next challenge is architecture. How do you structure a workflow so that it's readable six months later? How do you write logic that can be reused across workflows without copy-pasting? How do you build something a teammate can debug without asking you for a walkthrough?

The answer starts with a clear mental model: know what belongs in an Action, what belongs in a Scriptable Task, and how those pieces fit into a repeatable workflow skeleton. Get that right, and everything else follows.

02

Actions vs. Scriptable Tasks

This is the single most important architectural decision in vRO. It's also where most workflows go wrong.

The rule is simple:

Rule of ThumbIf you'd copy-paste a script into two workflows, it belongs in an Action. Scriptable Tasks should be thin.

In practice, a well-designed Scriptable Task is often a single line — just a call into an Action:

JavaScript// Good — logic lives in the Action, the task just calls it
accessToken = System.getModule("com.company.azure").GetAzureToken();

Or unpacking a structured result into typed workflow variables:

JavaScript// Unpack a Properties object into typed workflow variables
vmName         = parsedResult.get("name");
resourceGroup  = parsedResult.get("resourceGroup");
subscriptionId = parsedResult.get("subscriptionId");

If your Scriptable Task is 40 lines of business logic, that's a signal the logic belongs in an Action.

03

Single Responsibility

Actions are only reusable if they do one thing.

The Single Responsibility Principle (SRP) is especially important in vRO because actions are called by name at runtime. An action that does too much becomes impossible to reuse without pulling in side effects you don't want.

✅ Single Responsibility❌ Violates SRP
GetAzureToken — fetches and returns a token Action that fetches a token and queries a VM
QueryAzureVM — queries and returns the raw response body Action that queries and parses the response
ParseGraphQueryResponse — parses any graph response into a Properties object Parser that also unpacks results to workflow variables

Notice the third example: parsing and unpacking are separate responsibilities. The parser returns a structured result; the unpacking happens in a Scriptable Task that maps values to workflow variables. This keeps the parser reusable across any workflow that calls the same API, regardless of what variable names that workflow uses.

The PayoffWhen an API changes, you update one action. Every workflow that calls it gets the fix automatically.
04

Standard Workflow Structure

Once you accept that Actions hold logic and Scriptable Tasks hold wiring, a natural workflow skeleton emerges. Nearly every integration workflow in vRO follows this pattern:

Standard Workflow Skeleton
Start
Credential / Auth Block  Actions — locked, reused
Query / Lookup Block  Actions — locked or new
Unpack / Transform  Scriptable Task — thin
Decision Element  Branch on null-check or status
Operation Block  Actions — locked or new
End / Error End

This structure makes workflows predictable. Anyone familiar with the pattern can read a new workflow and immediately know where credentials are loaded, where the data comes from, where branching happens, and where the actual operation executes.

Three Principles Behind the Skeleton

Auth first, always. Credentials and tokens are loaded at the top, before any query or operation. If auth fails, the workflow fails fast — before touching anything.

Query before operate. Look up the resource first, validate it exists, then act on it. A Decision element after the query handles the "not found" case cleanly, without letting the operation block run blind.

Operations are late. The actual mutation — the delete, the deploy, the update — sits as far right in the workflow as possible. Everything before it is read-only setup. This makes it easy to add pre-flight checks without restructuring the whole workflow.

05

Naming Conventions

Consistent naming makes a workflow library navigable. These conventions apply across all workflows, actions, and modules:

ThingConventionExample
WorkflowTitle CaseAzure VM Decommission
ActioncamelCaseGetAzureToken, ParseGraphQueryResponse
ModuleReverse-domaincom.company.azure
Workflow VariablecamelCaseaccessToken, graphResponseBody
Workflow InputcamelCasevmName, waitingPeriod
Pseudo-constantUPPER_SNAKEMAX_RETRIES, POLL_MS
Config ElementDescriptive with hyphensAzure-API-Authentication
Optional Action paramopt_ prefixopt_timeout, opt_rowIndex

A few notes worth calling out:

06

Key Takeaways

Up NextPart 2 of this series covers IN/OUT variable bindings and Decision elements — the silent failure modes that trip up even experienced vRO developers.