Installation
https://docs.openstack.org/bifrost/latest/install/index.html
Documentation
https://docs.openstack.org/bifrost/latest/user/howto.html
Ironic Ansible module
https://docs.openstack.org/ironic/latest/admin/drivers/ansible.html
https://docs.openstack.org/ironic/latest/configuration/config.html#ansible
Manual deployment
# cleanup disk umount /dev/mapper/system-* /dev/disk/by-label/ESP vgchange -an wipefs -a /dev/nvme0n1 # create inventory cat /tmp/inventory.txt node1 cd /opt/openstack-prepare-baremetal/ironic-staging-driver-ansible/playbooks cat <<EOF> deploy_node_debug.yaml --- - hosts: all become: yes roles: - deploy_node EOF # run playbook su ironic - cd /opt/openstack-prepare-baremetal/ironic-staging-driver-ansible/playbooks ansible-playbook deploy_node_debug.yaml -i /tmp/inventory.txt
Debug
source /opt/stack/bifrost/env-vars ironic node-show ${NODE} Asynchronous exception for node 00000000-0000-0000-0000-AC1F6B0EF226: Node failed to deploy. Exception: Failed to deploy instance: Unexpected error while running command. Command: env ANSIBLE_CONFIG=/usr/local/lib/python2.7/dist-packages/ironic_staging_drivers/ansible/playbooks/ansible.cfg ansible-playbook /opt/openstack-prepare-baremetal/ironic-staging-driver-ansible/playbooks/deploy_node.yaml -i /usr/local/lib/python2.7/dist-packages/ironic_staging_drivers/ansible/playbooks/inventory -e { "ironic": {"nodes": [{"ip": "10.11.12.13", "extra": { "prov_ip": null, "root_disk": "/dev/sda"}, "user": "ansible", "name": "00000000-0000-0000-0000-AC1F6B0EF226"}], "image": {"mem_req": 407, "validate_certs": "yes", "url": "http://10.33.33.40:8080/httpboot/img-bionic-minimal.tgz", "checksum": "md5:a50dc06157e4c7dd773389e4717323d5", "disk_format": "tgz", "source": "http://10.33.33.40:8080/httpboot/img-bionic-minimal.tgz", "type": "whole-disk-image"}, "configdrive": {"type": "url", "location": "http://10.11.12.40:8080/configdrive-00000000-0000-0000-0000-AC1F6B0EF226.iso.gz"}}} --skip-tags=wait # cat /usr/local/lib/python2.7/dist-packages/ironic_staging_drivers/ansible/playbooks/ansible.cfg [ssh_connection] retries=1000
Log
/var/log/ansible.log
Delete node
ironic node-set-provision-state ${NODE} deleted ironic node-set-maintenance ${NODE} on ironic node-delete ${NODE}
States diagram
https://docs.openstack.org/ironic/latest/_images/states.svg
Rebuild Bifrost PXE boot image
# gzip compressed data zcat /tmp/ironic-python-agent.initramfs | cpio -idmv # xz xzcat /httpboot/ansible_ubuntu.initramfs | cpio -idmv # apply changes cat <<EOF> ./etc/netplan/dhcp-all-nic.yaml network: version: 2 renderer: networkd ethernets: all: match: macaddress: * dhcp4: yes EOF cp /usr/local/sbin/dhcp-all-interfaces.sh{,.org} cat <<EOF> ./usr/local/sbin/dhcp-all-interfaces.sh #!/bin/bash BOOTIF=$(cat /proc/cmdline | sed -e 's/^.*BOOTIF=//' -e 's/ .*$//') sed -i "s/macaddress: \*/macaddress: ${BOOTIF}/g" /etc/netplan/dhcp-all-nic.yaml netplan apply /bin/ping -W 10 -c 10 8.8.8.8 exit 0 EOF mv /httpboot/ansible_ubuntu.initramfs /httpboot/ansible_ubuntu.initramfs.$(date -I) find ./ | cpio -H newc -o | xz -9 --format=lzma > /httpboot/ansible_ubuntu.initramfs # gzip find ./ | cpio -H newc -o | gzip --best > /httpboot/ansible_ubuntu.initramfs # parallel compress test (broken) # apt-get install pxz # find ./ | cpio -H newc -o | pxz -9 --format=lzma > /httpboot/ansible_ubuntu.initramfs
Rebuild / Change image
cd /tmp/img-bionic-minimal tar czf /httpboot/img-bionic-minimal.tgz .
Undeploy node
NODE_UUID=$(openstack baremetal node list -c UUID -f value) openstack baremetal node undeploy ${NODE_UUID} openstack baremetal node maintenance set ${NODE_UUID} openstack baremetal node delete ${NODE_UUID} # list available nodes openstack baremetal node list
Power on all nodes
openstack baremetal node list -c UUID -f value | xargs -L1 openstack baremetal node power on
Ironic Ansible deployment
https://docs.openstack.org/ironic/queens/admin/drivers/ansible.html
https://docs.openstack.org/ironic/queens/configuration/config.html#ansible
https://docs.openstack.org/ironic/ussuri/admin/interfaces/deploy.html
Ironic Virtual media (ISO) deployment
https://docs.openstack.org/ironic/latest/admin/ramdisk-boot.html
Ironic manual deployment
ssh ironic.dev.i.example.com source /opt/stack/bifrost/bin/activate export OS_CLOUD=bifrost HOST_NAME=ctl1-dev HOST_MAC=00:11:22:33:44:55 env ANSIBLE_CONFIG=/opt/openstack-ironic/playbooks/ansible.cfg \ ansible-playbook /opt/openstack-ironic/playbooks/deploy.yaml \ -i /opt/openstack-ironic/playbooks/inventory \ --private-key=/etc/ironic/id_rsa \ -e "{ 'ironic':{ 'nodes':[ { 'ip':'${HOST_NAME}', 'extra':{ 'hostname':'${HOST_NAME}', 'bootif':'${HOST_MAC}' }, 'user':'root', 'name':'ironic-manual-prov' } ], 'image':{ 'source':'http://ironic.dev.i.example.com:8080/img-focal-minimal.tgz', 'url':'http://ironic.dev.i.example.com:8080/img-focal-minimal.tgz', 'type':'whole-disk-image', 'mem_req':512, 'validate_certs':'yes' } } }" \ -e "{'pre_deploy_wait_minutes':0}" \ -vvv
Links
https://www.mirantis.com/blog/automate-bare-metal-server-provisioning-using-ironic-bifrost-and-the-ansible-deploy-driver/
http://dtantsur.github.io/talks/fosdem2016/
https://docs.openstack.org/bifrost/latest/install/index.html
https://specs.openstack.org/openstack/tripleo-specs/specs/pike/tripleo-routed-networks-ironic-inspector.html
https://docs.openstack.org/ironic/latest/user/index.html