How to Join Brownfield ESXi Machines into Your DRP Endpoint¶
This guide shows an operator how to bring an existing, already-running ESXi host — a brownfield machine that Digital Rebar Provision (DRP) did not install — under DRP management without rebooting, wiping, or PXE-discovering it.
The procedure creates a DRP Machine for the host,
attaches the credentials the ESXi content needs, pins it to boot from its own
disk, and runs the esxi-no-vib-joinup Workflow inside the esxi-agent-runner
execution Context to complete the join.
Brownfield vs. greenfield
Greenfield ESXi provisioning installs ESXi from scratch via PXE Discovery. Brownfield means the host is already installed and in service; you only want DRP to manage it, so the machine must never be allowed to netboot into Sledgehammer discovery.
Overview¶
A helper script, create-esxi-machine.sh, performs the join. It runs entirely
against the DRP API through drpcli — you run it from any workstation that can
reach the endpoint, and the script itself installs nothing on the ESXi host.
When the esxi-no-vib-joinup workflow runs, DRP installs its agent into
memory on the ESXi host to execute the workflow's tasks; it is not written to
the host's disk and does not persist across a reboot.
The script performs four ordered steps, each of which must succeed before the next runs:
- Create the Machine with its name, management address, ESXi params, and
Meta.BaseContext— but with no Stage, so DRP does not immediately queue discovery tasks. - Clear the auto-assigned workflow and set
Stage→none, fully parking the machine. - Set
BootEnv→localso the host boots from its own disk and never netboots into discovery. - Set
Workflow→esxi-no-vib-joinup, which drives the brownfield join. The execution Context followsMeta.BaseContextautomatically (see Why the Context is set this way).
What the workflow does¶
The esxi-no-vib-joinup workflow runs three stages:
esxi-no-vib-check-api— in theesxi-agent-runnercontext container, checks the ESXi API, then over SSH installs the drpy agent into memory on the host and starts it.esxi-no-vib-joinup-cleanup— clears the machine'sContextandMeta.BaseContext(viadrpcli) so theesxi-agent-runnercontext container is released rather than left running after the join.complete— finalizes with the machine on local boot.
Prerequisites¶
- A running DRP endpoint with the API reachable.
drpcliinstalled on your workstation and configured for the endpoint. SetRS_ENDPOINTand eitherRS_KEY(user:password) orRS_TOKEN. Verify with:
jqinstalled (the script uses it to build JSON safely and to read the created machine's UUID).- The ESXi content pack installed on the endpoint, which provides the
esxi-no-vib-joinupWorkflow and theesxi-agent-runnerContext. Confirm:
- The ESXi host's root password and its management IP address.
The Script¶
This script also ships with the vmware content pack and is served from the
endpoint at {ProvisionerURL}/files/plugin_providers/vmware/scripts/create-esxi-machine.sh.
To use it standalone, save the following as create-esxi-machine.sh and make it
executable (chmod +x create-esxi-machine.sh):
#!/usr/bin/env bash
#===============================================================================
# create-esxi-machine.sh
#
# Join a brownfield ESXi host into a DRP endpoint as a managed Machine, without
# rebooting it or running it through PXE discovery. See the DRP operator docs:
# "Joining Brownfield ESXi Machines".
#===============================================================================
# -e: stop on the first failing command (enforces the "each step must succeed
# before the next" ordering). -u: error on unset variables.
# -o pipefail: a pipeline fails if any stage fails.
set -euo pipefail
# Fixed content targets. Override here if your site renames the ESXi content.
WORKFLOW="esxi-no-vib-joinup" # Workflow the machine ends up running.
CONTEXT="esxi-agent-runner" # Execution Context the machine's tasks run in.
usage() {
echo "Usage: $0 <name> <address> <insecure-password> <firstboot-ipaddr>" >&2
exit 1
}
# Require EXACTLY four positional arguments.
[ "$#" -eq 4 ] || usage
NAME="$1" # DRP Machine name (usually the ESXi hostname)
ADDRESS="$2" # Management IP address of the ESXi host
PASSWORD="$3" # -> param "esxi/insecure-password"
FIRSTBOOT_IPADDR="$4" # -> param "esxi/network-firstboot-ipaddr"
# jq builds escape-safe JSON and parses the created object's Uuid.
command -v jq >/dev/null 2>&1 || { echo "error: jq is required" >&2; exit 1; }
# --- Step 1: create the Machine WITHOUT a Stage --------------------------
# Omitting Stage keeps DRP from laying down discovery tasks. Meta.BaseContext is
# set now so later Stage changes reset the Context to the value we want.
echo ">> Creating machine '$NAME' ($ADDRESS)..."
PAYLOAD="$(jq -n \
--arg name "$NAME" \
--arg address "$ADDRESS" \
--arg pw "$PASSWORD" \
--arg fb "$FIRSTBOOT_IPADDR" \
--arg ctx "$CONTEXT" \
'{
Name: $name,
Address: $address,
Meta: { "BaseContext": $ctx },
Params: {
"esxi/insecure-password": $pw,
"esxi/network-firstboot-ipaddr": $fb
}
}')"
CREATED="$(drpcli machines create "$PAYLOAD")"
UUID="$(jq -r '.Uuid' <<<"$CREATED")"
[ -n "$UUID" ] && [ "$UUID" != "null" ] || { echo "error: could not determine created machine Uuid" >&2; exit 1; }
echo " created Uuid=$UUID"
# --- Step 2: clear the auto-assigned workflow, then park the Stage -------
# The workflow must be cleared first: while under a workflow, DRP manages the
# Stage and refuses direct Stage/BootEnv changes.
echo ">> Clearing workflow and setting Stage=none..."
drpcli machines workflow "$UUID" "" >/dev/null
drpcli machines stage "$UUID" none >/dev/null
# --- Step 3: set BootEnv to local ----------------------------------------
# "local" boots the host from its own disk -- this is what prevents the
# brownfield ESXi machine from netbooting into discovery (and being wiped).
echo ">> Setting BootEnv=local..."
drpcli machines bootenv "$UUID" local >/dev/null
# --- Step 4: assign the joinup Workflow ----------------------------------
# Context is NOT set directly: every Workflow change resets Machine.Context to
# Meta.BaseContext. Because BaseContext was set in step 1, this Workflow change
# lands the Context on "$CONTEXT" automatically and keeps it pinned there.
echo ">> Setting Workflow=$WORKFLOW (Context follows BaseContext=$CONTEXT)..."
drpcli machines workflow "$UUID" "$WORKFLOW" >/dev/null
echo ">> Done. Machine '$NAME' ($UUID) is running Workflow=$WORKFLOW, Context=$CONTEXT."
Running It¶
| Argument | Meaning | Maps to |
|---|---|---|
<name> |
Machine name in DRP (typically the ESXi hostname) | Machine.Name |
<address> |
Management IP DRP uses to reach the host | Machine.Address |
<insecure-password> |
The ESXi root password | Param esxi/insecure-password |
<firstboot-ipaddr> |
First-boot management IP | Param esxi/network-firstboot-ipaddr |
Example:
Quote the password
Wrap arguments that contain shell-special characters (!, $, spaces,
etc.) in single quotes so your shell does not mangle them before the script
sees them.
Expected output:
>> Creating machine 'esxi-01' (10.10.0.21)...
created Uuid=3b8f...c2a1
>> Clearing workflow and setting Stage=none...
>> Setting BootEnv=local...
>> Setting Workflow=esxi-no-vib-joinup (Context follows BaseContext=esxi-agent-runner)...
>> Done. Machine 'esxi-01' (3b8f...c2a1) is running Workflow=esxi-no-vib-joinup, Context=esxi-agent-runner.
Verifying the Result¶
Confirm the machine landed in the expected state:
drpcli machines show Name:esxi-01 | jq '{Name, Address, BootEnv, Workflow, Stage, Context, Meta}'
Right after the script runs — and while the workflow is in progress — you should see:
Workflow:esxi-no-vib-joinupContext:esxi-agent-runnerMeta.BaseContext:esxi-agent-runnerBootEnvandStageare governed by the workflow as it runs.
After the workflow completes, the esxi-no-vib-joinup-cleanup stage clears
the context, so you should then see:
Context:""(empty)Meta.BaseContext: unset/emptyWorkflowComplete:true
If the context is still esxi-agent-runner after completion, see the note below.
Why the Context Is Set This Way¶
DRP resets a Machine's Context to its Meta.BaseContext value on every
Stage or Workflow change. Setting the Context field directly does not
survive, because the next Stage or Workflow change (of which this procedure
performs several) overwrites it back to BaseContext — which is empty by
default.
The supported, durable way to pin an execution Context is therefore to set
Meta.BaseContext. The script does this at create time, so every Stage or
Workflow change during the join lands the Context on esxi-agent-runner,
keeping the machine's tasks running in that context container.
Because DRP does not clear Context when a workflow completes, the
esxi-no-vib-joinup-cleanup stage explicitly clears both Context and
Meta.BaseContext at the end of the join (in a single drpcli machines update).
Without that step the context container would leak — it would keep running for
the machine forever. Clearing Meta.BaseContext as well ensures no later change
re-pins the context.
What Next?¶
The machine is now running the esxi-no-vib-joinup workflow. As its tasks run,
DRP installs its agent into memory on the ESXi host and completes the join over
the ESXi API — the host is never netbooted.
- Watch progress with
drpcli machines show Name:esxi-01(seeWorkflowCompleteandRunnable) or from the UX. - When the workflow completes, the context container has been released and the machine sits on local boot, managed by its on-host agent.
- Add profiles or params and assign further workflows for ongoing lifecycle management.
Troubleshooting¶
| Symptom | Cause / Fix |
|---|---|
error: jq is required |
Install jq on the workstation running the script. |
Workflow esxi-no-vib-joinup does not exist |
The ESXi content pack is not installed on the endpoint. Install it, then re-run. |
Context esxi-agent-runner ... is not available |
The esxi-agent-runner Context has no running container/plugin backing it. Ensure the context is available before running. |
Context still esxi-agent-runner after the workflow completes |
The esxi-no-vib-joinup-cleanup stage did not run or failed. Confirm the workflow ends with that stage and that its esxi-no-vib-release-context task succeeded. |
| Machine reboots into discovery | BootEnv is not local. Confirm step 3 succeeded, and that the assigned workflow keeps the machine on local boot. |
See Also¶
- Manual Join Up — joining Linux/Windows/ESXi hosts with the join-up scripts.
- Discovery Reference — all discovery and registration methods.