diff --git a/ansible/roles/barbican/defaults/main.yml b/ansible/roles/barbican/defaults/main.yml
index c7349fb95cdbe903389d51914defbeee0d805392..37686cbc37267308cf941d8f0831a601bfa0c11b 100644
--- a/ansible/roles/barbican/defaults/main.yml
+++ b/ansible/roles/barbican/defaults/main.yml
@@ -133,3 +133,9 @@ barbican_ks_users:
     user: "{{ barbican_keystone_user }}"
     password: "{{ barbican_keystone_password }}"
     role: "admin"
+
+barbican_ks_roles:
+  - "{{ barbican_keymanager_role }}"
+  - "{{ barbican_creator_role }}"
+  - "{{ barbican_observer_role }}"
+  - "{{ barbican_audit_role }}"
diff --git a/ansible/roles/barbican/tasks/register.yml b/ansible/roles/barbican/tasks/register.yml
index 84cc5d7911d56500356c0cfd9cda568ea0d4a990..0ceb37f914b8929680b5d59c9892f540ba377ffb 100644
--- a/ansible/roles/barbican/tasks/register.yml
+++ b/ansible/roles/barbican/tasks/register.yml
@@ -5,20 +5,5 @@
     service_ks_register_auth: "{{ openstack_barbican_auth }}"
     service_ks_register_services: "{{ barbican_ks_services }}"
     service_ks_register_users: "{{ barbican_ks_users }}"
+    service_ks_register_roles: "{{ barbican_ks_roles }}"
   tags: always
-
-- name: Creating default barbican roles
-  become: true
-  kolla_toolbox:
-    module_name: os_keystone_role
-    module_args:
-      name: "{{ item }}"
-      auth: "{{ openstack_barbican_auth }}"
-      endpoint_type: "{{ openstack_interface }}"
-      cacert: "{{ openstack_cacert }}"
-  run_once: True
-  with_items:
-    - "{{ barbican_keymanager_role }}"
-    - "{{ barbican_creator_role }}"
-    - "{{ barbican_observer_role }}"
-    - "{{ barbican_audit_role }}"
diff --git a/ansible/roles/cloudkitty/defaults/main.yml b/ansible/roles/cloudkitty/defaults/main.yml
index 440a40a48c06a74d91d31c31dfa71825ac81810e..0f6ccce09de60c879b9ebb5ba1c6633701577617 100644
--- a/ansible/roles/cloudkitty/defaults/main.yml
+++ b/ansible/roles/cloudkitty/defaults/main.yml
@@ -140,3 +140,6 @@ cloudkitty_ks_users:
     user: "{{ cloudkitty_keystone_user }}"
     password: "{{ cloudkitty_keystone_password }}"
     role: "admin"
+
+cloudkitty_ks_roles:
+  - "{{ cloudkitty_openstack_keystone_default_role }}"
diff --git a/ansible/roles/cloudkitty/tasks/register.yml b/ansible/roles/cloudkitty/tasks/register.yml
index 639c48cfea5cc3e792c4a6f0e1d91bcf75c93d8d..fa45947e2f54d55d583d9a10da32750a71a8194e 100644
--- a/ansible/roles/cloudkitty/tasks/register.yml
+++ b/ansible/roles/cloudkitty/tasks/register.yml
@@ -5,15 +5,5 @@
     service_ks_register_auth: "{{ openstack_cloudkitty_auth }}"
     service_ks_register_services: "{{ cloudkitty_ks_services }}"
     service_ks_register_users: "{{ cloudkitty_ks_users }}"
+    service_ks_register_roles: "{{ cloudkitty_ks_roles }}"
   tags: always
-
-- name: Creating the rating role
-  become: true
-  kolla_toolbox:
-    module_name: os_keystone_role
-    module_args:
-      name: "{{ cloudkitty_openstack_keystone_default_role }}"
-      auth: "{{ openstack_cloudkitty_auth }}"
-      endpoint_type: "{{ openstack_interface }}"
-      cacert: "{{ openstack_cacert }}"
-  run_once: True
diff --git a/ansible/roles/heat/defaults/main.yml b/ansible/roles/heat/defaults/main.yml
index 93d4884921f8372007246119d8334264852704ec..aaee97bce60145a44a440ae86bd6411784dbd391 100644
--- a/ansible/roles/heat/defaults/main.yml
+++ b/ansible/roles/heat/defaults/main.yml
@@ -161,3 +161,12 @@ heat_ks_users:
     user: "{{ heat_keystone_user }}"
     password: "{{ heat_keystone_password }}"
     role: "admin"
+
+heat_ks_roles:
+  - "{{ heat_stack_owner_role }}"
+  - "{{ heat_stack_user_role }}"
+
+heat_ks_user_roles:
+  - project: "{{ openstack_auth.project_name }}"
+    user: "{{ openstack_auth.username }}"
+    role: "{{ heat_stack_owner_role }}"
diff --git a/ansible/roles/heat/tasks/register.yml b/ansible/roles/heat/tasks/register.yml
index abb38cc6b2bcde39ca8767ac1195faea3f764b27..aea43c7add760f23244b5c43de47d4b6e8e228b1 100644
--- a/ansible/roles/heat/tasks/register.yml
+++ b/ansible/roles/heat/tasks/register.yml
@@ -5,40 +5,6 @@
     service_ks_register_auth: "{{ openstack_heat_auth }}"
     service_ks_register_services: "{{ heat_ks_services }}"
     service_ks_register_users: "{{ heat_ks_users }}"
+    service_ks_register_roles: "{{ heat_ks_roles }}"
+    service_ks_register_user_roles: "{{ heat_ks_user_roles }}"
   tags: always
-
-- name: Creating the heat_stack_user role
-  become: true
-  kolla_toolbox:
-    module_name: os_keystone_role
-    module_args:
-      name: "{{ heat_stack_user_role }}"
-      auth: "{{ openstack_heat_auth }}"
-      endpoint_type: "{{ openstack_interface }}"
-      cacert: "{{ openstack_cacert }}"
-  run_once: True
-
-- name: Creating the heat_stack_owner role
-  become: true
-  kolla_toolbox:
-    module_name: os_keystone_role
-    module_args:
-      name: "{{ heat_stack_owner_role }}"
-      auth: "{{ openstack_heat_auth }}"
-      endpoint_type: "{{ openstack_interface }}"
-      cacert: "{{ openstack_cacert }}"
-  run_once: True
-
-- name: Add the heat_stack_owner role to the admin project
-  become: true
-  kolla_toolbox:
-    module_name: "os_user_role"
-    module_args:
-      project: "{{ openstack_auth.project_name }}"
-      user: "{{ openstack_auth.username }}"
-      role: "{{ heat_stack_owner_role }}"
-      region_name: "{{ openstack_region_name }}"
-      auth: "{{ openstack_heat_auth }}"
-      endpoint_type: "{{ openstack_interface }}"
-      cacert: "{{ openstack_cacert }}"
-  run_once: True
diff --git a/ansible/roles/monasca/defaults/main.yml b/ansible/roles/monasca/defaults/main.yml
index 2fafe8dbed25f7651c905918da95ac7d081fb851..ccd229401889b14fb9476990c9d745f430932966 100644
--- a/ansible/roles/monasca/defaults/main.yml
+++ b/ansible/roles/monasca/defaults/main.yml
@@ -367,3 +367,9 @@ monasca_ks_users:
     user: "{{ monasca_agent_user }}"
     password: "{{ monasca_agent_password }}"
     role: "{{ monasca_agent_authorized_roles | first }}"
+
+monasca_ks_roles:
+  - "{{ monasca_default_authorized_roles }}"
+  - "{{ monasca_agent_authorized_roles }}"
+  - "{{ monasca_read_only_authorized_roles }}"
+  - "{{ monasca_delegate_authorized_roles }}"
diff --git a/ansible/roles/monasca/tasks/register.yml b/ansible/roles/monasca/tasks/register.yml
index 538f5ca26ecbab285e08d8bf2f8a89694d0cf3ba..afab0c7699fa778e563bf4f6927f73bb93ca1565 100644
--- a/ansible/roles/monasca/tasks/register.yml
+++ b/ansible/roles/monasca/tasks/register.yml
@@ -5,22 +5,5 @@
     service_ks_register_auth: "{{ monasca_openstack_auth }}"
     service_ks_register_services: "{{ monasca_ks_services }}"
     service_ks_register_users: "{{ monasca_ks_users }}"
+    service_ks_register_roles: "{{ monasca_ks_roles }}"
   tags: always
-
-
-- name: Creating monasca roles
-  become: true
-  kolla_toolbox:
-    module_name: os_keystone_role
-    module_args:
-      name: "{{ item }}"
-      region_name: "{{ openstack_region_name }}"
-      auth: "{{ monasca_openstack_auth }}"
-      endpoint_type: "{{ openstack_interface }}"
-      cacert: "{{ openstack_cacert }}"
-  run_once: True
-  with_items:
-    - "{{ monasca_default_authorized_roles }}"
-    - "{{ monasca_agent_authorized_roles }}"
-    - "{{ monasca_read_only_authorized_roles }}"
-    - "{{ monasca_delegate_authorized_roles }}"
diff --git a/ansible/roles/service-ks-register/defaults/main.yml b/ansible/roles/service-ks-register/defaults/main.yml
index 8c27c12cd9c508a1975ee9ec05087108bc795d2e..583774811d565702cb9513b56e88657b586aed37 100644
--- a/ansible/roles/service-ks-register/defaults/main.yml
+++ b/ansible/roles/service-ks-register/defaults/main.yml
@@ -7,11 +7,34 @@ service_ks_register_endpoint_region: "{{ openstack_region_name }}"
 service_ks_register_domain: "default"
 service_ks_register_delegate_host: "{{ groups['control'][0] }}"
 # A list of services to register with Keystone. Each service definition should
-# provide a description, service type, and a list of associated endpoints to be
-# registered.
+# provide the following fields:
+# 'name'
+# 'description'
+# 'type'
+# 'endpoints'
+# The 'endpoints' field should be a list, with each item having the following
+# fields:
+# 'url'
+# 'interface'
 service_ks_register_services: []
-# A list of users and associated roles for this service to register with Keystone
+# A list of users and associated roles for this service to register with
+# Keystone. Each item should provide the following fields:
+# 'project'
+# 'user'
+# 'password'
+# 'role'
+# The project, user and role will be created if they do not exist, and the user
+# will be granted the role in the project.
 service_ks_register_users: []
+# A list of roles to register with Keystone.
+service_ks_register_roles: []
+# A list of existing users and associated roles for this service to register
+# with Keystone. Each item should provide the following fields:
+# 'project'
+# 'user'
+# 'role'
+# The user will be granted the role in the project.
+service_ks_register_user_roles: []
 # Number of retries for each task.
 service_ks_register_retries: 5
 # Delay between task retries.
diff --git a/ansible/roles/service-ks-register/tasks/main.yml b/ansible/roles/service-ks-register/tasks/main.yml
index edba77d0cafeba63cd7142e6b14f9963f30762e5..de5b9ea533179cc8ae99c9c5ca4aac58a2a9a3a2 100644
--- a/ansible/roles/service-ks-register/tasks/main.yml
+++ b/ansible/roles/service-ks-register/tasks/main.yml
@@ -1,5 +1,5 @@
 ---
-- name: Creating the {{ project_name }} service
+- name: "{{ project_name }} | Creating services"
   become: true
   kolla_toolbox:
     module_name: "os_keystone_service"
@@ -14,12 +14,16 @@
   run_once: True
   loop: "{{ service_ks_register_services }}"
   delegate_to: "{{ service_ks_register_delegate_host }}"
+  loop_control:
+    label:
+      name: "{{ item.name }}"
+      service_type: "{{ item.type }}"
   register: service_ks_register_result
   until: service_ks_register_result is success
   retries: "{{ service_ks_register_retries }}"
   delay: "{{ service_ks_register_delay }}"
 
-- name: Creating the {{ project_name }} endpoints
+- name: "{{ project_name }} | Creating endpoints"
   become: true
   kolla_toolbox:
     module_name: "os_keystone_endpoint"
@@ -37,12 +41,17 @@
     - "{{ service_ks_register_services }}"
     - endpoints
   delegate_to: "{{ service_ks_register_delegate_host }}"
+  loop_control:
+    label:
+      service: "{{ item.0.name }}"
+      url: "{{ item.1.url }}"
+      interface: "{{ item.1.interface }}"
   register: service_ks_register_result
   until: service_ks_register_result is success
   retries: "{{ service_ks_register_retries }}"
   delay: "{{ service_ks_register_delay }}"
 
-- name: Creating the {{ project_name }} service project
+- name: "{{ project_name }} | Creating projects"
   become: true
   kolla_toolbox:
     module_name: "os_project"
@@ -61,7 +70,7 @@
   retries: "{{ service_ks_register_retries }}"
   delay: "{{ service_ks_register_delay }}"
 
-- name: Creating the {{ project_name }} service users
+- name: "{{ project_name }} | Creating users"
   become: true
   kolla_toolbox:
     module_name: "os_user"
@@ -86,7 +95,7 @@
   retries: "{{ service_ks_register_retries }}"
   delay: "{{ service_ks_register_delay }}"
 
-- name: Creating the {{ project_name }} service roles
+- name: "{{ project_name }} | Creating roles"
   become: true
   kolla_toolbox:
     module_name: "os_keystone_role"
@@ -97,14 +106,14 @@
       interface: "{{ service_ks_register_interface }}"
       cacert: "{{ service_ks_cacert }}"
   run_once: True
-  with_items: "{{ service_ks_register_users | map(attribute='role') | unique | list }}"
+  with_items: "{{ service_ks_register_users | map(attribute='role') | unique | list + service_ks_register_roles }}"
   delegate_to: "{{ service_ks_register_delegate_host }}"
   register: service_ks_register_result
   until: service_ks_register_result is success
   retries: "{{ service_ks_register_retries }}"
   delay: "{{ service_ks_register_delay }}"
 
-- name: Granting the {{ project_name }} service user roles
+- name: "{{ project_name }} | Granting user roles"
   become: true
   kolla_toolbox:
     module_name: "os_user_role"
@@ -118,7 +127,7 @@
       interface: "{{ service_ks_register_interface }}"
       cacert: "{{ service_ks_cacert }}"
   run_once: True
-  with_items: "{{ service_ks_register_users }}"
+  with_items: "{{ service_ks_register_users + service_ks_register_user_roles }}"
   delegate_to: "{{ service_ks_register_delegate_host }}"
   loop_control:
     label: