Dr. Pranay Jha

VMware • Cloud • AI • Enterprise Architecture

FORMERLY
VMware Insight & Cloud Pathshala
What began over a decade ago as a passion for sharing knowledge has evolved into a unified platform for Enterprise AI, VMware, Cloud Architecture, Research, and Modern Infrastructure.
, ,

Custom Forms and Request Customization in VCF Automation (VCF Automation 9 Series, Part 15)

How to build catalog request forms in Automation Service Broker for VCF Automation: value sources, external-value Orchestrator actions, field and external validation, and the design mistakes that leave forms half-populated.

VCF Automation 9 Series · Part 15 of 41
TL;DR · Key Takeaways
  • A custom form lives in Automation Service Broker and overrides the default request form that VCF Automation generates from a Cloud Template input schema.
  • Field values come from one of five sources: Constant, Bind, Computed, Conditional, External Value. External Value calls a VCF Operations Orchestrator action, and the action return type must match the field type.
  • There are two validation layers: field constraints (live, per field) and external validation (an Orchestrator action that runs on submit and can fail the whole form).
  • The single most common support ticket is a form that loads empty. The cause is almost always a required field with no default value feeding an external-value action.
  • Keep form actions dumb and fast. Quota and placement belong in projects, policies and the template, not in the form.
Who this is for: cloud admins and automation engineers who publish catalog items in VCF Automation (formerly Aria Automation, formerly vRealize Automation) and want request forms that match what their tenants actually need.
Prerequisites: a released Cloud Template in the catalog (see Part 14), an Automation Service Broker role that can edit content, and an Orchestrator instance reachable from the org if you plan to use external values.

Mark one dropdown required, give it no default value, then bind it to an external-value action that fills in the field below it. Publish. The tenant opens the catalog item and sees a blank form that never populates, no error, no spinner, nothing. That exact pattern is the most frequent custom-form complaint I get called about, and it has nothing to do with the action code. The form designer is doing precisely what it was told. This Part is about telling it the right things.

Where custom forms actually live

When you publish a Cloud Template to the catalog, VCF Automation auto-generates a request form from the template inputs section. Every input becomes a field, the input type picks the widget, and any enum becomes a dropdown. That generated form is functional and ugly. A custom form is the override: you open the form designer in Automation Service Broker, switch the form on, and from that point the designer owns what the tenant sees. The underlying template inputs do not change, which matters because the same template can be requested through the API with no form involved at all.

This is a clean separation worth keeping in your head: the template defines what can be provisioned and what governance applies, the form defines how a human asks for it. Do not push provisioning logic into the form. The form is the storefront, not the warehouse.

From template input to tailored request formThe custom form overrides the auto-generated form; the template inputs stay the sameCloud Templateinputs: { } inAssemblerReleased toService Brokerauto form builtCustom Formdesigner ONoverrides layoutTenantsees the form,submits requestAPI requests bypass the form entirely and hit the template inputs directly.
The custom form sits between the released template and the tenant. It changes presentation, not the provisioning contract.

VM Apps and All Apps draw the form from different places

In a VM Apps organization the experience is the one carried over from Aria Automation 8.x: the Service Broker custom form designer, the value sources you already know, and external values backed by an embedded or external Orchestrator. In an All Apps organization custom forms attach to blueprints through the Content Hub, and the org requires an external Orchestrator for external values. The field properties and validation concepts line up, but the navigation and a few capabilities differ. Confirm which org type you are in before you start clicking, because the menus do not match the older screenshots floating around the community.

The five value sources, and when each earns its place

Every field in the designer pulls its value, its option list, its constraints and its visibility from a value source. Pick the cheapest one that does the job. Reaching for External Value when a Constant would do is how forms get slow and brittle.

Value sourceWhat it doesReach for it when
ConstantA fixed value baked into the form.A default that never changes per request.
BindMirrors another field on the form.One answer should drive another field directly.
ComputedA value calculated from other fields, no code.Simple arithmetic or string joins suffice.
ConditionalSets value, options or visibility from rules.Show or hide sections based on a prior choice.
External ValueRuns an Orchestrator action to return the value.The data lives in an external system (IPAM, CMDB).
Choosing a value sourcePick the cheapest source that answers the questionA form fieldConstantfixed valueBind / Computedfrom other fieldsConditionalrules / visibilityExternal ValueOrchestrator actionExternal systemIPAM, CMDB,vCenter
External Value is the only source that leaves the appliance. Treat that round trip as a cost, not a default.
In practice: External Value is the source people overuse. Every external value is a synchronous call to Orchestrator on form load or on field change. Ten of them on one form, all chained, and the tenant watches a half-rendered page. The first thing I check on a slow form is how many external values fire on initial load.

External Value: wiring an Orchestrator action

The mechanism is simple. In the field Values tab, set the value source to External Value, then pick an Orchestrator action. The designer only lists actions whose return type matches the field type: a text field accepts actions returning a String, a multi-value field accepts an Array/string, and so on. Get the return type wrong and your action simply will not appear in the list. That is the first thing to verify when an action is missing.

Action inputs can be constants or bound to other fields. Constants are safe, because an empty string is passed when nothing is set. Bound inputs are where forms break. During form initialization a bound field with no default is null, your action receives null, and if it calls a method on that null it throws. Guard every bound input. Here is a name generator that defaults cleanly instead of failing:

// VCF Operations Orchestrator action: getDefaultVmName
// Return type: String  (must match the form field type)
// Input: projectName (String), bound to the Project field

if (projectName == null || projectName == '') {
    return 'vm-unassigned';      // never let a null reach .substring()
}
var prefix = projectName.substring(0, 4).toLowerCase();
return prefix + '-' + System.nextUUID().substring(0, 6);

// Bound input null on load  =>  returns 'vm-unassigned'
// Project = 'Finance'       =>  returns 'fina-a1b2c3'
Gotcha
There is a second, quieter failure mode. External actions only run once every dependent field with a constraint holds a valid value. A required dropdown with no selection is invalid, so any action bound to it never fires, and the downstream field stays empty with no error. Users read that as a broken form. It is a constraint that was never satisfied.

Two validation layers, and why I prefer the cheap one

VCF Automation gives you two ways to keep bad input out of a deployment. They run at different times and cost different amounts.

Field constraints run live and for free

Required, min/max value, min/max length, regex pattern and match are properties on the field itself. They evaluate in the browser as the user types, with no Orchestrator round trip. A match constraint on a confirm-password field does the same job as a custom action and costs nothing. If a field constraint can express the rule, use it.

External validation runs on submit and can see the whole form

An external validation is an Orchestrator action wired in the form Validation tab. It runs when the user submits, can read several fields at once, and returns null for pass or an error string for fail. Use it for logic field constraints cannot express, like checking a request against a project ceiling or a policy. Do not use it for things a regex already handles.

// Orchestrator action: validateVmRequest  (return type: String)
// Inputs: cpuCount (Number), memoryGB (Number) bound to form fields
// Returns null when valid, or an error message when not

var MAX_CPU = 16;
var MAX_MEM_GB = 64;

if (cpuCount == null || memoryGB == null) {
    return null;     // let the 'required' constraint handle empties
}
if (cpuCount > MAX_CPU) {
    return 'CPU count ' + cpuCount + ' exceeds the project ceiling of ' + MAX_CPU + '.';
}
if (memoryGB > MAX_MEM_GB) {
    return 'Memory ' + memoryGB + ' GB exceeds the ceiling of ' + MAX_MEM_GB + ' GB.';
}
return null;
Field constraintExternal validation
Runs whenAs the user typesOn submit
CostNone, in browserOne Orchestrator call
ScopeOne fieldMany fields, form-wide message
Best forrequired, length, regex, matchpolicy / quota / cross-field rules

Worked example: a clean "Request a VM" form

Take a template that exposes four inputs: project, environment, CPU and memory. A naive form marks all four required, binds a name generator to project, and adds external validations on CPU and memory. It loads slow and sometimes blank. Here is the version I would ship.

The dependency chain, and where it breaksTop: required, no default = chain stalls. Bottom: default set = chain runs.Projectrequired, NO defaultgetDefaultVmNamenever firesVM Namestays emptyProjectdefault = FinancegetDefaultVmNameruns on loadVM Namefina-a1b2c3
Same form, one change. A default on the required Project field lets the whole chain evaluate on load.
Worked example numbers
Project: required, default Finance, options from one external value cached on load. Environment: required, default Dev. CPU: number, field constraints min 1 / max 16. Memory: number, min 2 / max 64 GB. VM Name: external value bound to Project, guarded. One external validation, validateVmRequest, as a backstop. Result: two external calls on load instead of five, every field valid at render, and the ceiling enforced both in the field and on submit.

The mistakes teams make

Four patterns account for most of the custom-form tickets I see:

1. Required fields with no default. Covered above and worth repeating because it is number one. If a field is required and feeds an action, give it a default.

2. Long chains of dependent actions. Field A feeds action B feeds field C feeds action D. One invalid link stalls everything after it, and it is miserable to debug. Break the form into pages and flatten the dependencies.

3. Heavy actions. Form actions should return in a second or two. They are not the place for large REST sweeps or database joins. If you need expensive data, fetch a narrow slice or pre-compute it.

4. Governance in the form. A clever validation that blocks a request is trivial to bypass through the API, which ignores the form entirely. Quotas, leases and approvals belong in projects and policies, not in form JavaScript.

My take: the form is UX, not a control plane. Anything that must hold true regardless of how the request arrives goes in the template inputs, the project limits, or a governance policy. I treat external validation as a helpful warning at the storefront, never as the lock on the door.

A note for All Apps organizations

If you run an All Apps org, custom forms attach to blueprints through the Content Hub rather than the classic Service Broker content list, and external values require an external Orchestrator wired to the org. The value sources and the field-versus-external validation split behave the same way, so the design rules in this Part carry over. What differs is the path to the designer and a handful of capabilities that landed first in the VM Apps experience. When a community walkthrough does not match your screen, the org type is usually why. Part 3 covers the org-type decision in full.

Disclaimer: validate form and action changes in a non-production org first. Editing a custom form on a live catalog item changes what every tenant sees on their next request. Export the form definition before a major edit so you can roll back.

Test the form before your tenants do

A custom form has more moving parts than it looks, and the only way to know it behaves is to request through it the way a tenant would. The catalog has a request preview, but a preview is not a submission. The behaviour I care about only shows up end to end: does every external value resolve on load, does each validation fire at the right moment, and does the request actually reach a deployment.

The check I run on every form before it goes near production tenants is short and always the same. Open the catalog item as a member of a real project, not as an admin, because role and project scope change which options the value sources return. Watch the network for how many Orchestrator calls fire while the form renders; one or two is healthy, a cascade is the dependent-action chain biting. Leave each required field at its default and confirm the dependent fields populate without a single click, because that is exactly the state a first-time user lands in. Then push each numeric field one past its ceiling and confirm both the field constraint and the external validation reject it, since you want the field constraint catching it live and the validation as the backstop. Last, submit a genuinely valid request and follow it to a running deployment, because a form that validates perfectly but never provisions is still broken.

One more habit worth keeping: export the form definition before any significant edit. The designer has no version history of its own, so the exported JSON is your rollback. When a change to a live catalog item misbehaves, re-importing the previous definition is far faster than reconstructing the layout field by field from memory while tenants are filing tickets.


What I'd Do

Start from the auto-generated form and change only what the tenant genuinely needs. Default every required field that feeds an action. Push validation down to field constraints wherever a regex or a min/max can carry it, and keep external validation for the cross-field and policy checks that constraints cannot express. Keep external-value actions small, guarded and fast, and count how many fire on load before you publish. Above all, remember the API does not see your form, so never let it be the only thing standing between a tenant and a bad deployment. Build your next catalog item this way and the support queue gets noticeably quieter. In Part 16 I move from the form to the rules behind it: approval, lease and day-2 governance policies.

VCF Automation 9 Series · Part 15 of 41
« Previous: Part 14  |  VCF Automation Guide  |  Next: Part 16 »

References

Broadcom TechDocs — Custom forms in VCF Automation for VM Apps
Broadcom TechDocs — Custom forms in VCF Automation for All Apps
VCF Blog — Good Practices for Developing Custom Forms with VCF Automation

About The Author


Discover more from Dr. Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

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

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

VCF Automation 9 Series

Discover more from Dr. Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading