diff --git a/tests/ansible/role-test-runner.yaml b/tests/ansible/role-test-runner.yaml
new file mode 100644
index 000000000..c6c0f11f3
--- /dev/null
+++ b/tests/ansible/role-test-runner.yaml
@@ -0,0 +1,18 @@
+---
+- hosts: primary
+  tasks:
+    - name: set default roles
+      set_fact:
+        test_subject_roles_default:
+        - libvirt-network
+        - libvirt-pool
+        - libvirt-volume
+        - libvirt-domain
+        - redfish-emulator
+        - airship-libvirt-gate
+        - http-fileserver
+    - name: run tests against defined roles
+      include_tasks: "../../roles/{{ role_name }}/tests/main.yaml"
+      with_items: "{{ test_subject_roles | default(test_subject_roles_default) }}"
+      loop_control:
+        loop_var: role_name
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 6867f4036..8ffe3c0b0 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -10,6 +10,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+- job:
+    name: airship-airshipctl-roles-test
+    run: tests/ansible/role-test-runner.yaml
+    nodeset: airship-airshipctl-single-node
+
 - job:
     name: airship-airshipctl-build-docs
     nodeset: airship-airshipctl-single-node
diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml
index b1ca72b2a..138a7b7a5 100644
--- a/zuul.d/projects.yaml
+++ b/zuul.d/projects.yaml
@@ -16,6 +16,9 @@
       rtd_webhook_id: 112688
     check:
       jobs:
+        - airship-airshipctl-roles-test:
+            files:
+              - "roles/*"
         - airship-airshipctl-build-docs
         - airship-airshipctl-lint-unit
         - airship-airshipctl-build-image