Lets start this post by saying, I don't recommend relying solely on this method however, it may give you a glimpse into what's possible without needing to perform a stack update/deploy; which in some instances is a deal-breaker.

Pull an inventory out of TripleO from the undercloud

ssh $undercloud
cd /home/stack; source stackrc
tripleo-ansible-inventory --static-yaml-inventory inventory.yaml

Create the following playbook:

---
- hosts:
  - Controller
  - CephStorage

  gather_facts: True
  become: True
  any_errors_fatal: true

  vars:
    - mon_group_name: Controller
    - mgr_group_name: Controller
    - osd_group_name: CephStorage
  roles:
    - role: ceph-defaults
    - role: ceph-infra
...

Now you have everything required to execute the roles only against all storage nodes in your environment. A good reason you may want to do this is if you've recently rebooted a server, and for some reason none of the OSDs come back up.

Execute the playbook:

ansible-playbook -b --ssh-extra-args "-o StrictHostKeyChecking=no" \
  -i inventory.yaml playbook.yml