Skip to content

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:

  1. 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.
  2. Clear the auto-assigned workflow and set Stagenone, fully parking the machine.
  3. Set BootEnvlocal so the host boots from its own disk and never netboots into discovery.
  4. Set Workflowesxi-no-vib-joinup, which drives the brownfield join. The execution Context follows Meta.BaseContext automatically (see Why the Context is set this way).

What the workflow does

The esxi-no-vib-joinup workflow runs three stages:

  1. esxi-no-vib-check-api — in the esxi-agent-runner context container, checks the ESXi API, then over SSH installs the drpy agent into memory on the host and starts it.
  2. esxi-no-vib-joinup-cleanup — clears the machine's Context and Meta.BaseContext (via drpcli) so the esxi-agent-runner context container is released rather than left running after the join.
  3. complete — finalizes with the machine on local boot.

Prerequisites

  • A running DRP endpoint with the API reachable.
  • drpcli installed on your workstation and configured for the endpoint. Set RS_ENDPOINT and either RS_KEY (user:password) or RS_TOKEN. Verify with:
Bash
drpcli info status
  • jq installed (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-joinup Workflow and the esxi-agent-runner Context. Confirm:
Bash
drpcli workflows exists esxi-no-vib-joinup
drpcli contexts exists esxi-agent-runner
  • 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):

Bash
#!/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

Bash
./create-esxi-machine.sh <name> <address> <insecure-password> <firstboot-ipaddr>
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:

Bash
./create-esxi-machine.sh esxi-01 10.10.0.21 'MyP@ss!' 10.10.0.21

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:

Text Only
>> 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:

Bash
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-joinup
  • Context: esxi-agent-runner
  • Meta.BaseContext: esxi-agent-runner
  • BootEnv and Stage are 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/empty
  • WorkflowComplete: 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 (see WorkflowComplete and Runnable) 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