====== How-To ====== .. _baremetal-cli: Use the baremetal CLI ===================== If you wish to utilize the baremetal CLI in no-auth mode, there are two options for configuring the authentication parameters. clouds.yaml ----------- During installation, Bifrost creates a ``clouds.yaml`` file with credentials necessary to access Ironic. A cloud called ``bifrost`` is always available. For example: .. code-block:: bash export OS_CLOUD=bifrost baremetal node list baremetal introspection list .. note:: Previously, a separate cloud ``bifrost-inspector`` was provided for introspection commands. It is now deprecated, the main ``bifrost`` cloud should always be used. Environment variables --------------------- For convenience, an environment file called ``openrc`` is created in the home directory of the current user that contains default values for these variables and can be sourced to allow the CLI to connect to a local Ironic installation. For example: .. code-block:: bash . ~/openrc bifrost baremetal node list This should display a table of nodes, or nothing if there are no nodes registered in Ironic. Installing OpenStack CLI ------------------------ Starting with the Victoria release, the ``openstack`` command is only installed when Keystone is enabled. Install the ``python-openstackclient`` Python package to get this command. Inventory file format ===================== In order to enroll hardware, you will naturally need an inventory of your hardware. When utilizing the dynamic inventory module and accompanying roles the inventory can be supplied in one of three ways, all of which ultimately translate to JSON data that Ansible parses. The current method is to utilize a JSON or YAML document which the inventory parser will convert and provide to Ansible. The JSON format resembles the data structure that ironic utilizes internally. * The ``name``, ``uuid``, ``driver``, and ``properties`` fields are directly mapped through to ironic. Only the ``driver`` is required. .. note:: Most properties are automatically populated during inspection, if it is enabled. However, it is recommended to set the `root device `_ for nodes with multiple disks. * The ``driver_info`` field format matches one of the OpenStack Ansible collection and for legacy reasons can use nested structures ``power``, ``deploy``, ``management`` and ``console``. .. note:: With newer versions of the collection you should just put all fields under ``driver_info`` directly). * The ``nics`` field is a list of ports to create. The required field is ``mac`` - MAC address of the port. Example: .. code-block:: json { "testvm1": { "name": "testvm1", "driver": "ipmi", "driver_info": { "ipmi_address": "192.168.122.1", "ipmi_username": "admin", "ipmi_password": "pa$$w0rd" }, "nics": [ { "mac": "52:54:00:f9:32:f6" } ], "properties": { "cpu_arch": "x86_64", "root_device": {"wwn": "0x4000cca77fc4dba1"} } } } Overriding instance information ------------------------------- The additional power of this format is easy configuration parameter injection, which could potentially allow a user to provision different operating system images onto different hardware chassis by defining the appropriate settings in an ``instance_info`` variable, for example: .. code-block:: json { "testvm1": { "uuid": "00000000-0000-0000-0000-000000000001", "name": "testvm1", "driver": "redfish", "driver_info": { "redfish_address": "https://bmc.myhost.com", "redfish_system_id": "/redfish/v1/Systems/11", "redfish_username": "admin" "redfish_password": "pa$$w0rd", }, "nics": [ { "mac": "52:54:00:f9:32:f6" } ], "properties": { "cpu_arch": "x86_64", "root_device": {"wwn": "0x4000cca77fc4dba1"} }, "instance_info": { "image_source": "http://image.server/image.qcow2", "image_checksum": "", "configdrive": { "meta_data": { "public_keys": {"0": "ssh-rsa ..."}, "hostname": "vm1.example.com" } } } } } The ``instance_info`` format is documented in the `Ironic deploy guide `_. The ability to populate ``configdrive`` this way is a Bifrost-specific feature, but the ``configdrive`` itself follows the Ironic format. Examples utilizing JSON and YAML formatting, along host specific variable injection can be found in the ``playbooks/inventory/`` folder. Static network configuration ---------------------------- When building a configdrive, Bifrost can embed static networking configuration in it. This configuration will be applied by the first-boot service, such as cloud-init_ or glean_. The following fields can be set: ``ipv4_address`` The IPv4 address of the node. If missing, the configuration is not provided in the configdrive. When ``ipv4_address`` is set, it's also used as the default for ``ansible_ssh_host``. Because of this, you can run SSH commands against deployed hosts, as long as you use the Bifrost's inventory plugin. This parameter can also used for :doc:`DHCP configuration `. ``ipv4_subnet_mask`` The subnet mask of the IP address. Defaults to `255.255.255.0`. ``ipv4_interface_mac`` MAC address of the interface to configure. If missing, the MAC address of the first NIC defined in the inventory is used. ``ipv4_gateway`` IPv4 address of the default router. A default value is only provided for testing case. ``ipv4_nameserver`` The server to use for name resolution (a string or a list). ``network_mtu`` MTU to use for the link. For example: .. code-block:: json { "testvm1": { "name": "testvm1", "driver": "redfish", "driver_info": { "redfish_address": "https://bmc.myhost.com", "redfish_system_id": "/redfish/v1/Systems/11", "redfish_username": "admin" "redfish_password": "pa$$w0rd", }, "ipv4_address": "192.168.122.42", "ipv4_subnet_mask": "255.255.255.0", "ipv4_gateway": "192.168.122.1", "ipv4_nameserver": "8.8.8.8", "nics": [ { "mac": "52:54:00:f9:32:f6" } ], "properties": { "cpu_arch": "x86_64", "root_device": {"wwn": "0x4000cca77fc4dba1"} } } } .. warning:: Static network configuration only works this way if you let Bifrost generate the configdrive. .. _enroll: Enroll Hardware =============== Starting with the Wallaby cycle, you can use ``bifrost-cli`` for enrolling: .. code-block:: bash ./bifrost-cli enroll /tmp/baremetal.json Note that enrollment is a one-time operation. The Ansible module *does not* synchronize data for existing nodes. You should use the ironic CLI to do this manually at the moment. Additionally, it is important to note that the playbooks for enrollment are split into three separate playbooks based on the ``ipmi_bridging`` setting. .. _deploy: Deploy Hardware =============== After the nodes are enrolled, they can be deployed upon. Bifrost is geared to utilize configuration drives to convey basic configuration information to the each host. This configuration information includes an SSH key to allow a user to login to the system. Starting with the Yoga cycle, you can use ``bifrost-cli`` for deploying. If you used ``bifrost-cli`` for installation, you should pass its environment variables, as well as the inventory file (see `Inventory file format`_): .. code-block:: bash ./bifrost-cli deploy /tmp/baremetal.json \ -e @baremetal-install-env.json .. note:: By default, the playbook will return once the deploy has started. Pass the ``--wait`` flag to wait for completion. The inventory file may override some deploy settings, such as images or even the complete ``instance_info``, per node. If you omit it, all nodes from Ironic will be deployed using the Bifrost defaults: .. code-block:: bash ./bifrost-cli deploy -e @baremetal-install-env.json Command line parameters ----------------------- By default the playbooks use the image, downloaded or built during installation. You can also use a custom image: .. code-block:: bash ./bifrost-cli deploy -e @baremetal-install-env.json \ --image http://example.com/images/my-image.qcow2 \ --image-checksum 91ebfb80743bb98c59f787c9dc1f3cef \ You can also provide a custom configdrive URL (or its content) instead of the one Bifrost builds for you: .. code-block:: bash ./bifrost-cli deploy -e @baremetal-install-env.json \ --config-drive '{"meta_data": {"public_keys": {"0": "'"$(cat ~/.ssh/id_rsa.pub)"'"}}}' \ File images do not require a checksum: .. code-block:: bash ./bifrost-cli deploy -e @baremetal-install-env.json \ --image file:///var/lib/ironic/custom-image.qcow2 .. note:: Files must be readable by Ironic. Your home directory is often not. Partition images can de deployed by specifying an image type: .. code-block:: bash ./bifrost-cli deploy -e @baremetal-install-env.json \ --image http://example.com/images/my-image.qcow2 \ --image-checksum 91ebfb80743bb98c59f787c9dc1f3cef \ --partition .. note:: The default root partition size is 10 GiB. Set the ``deploy_root_gb`` parameter to override or use a first-boot service such as cloud-init to grow the root partition automatically. Redeploy Hardware ================= If the hosts need to be re-deployed, the dynamic redeploy playbook may be used: .. code-block:: bash export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.json cd playbooks ansible-playbook -vvvv -i inventory/bifrost_inventory.py redeploy-dynamic.yaml This playbook will undeploy the hosts, followed by a deployment, allowing a configurable timeout for the hosts to transition in each step. Use playbooks instead of bifrost-cli ==================================== Using playbooks directly allows you full control over what is executed by Bifrost, with what variables and using what inventory. Utilizing the dynamic inventory module, enrollment is as simple as setting the ``BIFROST_INVENTORY_SOURCE`` environment variable to your inventory data source, and then executing the enrollment playbook: .. code-block:: bash export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.json cd playbooks ansible-playbook -vvvv -i inventory/bifrost_inventory.py enroll-dynamic.yaml To utilize the dynamic inventory based deployment: .. code-block:: bash export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.json cd playbooks ansible-playbook -vvvv -i inventory/bifrost_inventory.py deploy-dynamic.yaml If you used ``bifrost-cli`` for installation, you should pass its environment variables: .. code-block:: bash export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.json cd playbooks ansible-playbook -vvvv \ -i inventory/bifrost_inventory.py \ -e @../baremetal-install-env.json \ deploy-dynamic.yaml Deployment and configuration of operating systems ================================================= By default, Bifrost deploys a configuration drive which includes the user SSH public key, hostname, and the network configuration in the form of network_data.json that can be read/parsed by `glean `_ or `cloud-init `_. This allows for the deployment of Ubuntu, CentOS, or Fedora "tenants" on baremetal. By default, Bifrost utilizes a utility called *simple-init* which leverages the previously noted glean utility to apply network configuration. This means that by default, root file systems may not be automatically expanded to consume the entire disk, which may, or may not be desirable depending upon operational needs. This is dependent upon what base OS image you utilize, and if the support is included in that image or not. At present, the standard Ubuntu cloud image includes cloud-init which will grow the root partition, however the ubuntu-minimal image does not include cloud-init and thus will not automatically grow the root partition. Due to the nature of the design, it would be relatively easy for a user to import automatic growth or reconfiguration steps either in the image to be deployed, or in post-deployment steps via custom Ansible playbooks. To be able to access nodes via SSH, ensure that the value for `ssh_public_key_path` in ``./playbooks/inventory/group_vars/baremetal`` refers to a valid public key file, or set the ``ssh_public_key_path`` variable on the command line, e.g. ``-e ssh_public_key_path=~/.ssh/id_rsa.pub``. Advanced topics =============== Using a remote ironic --------------------- When ironic is installed on remote server, a regular ansible inventory with a target server should be added to ansible. This can be achieved by specifying a directory with files, each file in that directory will be part of the ansible inventory. Refer to ansible documentation http://docs.ansible.com/ansible/intro_dynamic_inventory.html#using-inventory-directories-and-multiple-inventory-sources. Example: .. code-block:: bash export BIFROST_INVENTORY_SOURCE=/tmp/baremetal.json cd playbooks rm inventory/*.example ansible-playbook -vvvv -i inventory/ enroll-dynamic.yaml Build Custom Ironic Python Agent (IPA) images --------------------------------------------- Content moved, see :ref:`custom-ipa-images`. Configuring the integrated DHCP server -------------------------------------- Content moved, see :doc:`dhcp`. Use Bifrost with Keystone ------------------------- Content moved, see :doc:`keystone`.