diff --git a/playbooks/tox/cover-post.yaml b/playbooks/tox/cover-post.yaml
new file mode 100644
index 000000000..946b0c101
--- /dev/null
+++ b/playbooks/tox/cover-post.yaml
@@ -0,0 +1,3 @@
+- hosts: all
+  roles:
+    - role: fetch-coverage-output
diff --git a/roles/fetch-coverage-output/README.rst b/roles/fetch-coverage-output/README.rst
new file mode 100644
index 000000000..4058566ff
--- /dev/null
+++ b/roles/fetch-coverage-output/README.rst
@@ -0,0 +1,20 @@
+Collect output from a coverage run
+
+By default, this copies the output from a coverage run
+on the worker to the log root of the executor.
+
+**Role Variables**
+
+.. zuul:rolevar:: zuul_executor_dest
+   :default: {{ zuul.executor.log_root }}
+
+   The destination directory on the executor.  By default, the log
+   root.
+
+.. zuul:rolevar:: coverage_output_src
+   :default: {{ zuul.project.canonical_name }}/cover/
+
+   The location on the worker from which to fetch the coverage
+   output detail.  By default, the ``cover`` dir of the current
+   project.
+
diff --git a/roles/fetch-coverage-output/defaults/main.yaml b/roles/fetch-coverage-output/defaults/main.yaml
new file mode 100644
index 000000000..9181dddf2
--- /dev/null
+++ b/roles/fetch-coverage-output/defaults/main.yaml
@@ -0,0 +1,2 @@
+zuul_executor_dest: "{{ zuul.executor.log_root }}"
+coverage_output_src: "src/{{ zuul.project.canonical_name }}/cover/"
diff --git a/roles/fetch-coverage-output/tasks/main.yaml b/roles/fetch-coverage-output/tasks/main.yaml
new file mode 100644
index 000000000..63a627ad2
--- /dev/null
+++ b/roles/fetch-coverage-output/tasks/main.yaml
@@ -0,0 +1,6 @@
+- name: Collect coverage details output
+  synchronize:
+    dest: "{{ zuul_executor_dest }}"
+    mode: pull
+    src: "{{ coverage_output_src }}"
+    verify_host: true
diff --git a/zuul.yaml b/zuul.yaml
index bf1e29654..2ccc4f185 100644
--- a/zuul.yaml
+++ b/zuul.yaml
@@ -123,6 +123,7 @@
       Run code coverage tests.
 
       Uses tox with the ``cover`` environment.
+    post-run: playbooks/cover/tox/cover-post
     vars:
       tox_envlist: cover