Table of contents
A VM Apps Cloud Template may look like YAML that can simply be copied into an All Apps organization. That is the most dangerous interpretation of the migration. The document contains resource types, IDs, placement assumptions, event payloads, and lifecycle hooks that belong to the source control plane. Copying the syntax can preserve every hidden dependency while changing the platform underneath it.
The useful unit of work is therefore the service contract: what the WebShop consumer chooses, what the platform guarantees, which external systems are updated, and how deletion cleans them up. This article rebuilds that contract as an All Apps Blueprint design and a concrete dynamic Custom Form behavior contract. It also separates the artifacts that can help reconstruction from the bindings that must be created again.
Study status: not executed
This design is a reconstruction from Broadcom documentation, not a report from a completed VCF Automation 9.1 lab. Product labels, served API versions, event payloads, form import behavior, permissions, and failure handling must be checked on the exact source and target builds before the catalog is opened.
TL;DR
- Do not translate
Cloud.*resources one for one. Preserve the business inputs and observable lifecycle, then implement them against the All Apps services actually enabled in the target Region. - Treat a Custom Form export as reconstruction material, not as proof of cross-organization portability. IDs, action references, credentials, policies, and server-side authorization all need new evidence.
- Start with one WebShop request contract, one read-only Orchestrator action, and a test matrix that includes tampering, timeout, and deletion—not just the happy path.
Rebuild the service, not the document
The source catalog item exposes a familiar result: a WebShop deployment for dev, test, or prod. Behind that result, the VM Apps template may use Cloud.vSphere.Machine, cloud zones, image and flavor mappings, network profiles, approval policies, ABX actions, event subscriptions, and custom resources. All Apps introduces a different consumption hierarchy: organization, project, Region quota, Namespace, VPC, and services such as VM Service. The same input name can consequently drive a different placement and authorization path.
Build a parity sheet before writing the target Blueprint. For each source behavior, name the target mechanism and the proof that will demonstrate parity:
| Consumer behavior | Source implementation | Target decision | Required evidence |
|---|---|---|---|
| Select environment | template input and project constraint | stable environment input |
one accepted request per allowed value |
| Select placement | cloud zone, tags, profiles | Region, Namespace Class, infrastructure policy | effective Namespace, VM Class, storage and network |
| Configure VM | image/flavor mappings | Content Library image and VM Class | created VM specification and Ready condition |
| Approve production | approval policy | new All Apps approval policy | request blocked, approved, then resumed |
| Register external objects | subscriptions, ABX, custom resources | Orchestrator workflows with one writer | correlated DNS, IPAM and CMDB records |
| Delete service | deployment lifecycle | idempotent target cleanup | no orphan and a repeatable second delete |
The formatVersion documentation is important, but a version number is not a migration tool. A legacy template is identified by its resources and dependencies, not merely by formatVersion: 1. Generate or inspect a target example on the exact build, verify the VM Operator CRD served by the Supervisor, and only then commit the All Apps manifest.
Keep the consumer-facing contract deliberately small:
inputs:
application:
type: string
default: webshop
readOnly: true
environment:
type: string
enum: [dev, test, prod]
dataClassification:
type: string
enum: [internal, confidential]
migrationMode:
type: string
enum: [rebuild, repackage]
changeId:
type: string
Project IDs, Namespace Class names, VM Classes, storage classes, VPCs, and subnets are implementation details. The form resolves them; the server verifies them again. This keeps a later target change from becoming a breaking catalog API change.
Broadcom documents All Apps sample Blueprints and a Content Hub workflow. Import accepts .OVA, .OVF, and .YAML inputs for the documented stateful Blueprint flow. Export is a different operation: a valid Blueprint, its images, and dependencies are packaged as a re-importable ZIP, while ISO files are ignored. None of those mechanics prove that a VM Apps deployment instance, form binding, or external object moves with the archive.
A concrete dynamic Custom Form
The WebShop form below is based on the series contract examples/custom-form-dynamic-contract.yaml. It is intentionally a behavior specification rather than a claim that the YAML itself can be imported. The user chooses three business values. Production reveals a change-ticket field. A read-only VCF Operations Orchestrator action calculates an eligible target profile. Technical fields remain hidden from the user, but hidden never means trusted.
form: webshop-migration-request
visible_fields:
application:
value: webshop
read_only: true
environment:
values: [dev, test, prod]
required: true
data_classification:
values: [internal, confidential]
required: true
migration_mode:
values: [rebuild, repackage]
required: true
change_id:
visible_when: environment == "prod"
required_when: environment == "prod"
validation_pattern: "^CHG[0-9]{7}$"
dynamic_action:
name: com.corp.vcfa.forms.getMigrationTargetProfile
side_effects: none
inputs:
application: "${application}"
environment: "${environment}"
data_classification: "${data_classification}"
migration_mode: "${migration_mode}"
returns:
allowed: boolean
reason: string
target_profile:
project: string
namespace: string
namespace_class: string
vm_class: string
storage_class: string
vpc: string
subnet_front: string
subnet_application: string
subnet_data: string
approval_required: boolean
submission_controls:
disable_when_action_fails: true
revalidate_target_server_side: true
reject_modified_hidden_values: true
The structured response is a design contract
The single target_profile object and its multi-field bindings are not presented as a documented import schema. Confirm the supported return types and bindings on the exact 9.1 build. KB 445540 documents a 9.1.x validation failure when dropdown external values use Properties or Array/Properties; its workaround is to return primitive values of the expected type. Where that limitation applies, return a supported selection key or separate primitive values, then resolve and reauthorize the full target profile on the server.
Consider a prod + confidential + rebuild request. The action can return project prj-webshop-modern, Namespace ns-webshop-prod, Namespace Class nsclass-prod-confidential, VPC vpc-webshop-prod, three tier subnets, an encrypted storage class, and approval_required: true. The user sees a readable target summary and must enter a value such as CHG1234567. A dev + internal + rebuild request resolves to the development Namespace and does not request approval. If no compliant profile exists, allowed is false, submission stays disabled, and the form displays the returned reason.
The action needs four non-functional properties: it is read-only, deterministic for the same inputs and catalog state, free of secrets in its response, and bounded by a tested timeout. It should query a controlled target registry, not discover capacity by writing provisional infrastructure. At submission time, the request workflow must recompute or reauthorize the profile. A user can modify hidden values in the browser; server-side authorization is the only reliable boundary.
Broadcom’s Custom Forms guidance covers external values and dependencies. The official development practices article is useful for form design. Still, verify field identifiers, dependency refreshes, timeout presentation, accessibility, and role behavior on the target build. KB 437466 also documents a 9.x deployment-name customization limitation in specific tenancy contexts. Use a separate stable correlation key for CMDB and idempotency rather than turning a display name into a technical identity.
Where portability stops
An exported form can accelerate reconstruction when the source build supports the operation. It cannot establish portability by itself. Review every field ID, target input, default, constraint, visibility rule, external action reference, project or organization ID, role, error state, and sensitive value. Create fresh credentials and certificate trust. Record the source artifact checksum for audit, but assign new target IDs.
The same rule applies to extensibility:
- Export Orchestrator packages through the supported package mechanism, then reconfigure endpoints, plugins, certificates, credentials, and organization identifiers. The VCF Operations Orchestrator Packages API documents the package service, not behavioral compatibility between environments.
- Replace ABX actions rather than assuming their runtime follows the service. Broadcom documents ABX deprecation; preserve triggers, retries, idempotency, and observable effects in a supported target implementation.
- Recreate event subscriptions from payloads observed in the All Apps Event Log. The All Apps event-subscription documentation does not make an Aria Automation 8.x topic or filter automatically valid.
- Recreate custom-resource definitions with explicit Create, Read, Destroy, Day‑2, scope, and idempotency contracts. An existing CMDB item needs a recorded
adopt,reconcile, orreplacedecision; a legacyCustom.*deployment resource is not an automatically transferred instance. - Rebuild approval, Day‑2, lease, and infrastructure policies in a safe order. Test every persona, because inclusion policies can remove an action from a role that is not covered.
During coexistence, assign one writer per external object. If VM Apps owns DNS and All Apps owns CMDB for the pilot, document that split. Never let both generations create the same AD computer account or load-balancer member without a reconciliation key.
Validate the complete lifecycle
The minimum test matrix is broader than “the form submitted.” Run dev/internal/rebuild, prod/confidential/rebuild with a valid change ticket, missing and malformed tickets, no eligible target, action timeout, a project user modifying hidden values, an approval rejection, a duplicate event delivery, and deletion after partial external registration. Repeat the tests for organization admin, project admin, and project user.
Evidence should connect the catalog request to the Namespace, VM, policy decision, workflow run, and external record through one correlation key. Capture the All Apps event schema rather than paraphrasing it. Demonstrate that Read returns the external truth and that Destroy is idempotent. Finally, unpublish the target Blueprint version, disable new subscriptions, and remove only identified pilot objects as the pre-production rollback path.
The most common false success
An imported form that renders correctly is not a migrated service. It can still reference an obsolete action, accept a forged hidden target, emit an unmatched event, or create a second CMDB record. Publication should remain blocked until the request, Day‑2, failure, retry, and deletion paths have evidence on the exact build.
Conclusion
The migration succeeds when WebShop Modern has a stable consumer contract and a newly proven implementation—not when the source YAML has been made syntactically acceptable. Preserve business choices, rebuild target bindings, and make every external effect observable and reversible.
Contract before resources
Define inputs, outcomes, lifecycle, and evidence before selecting All Apps resource types.
Hidden is not trusted
Resolve targets dynamically, then authorize them again on the server when the request is submitted.
Bindings are new
Recreate policies, events, credentials, IDs, and writers; exports provide material, not proof.
Get the next one by email
New articles and series, sent when they are published. No other mail.



