diff --git a/ansible/group_vars/all/ipa b/ansible/group_vars/all/ipa
index 3d42284950038aa6838710dd533a9cb03170b5a2..d17cac11a8d3bc0c4a9a3791069e8e60ac0dda61 100644
--- a/ansible/group_vars/all/ipa
+++ b/ansible/group_vars/all/ipa
@@ -56,6 +56,9 @@ ipa_build_dib_env: >
 # stackhpc.os-images role for usage.
 ipa_build_dib_git_elements: []
 
+# List of DIB packages to install. Default is none.
+ipa_build_dib_packages: []
+
 ###############################################################################
 # Ironic Python Agent (IPA) images configuration.
 
diff --git a/ansible/overcloud-ipa-build.yml b/ansible/overcloud-ipa-build.yml
index 3b7a51399e96963f906346ad64c48b40f9746169..aa3c199465f3a101d170bb55f95435eb0a8c3310 100644
--- a/ansible/overcloud-ipa-build.yml
+++ b/ansible/overcloud-ipa-build.yml
@@ -36,6 +36,7 @@
               - name: "{{ ipa_image_name }}"
                 elements: "{{ ipa_build_dib_elements }}"
                 env: "{{ ipa_build_dib_env }}"
+                packages: "{{ ipa_build_dib_packages }}"
                 # Avoid needing to install qemu-img for qcow2 image.
                 type: raw
             os_images_git_elements: "{{ ipa_build_dib_git_elements }}"
diff --git a/ansible/seed-ipa-build.yml b/ansible/seed-ipa-build.yml
index f1afb808e4dd93d375184af26d105a5f929e9101..1e2e0e413838daa5e4e21d28b71c9c75a981f40b 100644
--- a/ansible/seed-ipa-build.yml
+++ b/ansible/seed-ipa-build.yml
@@ -27,6 +27,7 @@
               - name: "{{ ipa_image_name }}"
                 elements: "{{ ipa_build_dib_elements }}"
                 env: "{{ ipa_build_dib_env }}"
+                packages: "{{ ipa_build_dib_packages }}"
                 # Avoid needing to install qemu-img for qcow2 image.
                 type: raw
             os_images_git_elements: "{{ ipa_build_dib_git_elements }}"
diff --git a/doc/source/configuration/bifrost.rst b/doc/source/configuration/bifrost.rst
index c24b2e50e16276481c789b6365c8ce7cf2145a9b..a8673a7160fdf303360a620c73b622f3b8c0ac2d 100644
--- a/doc/source/configuration/bifrost.rst
+++ b/doc/source/configuration/bifrost.rst
@@ -167,6 +167,20 @@ Alternatively, the :diskimage-builder-doc:`dynamic-login element
 <elements/dynamic-login/README>` can be used to authorize SSH keys by appending
 them to the kernel arguments.
 
+Example: Installing a package
+-----------------------------
+
+It can be necessary to install additional packages in the root disk image.
+Rather than needing to write a custom DIB element, we can use the
+``kolla_bifrost_dib_packages`` variable. For example, to install the
+``biosdevname`` package:
+
+.. code-block:: yaml
+   :caption: ``ipa.yml``
+
+   kolla_bifrost_dib_packages:
+     - "biosdevname"
+
 Ironic configuration
 ====================
 
diff --git a/doc/source/configuration/ironic-python-agent.rst b/doc/source/configuration/ironic-python-agent.rst
index 74c8c4cefca3d2d6f8e5e201382db6325b67af5b..c79b941899ec8420ee43cffd37de2531d1e7f756 100644
--- a/doc/source/configuration/ironic-python-agent.rst
+++ b/doc/source/configuration/ironic-python-agent.rst
@@ -66,6 +66,8 @@ image build``.
     List of git repositories containing Diskimage Builder (DIB) elements. See
     `stackhpc.os-images <https://galaxy.ansible.com/stackhpc/os-images>`__ role
     for usage. Default is none.
+``ipa_build_dib_packages``
+    List of DIB packages to install. Default is none.
 
 Example: Building IPA images locally
 ------------------------------------
@@ -156,6 +158,20 @@ In this example the ``master`` branch of
 https://git.example.com/custom-dib-elements would have a top level ``elements``
 directory, containing a ``my-element`` directory for the element.
 
+Example: Installing a package
+-----------------------------
+
+It can be necessary to install additional packages in the IPA image. Rather
+than needing to write a custom DIB element, we can use the
+``ipa_build_dib_packages`` variable. For example, to install the
+``biosdevname`` package:
+
+.. code-block:: yaml
+   :caption: ``ipa.yml``
+
+   ipa_build_dib_packages:
+     - "biosdevname"
+
 Ironic Python Agent (IPA) images configuration
 ==============================================
 
diff --git a/etc/kayobe/ipa.yml b/etc/kayobe/ipa.yml
index 63b0499d2ab9bea75dd29eac7c579c14f24f0ce6..e91ac57a01622335646d072a33840b3b4e5cf75d 100644
--- a/etc/kayobe/ipa.yml
+++ b/etc/kayobe/ipa.yml
@@ -47,6 +47,9 @@
 # stackhpc.os-images role for usage.
 #ipa_build_dib_git_elements:
 
+# List of DIB packages to install. Default is none.
+#ipa_build_dib_packages:
+
 ###############################################################################
 # Ironic Python Agent (IPA) images configuration.
 
diff --git a/releasenotes/notes/ipa-build-dib-packages-5e85baba3294eb65.yaml b/releasenotes/notes/ipa-build-dib-packages-5e85baba3294eb65.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..02ef4ea3f1222b7634c9d15a9a2c099e4a89b5f6
--- /dev/null
+++ b/releasenotes/notes/ipa-build-dib-packages-5e85baba3294eb65.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Adds support for installing packages in locally built Ironic Python Agent
+    (IPA) images via the ``ipa_build_dib_packages`` variable. See `story
+    2006855 <https://storyboard.openstack.org/#!/story/2006855>`__ for details.
diff --git a/requirements.yml b/requirements.yml
index fc75de49f0d77080cd41b267db168dd355f923ba..5b2d7642570dccf8309c37839a11c62d1b4020f1 100644
--- a/requirements.yml
+++ b/requirements.yml
@@ -30,7 +30,7 @@
 - src: stackhpc.mellanox-switch
   version: v1.0.0
 - src: stackhpc.os-images
-  version: v1.4.0
+  version: v1.6.0
 - src: stackhpc.os-ironic-state
   version: v1.1.0
 - src: stackhpc.os-networks