diff --git a/ansible/baremetal-compute-inspect.yml b/ansible/baremetal-compute-inspect.yml
index 2f70d1d32..0425c3cf6 100644
--- a/ansible/baremetal-compute-inspect.yml
+++ b/ansible/baremetal-compute-inspect.yml
@@ -3,20 +3,20 @@
 # baremetal-compute ansible group are inspected. The nodes should be in the
 # 'manageable' state.
 
-# We install shade in a virtualenv on one of the controllers, and delegate to
+# We install openstacksdk in a virtualenv on one of the controllers, and delegate to
 # it when executing the stackhpc.os-ironic-state role.
 
 - name: Ensure dependencies are installed and the virtual environment is activated
   hosts: controllers[0]
   gather_facts: true
   vars:
-    venv: "{{ virtualenv_path }}/shade"
+    venv: "{{ virtualenv_path }}/openstacksdk"
   roles:
-    - role: stackhpc.os-shade
-      os_shade_venv: "{{ venv }}"
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      os_shade_upper_constraints_file: "{{ pip_upper_constraints_file }}"
+    - role: stackhpc.os_openstacksdk
+      os_openstacksdk_venv: "{{ venv }}"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      os_openstacksdk_upper_constraints_file: "{{ pip_upper_constraints_file }}"
 
     - role: activate-virtualenv
       activate_virtualenv_path: "{{ venv }}"
diff --git a/ansible/baremetal-compute-manage.yml b/ansible/baremetal-compute-manage.yml
index 5668a2c58..43c19dc1c 100644
--- a/ansible/baremetal-compute-manage.yml
+++ b/ansible/baremetal-compute-manage.yml
@@ -3,20 +3,20 @@
 # ironic inventory are manageable. Supported initial states include 'enroll',
 # 'manageable', and 'available'.
 
-# We install shade in a virtualenv on one of the controllers, and delegate to
+# We install openstacksdk in a virtualenv on one of the controllers, and delegate to
 # it when executing the stackhpc.os-ironic-state role.
 
 - name: Ensure baremetal compute nodes are available in ironic
   hosts: controllers[0]
   gather_facts: true
   vars:
-    venv: "{{ virtualenv_path }}/shade"
+    venv: "{{ virtualenv_path }}/openstacksdk"
   roles:
-    - role: stackhpc.os-shade
-      os_shade_venv: "{{ venv }}"
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      os_shade_upper_constraints_file: "{{ pip_upper_constraints_file }}"
+    - role: stackhpc.os_openstacksdk
+      os_openstacksdk_venv: "{{ venv }}"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      os_openstacksdk_upper_constraints_file: "{{ pip_upper_constraints_file }}"
 
     - role: activate-virtualenv
       activate_virtualenv_path: "{{ venv }}"
diff --git a/ansible/baremetal-compute-provide.yml b/ansible/baremetal-compute-provide.yml
index 37a720d44..7c01d5a90 100644
--- a/ansible/baremetal-compute-provide.yml
+++ b/ansible/baremetal-compute-provide.yml
@@ -3,20 +3,20 @@
 # ironic inventory are available. Supported initial states include 'enroll' and
 # 'manageable'.
 
-# We install shade in a virtualenv on one of the controllers, and delegate to
+# We install openstacksdk in a virtualenv on one of the controllers, and delegate to
 # it when executing the stackhpc.os-ironic-state role.
 
 - name: Ensure baremetal compute nodes are available in ironic
   hosts: controllers[0]
   gather_facts: true
   vars:
-    venv: "{{ virtualenv_path }}/shade"
+    venv: "{{ virtualenv_path }}/openstacksdk"
   roles:
-    - role: stackhpc.os-shade
-      os_shade_venv: "{{ venv }}"
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      os_shade_upper_constraints_file: "{{ pip_upper_constraints_file }}"
+    - role: stackhpc.os_openstacksdk
+      os_openstacksdk_venv: "{{ venv }}"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      os_openstacksdk_upper_constraints_file: "{{ pip_upper_constraints_file }}"
 
     - role: activate-virtualenv
       activate_virtualenv_path: "{{ venv }}"
diff --git a/ansible/external-net.yml b/ansible/external-net.yml
index 30753679c..033646a8b 100644
--- a/ansible/external-net.yml
+++ b/ansible/external-net.yml
@@ -4,10 +4,10 @@
   hosts: controllers[0]
   roles:
     - role: stackhpc.os-networks
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      os_shade_upper_constraints_file: "{{ pip_upper_constraints_file }}"
-      os_networks_venv: "{{ virtualenv_path }}/shade"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      os_openstacksdk_upper_constraints_file: "{{ pip_upper_constraints_file }}"
+      os_networks_venv: "{{ virtualenv_path }}/openstacksdk"
       os_networks_openstack_auth_type: "{{ openstack_auth_type }}"
       os_networks_openstack_auth: "{{ openstack_auth }}"
       # Network configuration.
diff --git a/ansible/overcloud-grafana-configure.yml b/ansible/overcloud-grafana-configure.yml
index 8008c1e6f..5fd9cddc6 100644
--- a/ansible/overcloud-grafana-configure.yml
+++ b/ansible/overcloud-grafana-configure.yml
@@ -14,7 +14,7 @@
   tags:
     - grafana
   vars:
-    venv: "{{ virtualenv_path }}/shade"
+    venv: "{{ virtualenv_path }}/openstacksdk"
   roles:
     - role: stackhpc.os-openstackclient
       os_openstackclient_venv: "{{ venv }}"
diff --git a/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml b/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml
index 06f6b3a29..99898436c 100644
--- a/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml
+++ b/ansible/overcloud-introspection-rules-dell-lldp-workaround.yml
@@ -123,9 +123,9 @@
 
   roles:
     - role: ironic-inspector-rules
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      ironic_inspector_venv: "{{ virtualenv_path }}/shade"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      ironic_inspector_venv: "{{ virtualenv_path }}/openstacksdk"
       ironic_inspector_upper_constraints_file: "{{ pip_upper_constraints_file }}"
       ironic_inspector_auth_type: "{{ openstack_auth_type }}"
       ironic_inspector_auth: "{{ openstack_auth }}"
diff --git a/ansible/overcloud-introspection-rules.yml b/ansible/overcloud-introspection-rules.yml
index 39b004df1..c1d790cff 100644
--- a/ansible/overcloud-introspection-rules.yml
+++ b/ansible/overcloud-introspection-rules.yml
@@ -15,7 +15,7 @@
   tags:
     - introspection-rules
   vars:
-    venv: "{{ virtualenv_path }}/shade"
+    venv: "{{ virtualenv_path }}/openstacksdk"
   pre_tasks:
     - name: Validate OpenStack password authentication parameters
       fail:
@@ -57,8 +57,8 @@
 
   roles:
     - role: ironic-inspector-rules
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
       ironic_inspector_venv: "{{ venv }}"
       ironic_inspector_upper_constraints_file: "{{ pip_upper_constraints_file }}"
       ironic_inspector_auth_type: "{{ openstack_auth_type }}"
diff --git a/ansible/overcloud-ipa-images.yml b/ansible/overcloud-ipa-images.yml
index a6015775c..ec5fb5c75 100644
--- a/ansible/overcloud-ipa-images.yml
+++ b/ansible/overcloud-ipa-images.yml
@@ -99,9 +99,9 @@
         - item.src != item.dest
   roles:
     - role: ipa-images
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      ipa_images_venv: "{{ virtualenv_path }}/shade"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      ipa_images_venv: "{{ virtualenv_path }}/openstacksdk"
       ipa_images_upper_constraints_file: "{{ pip_upper_constraints_file }}"
       ipa_images_openstack_auth_type: "{{ openstack_auth_type }}"
       ipa_images_openstack_auth: "{{ openstack_auth }}"
diff --git a/ansible/provision-net.yml b/ansible/provision-net.yml
index ba8a5a2a4..6548e9d32 100644
--- a/ansible/provision-net.yml
+++ b/ansible/provision-net.yml
@@ -14,7 +14,7 @@
   hosts: controllers_for_provision_net_True[0]
   gather_facts: False
   vars:
-    venv: "{{ virtualenv_path }}/shade"
+    venv: "{{ virtualenv_path }}/openstacksdk"
     provision_net:
       name: "{{ kolla_ironic_provisioning_network }}"
       provider_network_type: "{% if provision_wl_net_name | net_vlan %}vlan{% else %}flat{% endif %}"
@@ -61,9 +61,9 @@
 
   roles:
     - role: stackhpc.os-networks
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      os_shade_upper_constraints_file: "{{ pip_upper_constraints_file }}"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      os_openstacksdk_upper_constraints_file: "{{ pip_upper_constraints_file }}"
       os_networks_venv: "{{ venv }}"
       os_networks_auth_type: "{{ openstack_auth_type }}"
       os_networks_auth: "{{ openstack_auth }}"
diff --git a/ansible/roles/ipa-images/defaults/main.yml b/ansible/roles/ipa-images/defaults/main.yml
index 9f39ca385..13df4cf9f 100644
--- a/ansible/roles/ipa-images/defaults/main.yml
+++ b/ansible/roles/ipa-images/defaults/main.yml
@@ -1,5 +1,5 @@
 ---
-# Path to virtualenv in which to install shade and its dependencies.
+# Path to virtualenv in which to install openstacksdk and its dependencies.
 ipa_images_venv:
 
 # Upper constraints file for installation of python-ironicclient.
diff --git a/ansible/roles/ipa-images/meta/main.yml b/ansible/roles/ipa-images/meta/main.yml
index eb9d26582..a1914d381 100644
--- a/ansible/roles/ipa-images/meta/main.yml
+++ b/ansible/roles/ipa-images/meta/main.yml
@@ -1,8 +1,8 @@
 ---
 dependencies:
-  - role: stackhpc.os-shade
-    os_shade_venv: "{{ ipa_images_venv }}"
-    os_shade_upper_constraints_file: "{{ ipa_images_upper_constraints_file }}"
+  - role: stackhpc.os_openstacksdk
+    os_openstacksdk_venv: "{{ ipa_images_venv }}"
+    os_openstacksdk_upper_constraints_file: "{{ ipa_images_upper_constraints_file }}"
   - role: stackhpc.os-openstackclient
     os_openstackclient_venv: "{{ ipa_images_venv }}"
     os_openstackclient_upper_constraints_file: "{{ ipa_images_upper_constraints_file }}"
diff --git a/ansible/roles/ironic-inspector-rules/README.md b/ansible/roles/ironic-inspector-rules/README.md
index eeaee662b..7a3bdb1d1 100644
--- a/ansible/roles/ironic-inspector-rules/README.md
+++ b/ansible/roles/ironic-inspector-rules/README.md
@@ -36,7 +36,7 @@ for rules.
 Dependencies
 ------------
 
-This role depends on the Kayobe `shade` role.
+This role depends on the Kayobe `openstacksdk` role.
 
 Example Playbook
 ----------------
diff --git a/ansible/roles/ironic-inspector-rules/library/os_ironic_inspector_rule.py b/ansible/roles/ironic-inspector-rules/library/os_ironic_inspector_rule.py
index 7d75c9d78..c97f625f2 100644
--- a/ansible/roles/ironic-inspector-rules/library/os_ironic_inspector_rule.py
+++ b/ansible/roles/ironic-inspector-rules/library/os_ironic_inspector_rule.py
@@ -24,7 +24,7 @@ try:
 except Exception as e:
     IMPORT_ERRORS.append(e)
 try:
-    import shade
+    import openstack
 except Exception as e:
     IMPORT_ERRORS.append(e)
 
@@ -76,17 +76,15 @@ os_ironic_inspector_rule:
 """
 
 
-def _build_client(module):
+def _build_client(module, cloud):
     """Create and return an Ironic inspector client."""
-    cloud = shade.operator_cloud(**module.params)
-    session = cloud.cloud_config.get_session()
     # Ensure the requested API version is supported.
     # API 1.14 is the latest API version available in Rocky.
     api_version = (1, 14)
     client = ironic_inspector_client.v1.ClientV1(
         inspector_url=module.params['inspector_url'],
         interface=module.params['interface'],
-        session=session, region_name=module.params['region_name'],
+        session=cloud.session, region_name=module.params['region_name'],
         api_version=api_version)
     return client
 
@@ -161,8 +159,9 @@ def main():
             endpoint=module.params['inspector_url']
         )
 
+    sdk, cloud = openstack_cloud_from_module(module)
     try:
-        client = _build_client(module)
+        client = _build_client(module, cloud)
         if module.params["state"] == "present":
             changed = _ensure_rule_present(module, client)
         else:
diff --git a/ansible/roles/ironic-inspector-rules/meta/main.yml b/ansible/roles/ironic-inspector-rules/meta/main.yml
index c775134e5..68a2262c3 100644
--- a/ansible/roles/ironic-inspector-rules/meta/main.yml
+++ b/ansible/roles/ironic-inspector-rules/meta/main.yml
@@ -1,5 +1,5 @@
 ---
 dependencies:
-  - role: stackhpc.os-shade
-    os_shade_venv: "{{ ironic_inspector_venv }}"
-    os_shade_upper_constraints_file: "{{ ironic_inspector_upper_constraints_file }}"
+  - role: stackhpc.os_openstacksdk
+    os_openstacksdk_venv: "{{ ironic_inspector_venv }}"
+    os_openstacksdk_upper_constraints_file: "{{ ironic_inspector_upper_constraints_file }}"
diff --git a/ansible/seed-introspection-rules.yml b/ansible/seed-introspection-rules.yml
index fca7eb08d..e10395c68 100644
--- a/ansible/seed-introspection-rules.yml
+++ b/ansible/seed-introspection-rules.yml
@@ -5,9 +5,9 @@
     - introspection-rules
   roles:
     - role: ironic-inspector-rules
-      os_shade_install_epel: "{{ yum_install_epel }}"
-      os_shade_state: latest
-      ironic_inspector_venv: "{{ virtualenv_path }}/shade"
+      os_openstacksdk_install_epel: "{{ yum_install_epel }}"
+      os_openstacksdk_state: latest
+      ironic_inspector_venv: "{{ virtualenv_path }}/openstacksdk"
       ironic_inspector_upper_constraints_file: "{{ pip_upper_constraints_file }}"
       # No auth required for Bifrost.
       ironic_inspector_auth_type: None
diff --git a/kayobe/ansible.py b/kayobe/ansible.py
index c7b930bb8..2cb355ee5 100644
--- a/kayobe/ansible.py
+++ b/kayobe/ansible.py
@@ -271,10 +271,7 @@ def prune_galaxy_roles(parsed_args):
     """
     LOG.info("Removing unnecessary galaxy roles from kayobe")
     roles_to_remove = [
-        'stackhpc.os-flavors',
-        'stackhpc.os-projects',
-        'stackhpc.parted-1-1',
-        'stackhpc.timezone',
+        'stackhpc.os-shade',
     ]
     LOG.debug("Removing roles: %s", ",".join(roles_to_remove))
     utils.galaxy_remove(roles_to_remove, "ansible/roles")
diff --git a/kayobe/tests/unit/test_ansible.py b/kayobe/tests/unit/test_ansible.py
index b1df9f5fb..bb5540ca6 100644
--- a/kayobe/tests/unit/test_ansible.py
+++ b/kayobe/tests/unit/test_ansible.py
@@ -468,10 +468,7 @@ class TestCase(unittest.TestCase):
         ansible.prune_galaxy_roles(parsed_args)
 
         expected_roles = [
-            'stackhpc.os-flavors',
-            'stackhpc.os-projects',
-            'stackhpc.parted-1-1',
-            'stackhpc.timezone',
+            'stackhpc.os-shade',
         ]
         mock_remove.assert_called_once_with(expected_roles,
                                             "ansible/roles")
diff --git a/requirements.yml b/requirements.yml
index 8502ca68b..950b8ef45 100644
--- a/requirements.yml
+++ b/requirements.yml
@@ -30,14 +30,14 @@
 - src: stackhpc.mellanox-switch
   version: v1.0.0
 - src: stackhpc.os-images
-  version: v1.7.0
+  version: v1.8.0
 - src: stackhpc.os-ironic-state
-  version: v1.2.0
+  version: v1.3.0
 - src: stackhpc.os-networks
-  version: v1.3.1
+  version: v1.4.0
 - src: stackhpc.os-openstackclient
-  version: v1.3.0
-- src: stackhpc.os-shade
-  version: v1.3.0
+  version: v1.4.0
+- src: stackhpc.os_openstacksdk
+  version: v1.0.0
 - src: yatesr.timezone
   version: 1.2.0