May 13, 2026
Baremetal Provisioning with Ironic
A practical operations guide for Bifrost, the lightweight standalone deployment of OpenStack Ironic. Covers installation, node enrollment, custom IPA initramfs, image building with disk-image-create, SW RAID, and end-to-end baremetal provisioning on Ubuntu 22.04.
Bifrost (Lightweight OpenStack Ironic) Operations Guide
OS Environment: Ubuntu 22.04.5 LTS (CLI)
Last Updated: April 2026
Table of Contents
- Overview
- System Update and Package Installation
- Downloading Bifrost
- Installing Bifrost
- Verifying Installation and Initial Setup
- Node Driver Configuration
- Nginx httpboot Configuration
- Building a Custom IPA initramfs
- Building a Deployment Image
- Deploying a Node
- SW RAID Setup and Teardown
- Undeploying a Node
- Appendix
1. Overview
Bifrost is a lightweight solution that lets you run Ironic — OpenStack's baremetal provisioning service — as a standalone component, without the rest of the OpenStack stack.
It gives you a complete baremetal deployment pipeline: PXE boot → IPA (Ironic Python Agent) → image deployment, all self-contained.
Key Components
| Component | Role |
|---|---|
| Ironic | Baremetal provisioning engine |
| IPA (Ironic Python Agent) | Agent running on the node (ramdisk) |
| Nginx (httpboot) | Serves kernel and image files over HTTP |
| dnsmasq | DHCP/TFTP for PXE booting |
Node State Flow
PXE boot → enroll → manageable → available → deploying → active
| State | Description |
|---|---|
enroll |
Initial state after auto-registration via PXE boot |
manageable |
IPMI/Redfish connectivity verified; node is under management |
available |
Ready for deployment (after cleaning completes) |
deploying |
OS image deployment in progress |
active |
Deployment complete; OS is running |
cleaning |
Disk wipe in progress |
clean failed |
Disk wipe failed |
maintenance |
Maintenance mode (automatic power state sync disabled) |
2. System Update and Package Installation
sudo apt update -y && sudo apt upgrade -y
sudo apt install -y \
git \
python3-pip \
python3-venv \
python3-dev \
libffi-dev \
libssl-dev \
build-essential \
libguestfs-tools \
qemu-utils \
diskimage-builder
3. Downloading Bifrost
git clone https://opendev.org/openstack/bifrost /opt/bifrost
cd /opt/bifrost
4. Installing Bifrost
Variable notation: Replace anything in
<...>with values matching your environment.
4-1. VM Environment (No IPMI / manual-management)
./bifrost-cli install \
--network-interface <NETWORK_INTERFACE> \ # e.g. enp1s0
--dhcp-pool <DHCP_START_IP>-<DHCP_END_IP> \ # e.g. 192.168.122.100-192.168.122.200
--hardware-types manual-management \
-e enable_inspector=true \
-e enable_inspector_discovery=true \
-e inspector_rule_default_node_driver=manual-management \
-e ironic_auth_strategy=noauth
4-2. Physical Baremetal Servers (IPMI / Redfish)
./bifrost-cli install \
--network-interface <NETWORK_INTERFACE> \ # e.g. enp2s0
--dhcp-pool <DHCP_START_IP>-<DHCP_END_IP> \ # e.g. 192.168.240.100-192.168.240.200
--hardware-types ipmi,redfish \
-e enable_inspector=true \
-e enable_inspector_discovery=true \
-e inspector_rule_default_node_driver=ipmi \
-e default_boot_mode=uefi \
-e ironic_auth_strategy=noauth
Important: Always include
-e ironic_auth_strategy=noauth.
If omitted, Bifrost installs withhttp_basicauth mode, and allbaremetalCLI commands will return401 Unauthorized.
4-3. Creating clouds.yaml Before Installation
Creating this file beforehand prevents failures during the installation verification step.
mkdir -p ~/.config/openstack
cat > ~/.config/openstack/clouds.yaml << 'EOF'
clouds:
bifrost:
auth_type: none
baremetal_endpoint_override: http://<CONTROLLER_IP>:6385
ironic_inspector_endpoint_override: http://<CONTROLLER_IP>:5050
region_name: RegionOne
EOF
5. Verifying Installation and Initial Setup
When installation completes successfully, you'll see:
Ironic is installed and running, try it yourself:
source /opt/stack/bifrost/bin/activate
export OS_CLOUD=bifrost
baremetal driver list
5-1. Activating the Environment
source /opt/stack/bifrost/bin/activate
export OS_CLOUD=bifrost
# List available drivers
baremetal driver list
# List nodes (an empty list here is expected and normal)
baremetal node list
5-2. Checking Service Status
systemctl status ironic
systemctl status ironic-inspector
systemctl status dnsmasq
systemctl status nginx
5-3. Verifying noauth and Fixing It Manually
grep auth_strategy /etc/ironic/ironic.conf
If the value is http_basic or keystone, fix it manually:
sed -i 's/auth_strategy = .*/auth_strategy = noauth/' /etc/ironic/ironic.conf
systemctl restart ironic
5-4. Suppressing Warning Messages (Optional)
Running baremetal commands may surface Eventlet deprecation warnings. They don't affect functionality, but if you want to suppress them, add the following to .bashrc:
echo "export PYTHONWARNINGS=ignore" >> ~/.bashrc
source ~/.bashrc
6. Node Driver Configuration
6-1. IPMI Driver
NODE=<NODE_UUID>
baremetal node set $NODE \
--driver ipmi \
--driver-info ipmi_address=<IPMI_IP> \ # e.g. 192.168.1.100
--driver-info ipmi_port=623 \
--driver-info ipmi_username=<USERNAME> \ # e.g. ADMIN
--driver-info ipmi_password=<PASSWORD>
6-2. Redfish Driver
Use this for servers that support Redfish — Supermicro, HPE iLO, Dell iDRAC, and so on.
NODE=<NODE_UUID>
baremetal node set $NODE \
--driver redfish \
--driver-info redfish_address=https://<BMC_IP> \ # e.g. https://192.168.1.100
--driver-info redfish_username=<USERNAME> \ # e.g. ADMIN
--driver-info redfish_password=<PASSWORD> \
--driver-info redfish_system_id=/redfish/v1/Systems/1 \
--driver-info redfish_verify_ca=False \ # Allow self-signed certificates
--bios-interface redfish \
--boot-interface redfish-virtual-media \
--deploy-interface direct \
--inspect-interface agent \
--management-interface redfish \
--power-interface redfish \
--raid-interface agent \
--vendor-interface no-vendor
Note: Use
redfish_verify_ca=False, notredfish_verify_cafile=False.
Using the wrong parameter name will cause SSL certificate errors and put the node into apower failurestate.
6-3. manual-management Driver (VM / Test Environments)
Use this when power control is not needed.
baremetal node set $NODE \
--driver manual-management \
--management-interface noop \
--power-interface fake \
--boot-interface ipxe \
--deploy-interface direct \
--inspect-interface no-inspect \
--vendor-interface no-vendor \
--raid-interface no-raid \
--bios-interface no-bios
6-4. Clearing Maintenance Caused by SSL Errors
# Clear maintenance mode
baremetal node maintenance unset $NODE
# Check power state
baremetal node show $NODE | grep -E "power_state|fault|maintenance"
7. Nginx httpboot Configuration
7-1. File Paths
| Item | Path |
|---|---|
| Ironic httpboot root | /var/lib/ironic/httpboot |
| Nginx config file | /etc/nginx/conf.d/bifrost-httpboot.conf |
7-2. Basic Nginx Configuration
server {
listen 8080;
server_name <SERVER_HOSTNAME>; # e.g. pxeserver
root /var/lib/ironic/httpboot;
location / {
autoindex on;
}
}
After making changes, reload Nginx:
nginx -t && systemctl reload nginx
8. Building a Custom IPA initramfs
The default ipa.initramfs has no user accounts, which makes direct SSH access for troubleshooting impossible.
The two methods below let you build a customized IPA image.
Method A: Build from Scratch with a devuser
Build an IPA image that includes a login-capable account and any additional packages you need.
If you don't have an SSH key yet, generate one first:
ssh-keygen -t rsa -b 4096
Set Environment Variables
export ELEMENTS_PATH=/opt/stack/bifrost/share/ironic-python-agent-builder/dib
export DIB_DEV_USER_USERNAME=<USERNAME> # e.g. ipauser
export DIB_DEV_USER_PASSWORD=<PASSWORD> # e.g. changeme123
export DIB_DEV_USER_PWDLESS_SUDO=yes
export DIB_DEV_USER_AUTHORIZED_KEYS=/root/.ssh/id_rsa.pub
export DIB_RELEASE=jammy
export DIB_DEV_USER_SHELL=/bin/bash
Build
ironic-python-agent-builder \
-o /opt/custom-ipa \
-e devuser \
ubuntu 2>&1 | tee /opt/ipa-build.log
Copy Build Output
cp /opt/custom-ipa.kernel /var/lib/ironic/httpboot/ipa.kernel
cp /opt/custom-ipa.initramfs /var/lib/ironic/httpboot/ipa.initramfs
chmod 644 /var/lib/ironic/httpboot/ipa.*
Method B: Unpack and Modify an Existing initramfs (Repackaging)
Use this when you need changes beyond just adding an account — like modifying services or config files.
Extract
mkdir -p /opt/ipa-custom && cd /opt/ipa-custom
zcat /var/lib/ironic/httpboot/ipa.initramfs | cpio -idmv
Change the root Password
chroot . /bin/bash
passwd root
exit
Enable SSH Access
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' etc/ssh/sshd_config
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' etc/ssh/sshd_config
# If a cloud-img override file exists
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' \
etc/ssh/sshd_config.d/60-cloudimg-settings.conf
Remove Boot Delay
Prevents the long wait caused by the network-online target during ramdisk boot:
rm -f etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service
rm -f etc/systemd/system/network-online.target.wants/ifupdown-wait-online.service
Repackage
cd /opt/ipa-custom
find . | cpio -H newc -o | gzip -9 > /var/lib/ironic/httpboot/ipa.initramfs
chmod 644 /var/lib/ironic/httpboot/ipa.initramfs
9. Building a Deployment Image
9-1. Building a Custom Image with disk-image-create
Cloud images downloaded via wget come with a fixed partition layout that doesn't allow flexible partitioning.
Using disk-image-create gives you full control over partition layout, installed packages, and the bootloader.
Set Environment Variables
# Ubuntu release codename (jammy = 22.04, noble = 24.04)
export DIB_RELEASE=jammy
# Temp directory for the build workspace — make sure there's enough free space
export TMPDIR=/tmp
# Package mirror — using a nearby mirror significantly speeds up the build
export DIB_DISTRIBUTION_MIRROR=http://mirror.kakao.com/ubuntu
# Image size in GiB — set this to the minimum you need for your OS
export DIB_IMAGE_SIZE=10
Partition Layout
Below is a standard 4-partition layout with UEFI boot support.
Adjust size values to suit your environment.
export DIB_BLOCK_DEVICE_CONFIG='
- local_loop:
name: image0
- partitioning:
base: image0
label: gpt
partitions:
- name: esp
type: EF00
size: 512MiB
mkfs:
type: vfat
mount:
mount_point: /boot/efi
fstab:
options: umask=0077
fsck-passno: 1
- name: bios
type: EF02
size: 8MiB
- name: boot
type: 8300
size: 1GiB
mkfs:
type: ext4
mount:
mount_point: /boot
fstab:
options: defaults
fsck-passno: 2
- name: root
type: 8300
size: 100%
mkfs:
type: ext4
mount:
mount_point: /
fstab:
options: defaults
fsck-passno: 1
'
Partition Notes
esp(EF00): UEFI boot partition. Minimum 256MiB, recommended 512MiB.bios(EF02): BIOS compatibility partition. No need to change the size.boot(8300): Mounted at/boot. Increase size if you plan to keep multiple kernels.root(8300): Root partition. Settingsize: 100%uses all remaining space.
Build the Image
disk-image-create \
ubuntu \
bootloader \
grub2 \
block-device-efi \
cloud-init \
growroot \
-p openssh-server,curl,vim,net-tools,htop,mdadm,\
grub-efi-amd64,grub-efi-amd64-signed,shim-signed \
-t qcow2 \
-o /var/lib/ironic/httpboot/ubuntu-22.04-baremetal \
2>&1 | tee /tmp/image-build.log
Elements (build components)
ubuntu: Base Ubuntu OSbootloader: Installs GRUB bootloadergrub2: GRUB2 configurationblock-device-efi: Enables UEFI partition layoutcloud-init: Includes cloud-init for user-data handling at deploy timegrowroot: Automatically expands the root partition on first boot
-ppackages: Add any packages you need, comma-separated.
mdadmis required for SW RAID — remove it if you don't need it.
Verify the Build
ls -lh /var/lib/ironic/httpboot/ubuntu-22.04-baremetal.qcow2
9-2. Patching UEFI Boot Files (If Needed)
If the /boot/efi/EFI/ubuntu path is missing after the build, apply this patch:
guestfish -a /var/lib/ironic/httpboot/ubuntu-22.04-baremetal.qcow2 << 'EOF'
run
mount /dev/sda4 /
mount /dev/sda3 /boot
mount /dev/sda1 /boot/efi
mkdir-p /boot/efi/EFI/ubuntu
mkdir-p /boot/efi/EFI/BOOT
copy-out /usr/lib/shim/shimx64.efi /tmp/
copy-in /tmp/shimx64.efi /boot/efi/EFI/BOOT/BOOTX64.EFI
copy-in /tmp/shimx64.efi /boot/efi/EFI/ubuntu/shimx64.efi
copy-out /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed /tmp/
copy-in /tmp/grubx64.efi.signed /boot/efi/EFI/ubuntu/grubx64.efi
copy-in /tmp/grubx64.efi.signed /boot/efi/EFI/BOOT/grubx64.efi
write /boot/efi/EFI/ubuntu/grub.cfg \
"search --no-floppy --label --set=root mkfs_boot\nset prefix=(\$root)/grub\nconfigfile \$prefix/grub.cfg\n"
write /boot/efi/EFI/BOOT/grub.cfg \
"search --no-floppy --label --set=root mkfs_boot\nset prefix=(\$root)/grub\nconfigfile \$prefix/grub.cfg\n"
sh "sed -i 's|search --no-floppy --fs-uuid --set=root.*|search --no-floppy --label --set=root mkfs_boot|g' /boot/grub/grub.cfg"
EOF
Partition number warning: The device numbers (
/dev/sda1,/dev/sda3,/dev/sda4) may differ depending on your build environment.
Always check your actual partition layout first:guestfish -a <image_path> run : list-filesystems
9-3. Further Customization with virt-customize
Apply additional configuration to the image after the build completes:
virt-customize -a /var/lib/ironic/httpboot/ubuntu-22.04-baremetal.qcow2 \
--root-password password:<ROOT_PASSWORD> \
--ssh-inject root:file:/root/.ssh/id_rsa.pub \
--run-command 'echo "PermitRootLogin yes" >> /etc/ssh/sshd_config' \
--run-command 'echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config' \
--run-command 'ssh-keygen -A' \
--run-command 'systemctl disable systemd-networkd-wait-online.service' \
--run-command 'systemctl mask systemd-networkd-wait-online.service' \
--run-command 'echo "network: {config: disabled}" > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg' \
--run-command 'cloud-init clean --logs --seed'
virt-customize Option Reference
Accounts / Passwords
--root-password password:<PASSWORD>
--password <USERNAME>:password:<PASSWORD>
SSH
--ssh-inject root:file:/root/.ssh/id_rsa.pub
--ssh-inject <USERNAME>:string:"ssh-rsa AAAA..."
File Operations
--upload /local/file:/remote/path
--write '/etc/hosts:127.0.0.1 myhost'
--delete /path/to/file
--mkdir /new/directory
Running Commands
--run-command 'apt-get install -y nginx'
--firstboot /path/to/script.sh # Run script on first boot
--firstboot-command 'systemctl start app'
Packages
--install nginx,curl,vim
--uninstall apache2
--update
System
--hostname <HOSTNAME>
--timezone Asia/Seoul
--truncate /path/to/file
9-4. Generating a SHA256 Checksum
sha256sum /var/lib/ironic/httpboot/ubuntu-22.04-baremetal.qcow2 \
> /var/lib/ironic/httpboot/ubuntu-22.04-baremetal.qcow2.sha256
cat /var/lib/ironic/httpboot/ubuntu-22.04-baremetal.qcow2.sha256
9-5. Preparing the cloud-init config-drive
user-data.yaml Example
A standard cloud-init configuration:
#cloud-config
# Hostname
hostname: baremetal-node-01
# User accounts
users:
- name: admin
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: false
# Generate with: openssl passwd -6 <password>
passwd: "$6$rounds=4096$saltsalt$hashedpassword..."
ssh_authorized_keys:
- ssh-rsa AAAA...your-public-key...
# Allow SSH password authentication
ssh_pwauth: true
# Package updates and installs
package_update: true
package_upgrade: true
packages:
- curl
- vim
- htop
- net-tools
- tmux
# Network configuration (netplan)
write_files:
- path: /etc/netplan/99-baremetal.yaml
permissions: '0600'
content: |
network:
version: 2
ethernets:
enp1s0:
dhcp4: true
enp2s0:
dhcp4: false
addresses:
- 192.168.240.100/24
# Commands to run after boot
runcmd:
- netplan apply
- systemctl restart ssh
- echo "Provisioning complete: $(date)" >> /var/log/provision.log
Generating a password hash:
openssl passwd -6 <your_password>
config-drive via Directory
mkdir -p /opt/configdrive/openstack/latest
cp user-data.yaml /opt/configdrive/openstack/latest/user_data
echo '{"uuid": "<NODE_UUID>"}' > /opt/configdrive/openstack/latest/meta_data.json
config-drive via Inline JSON
Encode user-data as JSON and set it directly on the node — no separate files needed:
python3 << 'EOF'
import json
with open('/var/lib/ironic/httpboot/user-data.yaml') as f:
userdata = f.read()
with open('/tmp/configdrive.json', 'w') as out:
json.dump({'user_data': userdata}, out)
EOF
baremetal node set $NODE \
--instance-info configdrive="$(cat /tmp/configdrive.json)"
10. Deploying a Node
10-1. Confirming Node Registration
When a baremetal server PXE boots, it registers with Ironic automatically:
baremetal node list
# provision_state should show: enroll
10-2. Transitioning to manageable
NODE=<NODE_UUID>
baremetal node manage $NODE
manual-managementdriver: transitions tomanageableimmediatelyipmi/redfishdrivers: verifies BMC connectivity first, then transitions tomanageable
10-3. Controlling automated clean
Running provide will trigger automated cleaning if automated_clean = True is set in /etc/ironic/ironic.conf.
Skip cleaning and go straight to available (per-node)
baremetal node set $NODE --no-automated-clean
baremetal node provide $NODE
Re-enable cleaning for a node
baremetal node set $NODE --automated-clean
Disable globally (applies to all nodes)
# /etc/ironic/ironic.conf
[conductor]
automated_clean = False
systemctl restart ironic
10-4. Transitioning to available
baremetal node provide $NODE
10-5. Setting Image Info on the Node
CONTROLLER_IP=<CONTROLLER_IP> # e.g. 192.168.240.1
IMAGE_NAME=ubuntu-22.04-baremetal
baremetal node set $NODE \
--instance-info image_source=http://${CONTROLLER_IP}:8080/${IMAGE_NAME}.qcow2 \
--instance-info image_os_hash_algo=sha256 \
--instance-info image_os_hash_value=$(curl -s http://${CONTROLLER_IP}:8080/${IMAGE_NAME}.qcow2.sha256 | awk '{print $1}')
10-6. Starting Deployment
Method A: config-drive from directory
baremetal node deploy $NODE --config-drive /opt/configdrive/
Method B: config-drive via inline JSON
Encode and set user-data without needing separate files:
python3 << 'EOF'
import json
with open('/var/lib/ironic/httpboot/user-data.yaml') as f:
userdata = f.read()
with open('/tmp/configdrive.json', 'w') as out:
json.dump({'user_data': userdata}, out)
EOF
baremetal node set $NODE \
--instance-info configdrive="$(cat /tmp/configdrive.json)"
baremetal node deploy $NODE
10-7. Monitoring Deployment Status
# Watch status in real time
watch -n2 "baremetal node list 2>/dev/null"
State flow during deployment:
available → deploying → wait call-back → active
Once the node reaches active, deployment is complete. Nodes registered via IPMI or Redfish will automatically reboot from local disk after deployment.
11. SW RAID Setup and Teardown
11-1. Writing the RAID Config File
The example below sets up RAID 1 (mirroring):
cat > /opt/sw-raid-config.json << 'EOF'
{
"logical_disks": [
{
"size_gb": "MAX",
"raid_level": "1",
"controller": "software",
"is_root_volume": true
}
]
}
EOF
raid_level options:
0(striping),1(mirroring),5(parity),10(mirrored striping)
11-2. Applying the RAID Config
Run this while the node is in manageable state:
baremetal node set $NODE --raid-interface agent
baremetal node set $NODE --target-raid-config /opt/sw-raid-config.json
11-3. Creating the RAID via a Clean Step
baremetal node clean $NODE \
--clean-steps '[
{"interface": "deploy", "step": "erase_devices_metadata"},
{"interface": "raid", "step": "create_configuration"}
]'
After cleaning completes, SSH into the server to verify:
cat /proc/mdstat
mdadm --detail /dev/md0
11-4. Tearing Down RAID
Removes the RAID and returns disks to a clean state. Run from
manageablestate.
Removing the RAID along with disk metadata prevents conflicts on the next deployment:
baremetal node clean $NODE \
--clean-steps '[
{"interface": "raid", "step": "delete_configuration"},
{"interface": "deploy", "step": "erase_devices_metadata"}
]'
To fully reset the RAID interface on the node:
baremetal node set $NODE --raid-interface no-raid
12. Undeploying a Node
12-1. Undeploy
baremetal node undeploy $NODE
The node transitions through: active → cleaning → available.
During cleaning, the node reboots into the ramdisk and wipes disk metadata.
Note for RAID-configured nodes: Do not undeploy directly. First boot into the ramdisk and run the
delete_configurationclean step, then undeploy.
Skipping this step can cause partition conflicts on the next deployment.
12-2. Manual Clean
baremetal node clean $NODE \
--clean-steps '[{"interface": "deploy", "step": "erase_devices_metadata"}]'
12-3. Deleting a Node
To completely remove a node, run from manageable state:
# Transition to manageable first
baremetal node manage $NODE
# Delete
baremetal node delete $NODE
13. Appendix
13-1. Node State Transition Summary
| Current State | Command | Next State |
|---|---|---|
enroll |
baremetal node manage |
manageable |
manageable |
baremetal node provide |
available (after clean) |
manageable |
baremetal node provide (no-automated-clean) |
available (immediately) |
available |
baremetal node deploy |
deploying → active |
active |
baremetal node undeploy |
cleaning → available |
any |
baremetal node maintenance set |
maintenance |
maintenance |
baremetal node maintenance unset |
previous state |
manageable |
baremetal node delete |
(deleted) |
clean failed |
baremetal node manage → baremetal node provide |
manageable → available |
13-2. Power Control After Cleaning
By default, Ironic powers off the node after clean or inspect completes. To prevent this, configure it per node:
# Keep power ON after clean completes
baremetal node set $NODE --disable-power-off
# Revert to default behavior
baremetal node set $NODE --enable-power-off
To detect when cleaning is done and automatically trigger a next step, you can use this script:
#!/bin/bash
NODE=$1
TARGET_STATE=${2:-available}
echo "Monitoring state changes for node $NODE..."
while true; do
STATE=$(baremetal node show $NODE -f value -c provision_state 2>/dev/null)
POWER=$(baremetal node show $NODE -f value -c power_state 2>/dev/null)
echo "$(date '+%H:%M:%S') state=$STATE power=$POWER"
if [ "$STATE" = "$TARGET_STATE" ]; then
echo "Target state reached: $TARGET_STATE"
break
elif [[ "$STATE" == *"failed"* ]]; then
echo "Error detected: $STATE"
exit 1
fi
sleep 5
done
13-3. Troubleshooting
baremetal command returns 401 Unauthorized
grep auth_strategy /etc/ironic/ironic.conf
# If not noauth, fix it:
sed -i 's/auth_strategy = .*/auth_strategy = noauth/' /etc/ironic/ironic.conf
systemctl restart ironic
Recovering from clean failed
baremetal node maintenance unset $NODE
baremetal node manage $NODE
baremetal node provide $NODE
power failure / Redfish SSL error
# Re-set redfish_verify_ca=False
baremetal node set $NODE --driver-info redfish_verify_ca=False
# Remove the incorrect parameter if it was set
baremetal node unset $NODE --driver-info redfish_verify_cafile
baremetal node maintenance unset $NODE
No IP assigned after PXE boot
# Check dnsmasq logs
journalctl -u dnsmasq -f
# Verify DHCP Discover packets are reaching the interface
tcpdump -i <PXE_INTERFACE> port 67 or port 68 -n
Node stuck in enroll and not registering
# Check Inspector status
systemctl status ironic-inspector
journalctl -u ironic-inspector -f
# Verify Inspector port is listening
ss -tlnp | grep 5050
13-4. Key Paths and Files
| Item | Path |
|---|---|
| Ironic config | /etc/ironic/ironic.conf |
| dnsmasq config | /etc/dnsmasq.conf, /etc/dnsmasq.d/ |
| httpboot root | /var/lib/ironic/httpboot/ |
| Deploy kernel / ramdisk | /var/lib/ironic/httpboot/ipa.kernel, ipa.initramfs |
| Deploy logs | /var/log/ironic/deploy/ |
| DHCP host config | /etc/dnsmasq.d/bifrost.dhcp-hosts.d/ |
| DHCP options config | /etc/dnsmasq.d/bifrost.dhcp-opts.d/ |
| clouds.yaml | ~/.config/openstack/clouds.yaml |