Automation for creating Red Hat OpenShift clusters for NVIDIA DPF (DPU Platform Framework) on Red Hat OpenShift clusters with NVIDIA BlueField-3 DPUs and NVIDIA Network Operator (NNO) deployments.
One command runs the complete DPF deployment:
make allThis handles the complete deployment lifecycle:
- Creates OpenShift clusters using Red Hat Assisted Installer
- Deploys NVIDIA DPF operator with all prerequisites
- Sets up DPU-accelerated networking with OVN-Kubernetes
- Provisions worker nodes automatically via Bare Metal Operator
- Host: RHEL 8/9, 64GB+ RAM, 16+ CPU cores
- Hardware: NVIDIA BlueField-3 DPUs on worker nodes
- Network: Internet access, management and high-speed networks
- OpenShift CLI (
oc) - Red Hat Assisted Installer CLI (
aicli) - Helm 3.x
- Standard tools:
jq,git,curl
- Red Hat Pull Secret: Download from Red Hat Console
- Red Hat Offline Token: Generate at cloud.redhat.com/openshift/token
- NVIDIA NGC API Key: Create at NGC Portal β Account β Setup
DPF enables RShim on the DPU BMC during provisioning. If you need it for debugging later, enable it manually on that DPU BMC after provisioning.
Complete these manual steps on every DPU BMC before running make all-zt:
-
Configure the same
rootpassword on every DPU BMC. SetZT_DPU_BMC_ROOT_PASSWORDto this password when generating.env. -
Verify that the BMC Redfish endpoint is reachable. This command prompts for the shared
rootpassword instead of putting it in the shell history:curl -k -u root https://<DPU_BMC_IP>/redfish/v1/Systems/Bluefield
-
Set
ZT_DPU_BMC_IP_RANGE_STARTandZT_DPU_BMC_IP_RANGE_END. ADPUDiscoveryscans this inclusive range and creates aDPUDevicefor every DPU BMC it finds. Scans use 25 workers. By default, the next scan starts three minutes after the previous scan completes; override the interval withZT_DPU_DISCOVERY_SCAN_INTERVAL. Only one range is supported. The DPU addresses may have gaps within it; every address in the range is scanned. -
List the DPU BMC IPs of every host in
WORKER_<N>_DPU_BMC_IPS, comma-separated without spaces, for exampleWORKER_1_DPU_BMC_IPS=10.6.136.33orWORKER_2_DPU_BMC_IPS=10.6.136.34,10.6.136.35for a host with two DPUs. Every address must be inside the discovery range, and each host with DPUs needsWORKER_<N>_DPU=trueand itsWORKER_<N>_BMC_*values. Hosts 1-5 are supported, since the HBN VLANs and BGP AS numbers are derived fromN. DPU serials are not required: discovery reads them from the DPU BMC.
Discovery does not create DPUNode resources (skipDPUNodeDiscovery: true).
The automation creates one DPUNode per host, dpu-node-worker-<N>, that
lists the DPUDevice discovered at each of the host's DPU BMC IPs. The DPUs
are named dpu-node-worker-<N>-<serial>. A discovered DPUDevice whose
address is not listed for any host is reported and is not provisioned.
Zero Trust DPU nodes use a custom-reboot-script ConfigMap based on NVIDIA's
example. The controller creates <dpunode-name>-script-job when reboot handling
is needed. The Job uses ZT_DPU_REBOOT_IMAGE, a small image containing Bash and
ipmitool, and performs the requested reset or power cycle through the matching
physical host BMC: dpu-node-worker-<N> uses the WORKER_<N>_BMC_* values.
PowerCycle uses chassis power cycle; the warm-reset methods use
chassis power reset; and NoAction exits without contacting the BMC.
With VERIFY_DEPLOYMENT=true, make all-zt and make scale-out-zt-dpus end
by waiting for every DPU listed in WORKER_<N>_DPU_BMC_IPS to reach phase
Ready and join the hosted cluster as a Ready Node, for the DPUDeployment to
be Ready, and for the management and hosted cluster operators to be stable.
The DPU and DPUDeployment waits are VERIFY_MAX_RETRIES x
VERIFY_SLEEP_SECONDS each (30 minutes by default). On timeout it prints each
DPU's phase and failing conditions, and the target fails. Run
make verify-zt-deployment to check an existing deployment.
Add WORKER_<N>_DPU_BMC_IPS for each new host to the inputs used to generate
.env. Ensure WORKER_COUNT includes every physical worker with DPUs and
configure its numbered WORKER_<N>_BMC_* variables. Regenerate .env, then
run:
source user.env
make generate-env FORCE=true
make scale-out-zt-dpusThe target checks every configured physical worker and powers on only those that
are off. It then waits for every configured DPU Redfish endpoint, waits for
discovery to create their DPUDevice resources, creates the missing host
DPUNode resources, and refreshes the HBN per-DPU configuration. Existing
IPAM, NAD, interface, and service-chain resources automatically reconcile for
the new DPUs. An existing DPUNode is not changed: to change the DPUs of a host
that is already deployed, scale it in first.
Scale-in works per host. Clear or change the host's WORKER_<N>_DPU_BMC_IPS in
the inputs used to generate .env, regenerate .env, then pass the host's
DPUNode explicitly. At least one host must keep its DPUs listed:
source user.env
make generate-env FORCE=true
make scale-in-zt-dpus DPU_NODE=dpu-node-worker-2The target removes the DPUNode from the DPUDeployment selector, waits for its
DPUs to be deleted, removes the DPUNode and its DPUDevice resources, and
refreshes the HBN configuration. Discovery recreates the DPUDevice of a DPU
whose address stays in the range within ZT_DPU_DISCOVERY_SCAN_INTERVAL, but
nothing provisions it while no host lists it. To take a DPU out of DPF
completely, for example to decommission it or to work on its BMC, move its BMC
IP outside ZT_DPU_BMC_IP_RANGE_START-ZT_DPU_BMC_IP_RANGE_END. To remove one
DPU from a host with several, list the remaining addresses,
run scale-in, then run make scale-out-zt-dpus; the remaining DPUs are
provisioned again. The target does not power off the physical worker.
Set VM_COUNT=1 to use an SNO management cluster. API_VIP and INGRESS_VIP
are not required. HYPERSHIFT_API_IP is ignored, MetalLB is skipped, and the
hosted control plane uses SingleReplica.
Add the SNO management-node network configuration to user.env:
# Zero Trust SNO management cluster
export VM_COUNT=1
export VM_STATIC_IP=true
export VM_EXT_IPS=10.6.135.30
export VM_EXT_PL=24
export VM_GW=10.6.135.254
export VM_DNS=10.11.5.160Replace the example values with the environment's reserved SNO address,
prefix length, gateway, and DNS server. The address in VM_EXT_IPS must be
unused before deployment, and DNS must resolve
api.<CLUSTER_NAME>.<BASE_DOMAIN> to that address so DPUs can reach the
management API.
Generate .env and confirm that the static network values were preserved:
source user.env
make generate-env FORCE=true
grep -E '^VM_(COUNT|STATIC_IP|EXT_IPS|EXT_PL|GW|DNS)=' .envThe DPU BMCs must still reach the BFB registry. By default, manifest
preparation resolves HOST_CLUSTER_API to the SNO management-node address
after make update-etc-hosts. Multi-node deployments use
HYPERSHIFT_API_IP for the registry address.
git clone https://github.com/rh-ecosystem-edge/openshift-dpf.git
cd openshift-dpf
cp .env.example .env# Add Red Hat offline token
mkdir -p ~/.aicli
echo "YOUR_OFFLINE_TOKEN" > ~/.aicli/offlinetoken.txt
# Add OpenShift pull secret (downloaded from Red Hat)
cp ~/Downloads/openshift-pull-secret.json openshift_pull.json
# Create NGC pull secret
cat > pull-secret.txt << 'EOF'
{
"auths": {
"nvcr.io": {
"username": "$oauthtoken",
"password": "YOUR_NGC_API_KEY",
"auth": "BASE64_ENCODED_CREDENTIALS"
}
}
}
EOF# Edit .env file with your settings
nano .env
# Essential settings (DPF is the default profile):
CLUSTER_NAME=my-dpf-cluster
BASE_DOMAIN=example.com
VM_COUNT=1 # 1=SNO, 3+=Multi-node
DPF_VERSION=v25.7.1make allβ±οΈ Takes 2-3 hours - fully automated, no user interaction needed
All scripts and Make targets read configuration from a single .env file at the
repo root. This file is generated β never edit the source files in ci/
for your local setup.
| File | Role |
|---|---|
ci/env.defaults |
Default values for every optional variable. User environment variables always overwrite these. |
ci/env.required |
Variables that have no default and must be provided. Generation fails immediately if these are not set in user environment. |
ci/env.template |
The canonical set variables used by the scripts .env and in what order. |
-
Export your required variables (and any optional overrides):
# DPF is the default; set DEPLOYMENT_PROFILE only when using NNO export CLUSTER_NAME=my-cluster export BASE_DOMAIN=example.com export API_VIP=10.1.150.100 export INGRESS_VIP=10.1.150.101 export DPU_HOST_CIDR=10.0.110.0/24 export BFB_URL=https://content.mellanox.com/BlueField/...
To keep overrides reusable, put them in a personal file (e.g.
user.env) and source it first:source user.env make generate-env -
Run the generator:
make generate-env # creates .env (fails if .env already exists) make generate-env FORCE=true # overwrites an existing .env
ci/env.defaultsis sourced β sets defaults for every variable, but does not overwrite anything already exported in your shell.ci/env.requiredis sourced β aborts with an error if any required variable is still unset.envsubstrendersci/env.templateinto.env, substituting every${VAR}with its resolved value.
A flat KEY=VALUE file at the repo root (.env) containing the merged
result of your overrides + the defaults. This is consumed by make and scripts/env.sh at runtime.
make validate-env-filesChecks that every variable in ci/env.defaults has a corresponding entry in
ci/env.template so nothing is silently dropped, and report template-only variables that have no default.
DEPLOYMENT_PROFILE accepts dpf or nno and defaults to dpf.
dpfkeeps the complete existing deployment and usesmake all.nnocreates a base OpenShift cluster through worker provisioning and skips DPF-only requirements and manifests, including the NFD operator.
Generate an NNO environment rather than editing .env manually:
export DEPLOYMENT_PROFILE=nno
export CLUSTER_NAME=my-nno-cluster
export BASE_DOMAIN=example.com
export VM_COUNT=1
export OPENSHIFT_PULL_SECRET=openshift_pull.json
make generate-env FORCE=true
make create-base-clusterFor a multi-node cluster, also set API_VIP and INGRESS_VIP. See the
NNO base cluster guide for
the complete workflow and instructions for switching an existing environment.
| Guide | Purpose |
|---|---|
| Getting Started | Step-by-step setup guide |
| NNO Base Cluster | Create a base OpenShift cluster for NNO |
| Configuration | Environment variables |
| Worker Provisioning | Add physical worker nodes |
| Troubleshooting | Fix common issues |
| External storage | SKIP_DEPLOY_STORAGE and storage requirements |
Perfect for development and edge computing:
VM_COUNT=1
RAM=32768 # 32GB recommended
make allFor high-availability environments:
VM_COUNT=3
API_VIP=10.1.150.100 # Required for multi-node
INGRESS_VIP=10.1.150.101 # Required for multi-node
make allFull DPU acceleration with worker nodes:
WORKER_COUNT=2 # Number of physical worker nodes
# Configure WORKER_*_BMC_IP, WORKER_*_BMC_USER, etc.
make allTo assign fixed IPs to cluster VMs (e.g. for predictable addressing or firewall rules), set VM_STATIC_IP=true and provide these required variables in .env:
| Variable | Description |
|---|---|
VM_EXT_IPS |
Comma-separated list of static IPs, one per VM (must have at least VM_COUNT entries). Example: 10.8.2.110,10.8.2.111,10.8.2.112 |
VM_EXT_PL |
Prefix length for the subnet (e.g. 24 for /24) |
VM_GW |
Default gateway IP |
VM_DNS |
DNS server IP(s), comma-separated |
Example for 3 VMs:
VM_STATIC_IP=true
VM_EXT_IPS=10.8.2.110,10.8.2.111,10.8.2.112
VM_EXT_PL=24
VM_GW=10.8.2.1
VM_DNS=8.8.8.8,4.4.4.4Optional: PRIMARY_IFACE (default enp1s0) β interface name used for static config on the VMs.
make all # Full automated deploymentmake create-cluster # Create OpenShift cluster
make deploy-dpf # Deploy DPF operator
make add-worker-nodes # Add worker nodesmake worker-status # Check worker status
make worker-secure-boot SECURE_BOOT_ACTION=show WORKER_INDEX=1
make worker-secure-boot-enable SECURE_BOOT_TIMEOUT_MINUTES=15
make worker-secure-boot-disable SECURE_BOOT_TIMEOUT_MINUTES=15
make run-dpf-sanity # Health checks
make clean-all # Complete cleanup, including physical worker power off
make clean-all POWER_OFF_WORKERS=false # Complete cleanup, leave physical workers powered onThe Secure Boot enable and disable targets force-restart workers that need a change, without draining them first. Workers already configured for and booted in the requested state are skipped. Schedule maintenance before running these commands on an active cluster.
Redfish TLS certificate verification is enabled by default. Set
REDFISH_CA_BUNDLE=/path/to/ca-bundle.pem when worker BMCs use a private CA.
For an isolated lab using self-signed BMC certificates, you can explicitly opt
out with make worker-secure-boot-disable REDFISH_INSECURE=true (or the enable
target). Use that only on a trusted management network.
- OpenShift: 4.20 (only supported version)
- DPF: v25.7+ (production), v25.4+ (legacy support)
- Hardware: NVIDIA BlueField-3 DPUs on Dell/HPE/Supermicro servers
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Issues: Report problems in GitHub Issues
- Documentation: Complete user guides in
docs/user-guide/ - Community: Join discussions in repository discussions
Get started with your first deployment: Getting Started Guide