- The All Apps organization presents a Kubernetes-style API, the Cloud Consumption Interface, so VMs, databases and clusters are provisioned with
kubectland YAML. - You get there with the new vcf-cli, which builds a kubeconfig from your tenant endpoint, an API token, and a context created with
vcf context create --type cci. - A single YAML can describe the application and the infrastructure under it, which is what makes this GitOps-friendly rather than just another CLI.
- The portal is still useful: its Create VM wizard generates the YAML you commit, so the UI becomes the starting point, not the system of record.
- My recommendation: kubectl and YAML for repeatable developer consumption, the portal for one-offs and discovery, and the vmware/vcfa Terraform provider for cross-resource platform-as-code.
Developers do not want your portal. They want to commit a YAML file to a repository and have a virtual machine, a database, or a Kubernetes cluster appear. The All Apps organization in VCF Automation 9 is built for exactly that. It presents a Kubernetes-style API, so the same kubectl and YAML your teams already use for applications now provision the infrastructure underneath them. A single file can describe the app and the VM it runs on. This Part is the consumption path; for the token mechanics in depth, see Part 20.
The All Apps API is just Kubernetes
The design decision that matters here: the All Apps organization exposes consumption through the Kubernetes API surface, not a proprietary one. You authenticate, you get a context, and from then on you use plain kubectl against your namespace. A VM is a resource you kubectl get, apply and delete like any other. Because it is declarative, the same YAML can carry the application and the infrastructure it depends on, which means one pull request, one review, one source of truth.
Setting up access
Three things stand between a developer and their first kubectl apply: the vcf-cli, an API token, and a context. The vcf-cli is the new VCF 9 tool that produces a kubeconfig for your tenant; install it as a binary or through a package manager. The API token is created in the tenant under account settings, and it is shown once, so copy it immediately. Do not use the redirected provider admin for this; use a normal All Apps org user, because that token will carry whatever privileges its owner has.
# Confirm the CLI is installed
vcf version
# Create a Kubernetes context for your All Apps org (type cci)
vcf context create allapps01
--endpoint https://flt-auto01.rainpole.io
--insecure-skip-tls-verify
--type cci --auth-type basic
--tenant-name allapps_org01
--api-token $API_TOKEN
# List namespaces, pick the default context, then use plain kubectl
vcf context list
vcf context use allapps01
kubectl get vm
# If the session expires, refresh it
vcf context refresh
Expected result: vcf context list shows the namespaces your user can reach, and kubectl get vm returns the VMs already in the selected namespace. The kubeconfig lands in your home .kube directory. Drop --insecure-skip-tls-verify once you have proper certificates in place; it is fine for a lab and wrong for production.
Provisioning declaratively
With a context in place, provisioning is ordinary Kubernetes. The fastest way to get a correct manifest is to walk the Create VM wizard in the portal, choose your components, and copy the YAML it produces into a file. That generated YAML is the source of truth for the exact apiVersion and fields your build expects, which is far safer than hand-writing them from memory.
# Representative VM Service manifest. Generate the exact apiVersion
# and fields from the Create VM wizard rather than hand-writing them.
apiVersion: vmoperator.vmware.com/v1alpha2
kind: VirtualMachine
metadata:
name: app-server-01
namespace: team-blue-ns
spec:
className: best-effort-medium
imageName: ubuntu-2204
storageClass: vsan-default
powerState: PoweredOn
# Apply it, watch it, remove it: all standard kubectl
kubectl apply -f app-server-01.yaml
kubectl get vm
kubectl delete -f app-server-01.yaml
Expected result: the VM reaches a running, powered-on state and shows in kubectl get vm. The most common failure is a name collision: apply a manifest whose name already exists and the request fails. Treat names as you would in any Kubernetes namespace, unique and intentional. The same model extends past VMs, so a database from Part 31 or a cluster is just another resource in the file.
Why this is worth enabling
The win is not that developers type kubectl instead of clicking. It is that infrastructure requests become code: reviewed in a pull request, versioned, diffable, and reproducible across environments. A single manifest that defines the app and its VM means the two never drift apart, and promoting from dev to prod is a path change, not a re-request. This is the consumption side of the same shift the deployment model assumes: the request and the running thing are described in one place.
kubectl, portal, or Terraform?
Three consumption paths coexist, and they are not rivals so much as different jobs. The portal is for one-off requests, discovery, and generating starter YAML. kubectl with vcf-cli is for repeatable developer consumption and GitOps. The vmware/vcfa Terraform provider is for cross-resource platform-as-code, where you manage organizations, projects and catalogs as a unit. Most shops end up using all three, and that is fine, as long as a given workload has one owner among them.
| Path | Best for | Trade-off |
|---|---|---|
| Portal (UI) | One-offs, discovery, YAML generation | Not repeatable or versioned |
| vcf-cli + kubectl | Declarative dev consumption, GitOps | Token and context setup; k8s familiarity |
| vmware/vcfa Terraform | Cross-resource platform-as-code | State and provider lifecycle to manage |
vcf context use against the dev namespace and kubectl apply on merge to the dev branch, then the same files against the prod namespace on merge to main. There is no second request system for infrastructure: the VM and the app ship together, reviewed in the same pull request. When the VM needs more memory, someone edits one line, opens a PR, and the change is auditable forever. The portal was used exactly once, on day one, to produce the first manifest.
--insecure-skip-tls-verify as a lab-only shortcut, not a habit.
Where This Pays Off
Turn on kubectl-native consumption the moment you have developers who already live in Kubernetes, because it removes the one piece of friction a portal can never fix: it puts infrastructure in the same workflow as their code. My recommendation is to lead developers to the generated-YAML habit immediately, so the portal becomes a teaching tool rather than a daily destination, and to reserve Terraform for the platform layer rather than per-workload requests. When would I not push this? For teams that do not use Kubernetes and never will, the portal or a Service Broker catalog item is a kinder interface than a kubeconfig. Match the path to the person. For everyone already fluent in kubectl, anything less than declarative consumption is friction you are choosing to keep. Could your developers provision their next VM from a pull request today, and if not, what is stopping them?
References
- VCF Automation 9: Provisioning a VM through the Kubernetes CLI (vrealize.it)
- About the VCF Automation API (Broadcom TechDocs)
- Installing and using the VCF CLI (Broadcom TechDocs)
- VCF Automation 9 programmatic token generation (vrealize.it)



