- ABX (Action Based Extensibility) runs short, polyglot scripts as functions, triggered by deployment events or called as resource actions. Runtimes are Python, Node.js and PowerShell.
- An action is four things: a main function, inputs, declared dependencies, and a FaaS provider. Secrets come from action constants, never hardcoded in the script.
- On-premises, ABX runs on the platform’s built-in FaaS runtime at no extra cost. AWS Lambda is an optional external provider, not a requirement.
- ABX and VCF Operations Orchestrator are not the same tool. ABX is glue: short, event-driven, polyglot. Orchestrator is for stateful, plugin-driven, long-running orchestration.
- My rule: reach for ABX first for a quick integration; move to Orchestrator the moment you need state, a plugin, retries, or a workflow you will share across organizations.
Who this is for: Automation engineers and platform admins extending VCF Automation, plus architects deciding between ABX and Orchestrator for a given integration.
Prerequisites: A VCF Automation 9.x instance with Automation Assembler access, a working cloud template, and basic Python, Node.js or PowerShell. Comfort with the request-to-deployment flow from the earlier Parts.
Myth: ABX and Orchestrator are two ways to do the same job, so pick whichever you know. Reality: they overlap at the edges and diverge fast, and choosing wrong is how a five-line script becomes an unmaintainable workflow, or how a job that needed a real workflow engine ends up as a pile of brittle functions. This Part is about the first of the two, Action Based Extensibility, what it is good at, where it runs, and the honest line between it and VCF Operations Orchestrator.
I am writing against VCF Automation 9 (the product formerly known as VMware Aria Automation, and before that vRealize Automation), current on the 9.1 release. ABX carries forward from the 8.x Assembler model, so if you ran ABX in Aria Automation, the concepts here will be familiar, with the platform names updated.
What ABX actually is
ABX is a function-as-a-service model inside VCF Automation. You write a small script with a single entry point, the platform runs it in a managed runtime when something triggers it, and it returns a result. The trigger is usually a deployment event delivered through the Event Broker, for example after a machine is provisioned, but an action can also back a day-2 resource action or feed a custom form. The point of ABX is speed of authoring: no workflow canvas, no plugin model, just code that runs on an event.
It is polyglot. The supported runtimes are Python, Node.js and PowerShell, so you write in whatever your team already maintains rather than learning a workflow scripting dialect. That is the real draw: an engineer who knows Python can ship an integration in an afternoon.
Anatomy of an action
You author actions in Automation Assembler under Extensibility. Every action has the same parts, and getting them right is most of the job.
Main function, inputs, dependencies, provider
The main function is the entry point the platform calls. Inputs are the event payload plus any values you add. Dependencies are the runtime modules your code imports, declared so the platform installs them; forget one and the action fails at runtime with an import error, not at save time. The FaaS provider decides where the function executes, either auto-selected or pinned to a specific provider. You can also write the action inline or upload a ZIP package for anything beyond a single file.
Secrets belong in constants, not code
API keys and passwords go into action constants and secrets, then the function reads them at runtime. Hardcoding a credential in the script is the mistake I flag most in reviews, because actions get exported, shared and version-controlled, and a secret in the body leaks with them. Below is a Python action that fires after a machine is provisioned, reads a secret, and would register the VM with an external system.
def handler(context, inputs):
# Triggered on compute.provision.post (machine provisioned).
names = inputs.get('resourceNames', [])
vm = names[0] if names else 'unknown'
# Pull a credential from an action constant / secret. Never hardcode.
api_key = context.getSecret(inputs['dnsApiKeySecret'])
# ... call your IPAM / DNS / CMDB API here.
# Keep it idempotent: the same event may be delivered more than once.
return {
'status': 'registered',
'vm': vm
}
Where ABX runs and what it costs
On-premises, which is where VCF Automation lives, ABX actions run on the platform’s built-in FaaS runtime. There is no per-execution bill and no external dependency for the standard case. The AWS Lambda option you will see in the docs is an external FaaS provider for cloud or hybrid scenarios; it is optional, and most on-prem teams never touch it. So treat ABX as free compute on the appliance, with the caveat that free compute is still finite compute.
FaaS functions are not always warm. The first call after idle pays a cold-start penalty while the runtime spins up, and every action has an execution timeout. Long-running work, a 90-second API sync or a loop over hundreds of objects, will hit that ceiling and fail mid-flight. If a task is slow or stateful, that is the signal it belongs in Orchestrator, not in an ABX action that times out and leaves the work half done.
ABX or Orchestrator
Both can be triggered by the same events, so the question is not what is possible but what is appropriate. ABX wins on authoring speed and language choice for short tasks. Orchestrator wins on everything that needs structure: stateful, multi-step flows, a deep plugin library for vSphere, NSX and third parties, built-in error handling and retries, and workflows a provider can share across tenant organizations. In an All Apps organization, Orchestrator must be external, which is worth knowing when you plan the heavier integrations.
| Dimension | ABX action | VCF Operations Orchestrator |
|---|---|---|
| Model | FaaS function | Workflow engine |
| Languages | Python, Node.js, PowerShell | JavaScript, plus Python/Node/PowerShell scripting |
| Best for | Short event glue, quick integrations | Stateful, long-running, complex orchestration |
| Plugins / library | None; you call APIs yourself | Rich plugin ecosystem |
| Retries / error handling | Roll your own in code | Built into the workflow model |
| Long tasks | Timeout-bound, cold starts | Designed for duration |
Operational reality
Three things separate an ABX action that survives production from one that pages you. First, idempotency. Events can be delivered more than once, and a non-idempotent action that creates a DNS record twice or increments a counter on every retry will corrupt state. Write actions that can run twice with the same result. Second, dependency hygiene. Declare every module and pin versions where you can, because an undeclared import is a runtime failure on the worst possible day. Third, observability. Log enough to reconstruct what happened from the action run history, since a function that fails silently inside a deployment event is hard to trace after the fact.
Goal: register every new VM in DNS automatically. Build one ABX Python action bound to compute.provision.post via a subscription. It reads the VM name and IP from the event, pulls the DNS API key from a secret, and creates the record. Make it idempotent: if the record already exists, update instead of create.
This is a textbook ABX job: one event, one short call, no state to keep. The moment the requirement grows to also update the CMDB, then the IPAM system, then roll back all three if any fails, stop. That is a workflow, and it belongs in Orchestrator where retries and compensation are part of the model.
In practice: I keep a small library of single-purpose ABX actions, each doing one thing, and resist the urge to grow them. A fat action with branches for five scenarios is a workflow wearing a function costume. Split it, or promote it to Orchestrator.
Disclaimer: ABX actions bound to provisioning events run on real deployments. Test new actions against a throwaway project and a non-blocking subscription first, confirm idempotency, and make sure a failing action cannot wedge a deployment before you wire it to a blocking event.
Three ways an action gets invoked
People think of ABX as event-driven only, but an action can be reached three different ways, and the trigger you choose changes how you design it. Knowing all three keeps you from writing a clumsy event subscription when a cleaner option exists.
Event subscriptions
The common path. A subscription binds a lifecycle event to the action, and the action runs as part of provisioning. Subscriptions can be blocking, where the deployment waits for the action and a failure can stop it, or non-blocking, where the action runs alongside and a failure is logged but does not halt the request. Use blocking only when the action is genuinely a precondition, because a slow or flaky blocking action turns into a deployment outage. Most glue work should be non-blocking.
Resource actions (day-2)
An action can back a day-2 operation a user runs on a live deployment, which then sits under the day-2 policies covered in the governance Part. This is how you expose a safe, curated operation, rejoin a domain, rotate a key, resize a mount, without handing users a shell. The action is the implementation; the day-2 policy decides who may run it and whether it needs approval.
Called from a template or another action
An action can also be referenced from a cloud template or invoked from Orchestrator, which is how ABX and Orchestrator actually cooperate in the field: a workflow handles the stateful orchestration and calls a small ABX action for the one polyglot task that is awkward in JavaScript. That pattern, Orchestrator for the spine and ABX for a limb, is the one I end up recommending most.
Bringing ABX across from Aria Automation
If you are migrating from Aria Automation 8.x, your existing ABX actions are largely portable, because the authoring model carried forward. The handler signature, the constants, and the runtimes are the same. What changes is the surrounding platform: organization type matters now. In a VM Apps organization the experience is close to 8.x. In an All Apps organization the heavier extensibility leans on an external Orchestrator, so plan a migration as a chance to sort which logic stays as ABX glue and which should have been a workflow all along. I treat a migration as a cleanup, not a copy, retiring the fat actions that grew branches over the years and rewriting them as either tidy single-purpose actions or proper workflows.
My Take
Reach for ABX first, but only for what it is: short, stateless, polyglot glue that fires on an event. It is the fastest way to ship a one-call integration, and for that job nothing in the platform beats it on time-to-value. I would not use ABX when the task needs state, retries, a plugin, or sharing across organizations, because every one of those pushes you toward reimplementing a workflow engine inside a function that will time out. Validate idempotency and dependency declarations before you trust an action in production, since those two failures account for most of the ABX incidents I have cleaned up. The honest verdict: ABX and Orchestrator are partners, not rivals, and the skill is knowing which shape of work you are holding.
Pick one real integration you keep doing by hand, write it as a single ABX action this week, and bind it to a non-blocking event. If you reach for a second branch or a retry loop, you have just found your first Orchestrator workflow.
References
- VMware Docs — Learn more about extensibility actions
- Cloud Blogger — vRO workflows, vRO actions and ABX compared
- VMware Cloud Management — ABX now available on-premises
- Broadcom TechDocs — What’s new in VCF Automation



