diff --git a/tests/multi-node-firewall-persistence.yaml b/tests/multi-node-firewall-persistence.yaml
new file mode 100644
index 00000000..3f646df7
--- /dev/null
+++ b/tests/multi-node-firewall-persistence.yaml
@@ -0,0 +1,64 @@
+- name: Test the persistent-firewall role
+  hosts: all
+  roles:
+    # We're including multi-node-bridge a second time with the toggle for
+    # enabling firewall rules for the bridge network subnet
+    # By this time, multi-node-firewall has already ran, we don't need to run
+    # it again -- we're testing here that both are persisted properly.
+    - { role: multi-node-bridge, bridge_authorize_internal_traffic: true }
+  post_tasks:
+    - name: Include OS-specific variables
+      include_vars: "{{ item }}"
+      with_first_found:
+        - "{{ ansible_distribution }}_{{ ansible_distribution_release }}.yaml"
+        - "{{ ansible_distribution }}.yaml"
+        - "{{ ansible_os_family }}.yaml"
+        - "default.yaml"
+
+    - name: Flush iptables rules
+      become: yes
+      command: "{{ item }}"
+      with_items:
+        - iptables --flush
+        - ip6tables --flush
+
+    # NOTE (dmsimard): We're using with_items here because RedHat needs to
+    # restart both iptables and ip6tables.
+    - name: Restart iptables
+      become: yes
+      service:
+        name: "{{ item }}"
+        state: restarted
+      when: iptables_service is defined
+      with_items: "{{ iptables_service }}"
+
+    - name: switch and peer nodes should be in the ipv4 firewall
+      become: yes
+      command: iptables-save
+      changed_when: false
+      failed_when: false
+      register: iptables_rules
+
+    - name: Validate ipv4 firewall configuration
+      assert:
+        that:
+          - "'-A INPUT -s {{ hostvars[item]['nodepool']['private_ipv4'] }}/32 -j ACCEPT' in iptables_rules.stdout"
+          - "'-A INPUT -s {{ hostvars[item]['nodepool']['public_ipv4'] }}/32 -j ACCEPT' in iptables_rules.stdout"
+          - "'-A INPUT -s {{ bridge_address_prefix }}.0/{{ bridge_address_subnet }} -d {{ bridge_address_prefix }}.0/{{ bridge_address_subnet }} -j ACCEPT' in iptables_rules.stdout"
+      with_items: "{{ groups['all'] }}"
+
+    # ipv6_addresses is set by the multi-node-firewall role
+    - when: ipv6_addresses | length > 0
+      block:
+        - name: switch and peer nodes should be in the ipv6 firewall
+          become: yes
+          command: ip6tables-save
+          changed_when: false
+          failed_when: false
+          register: ip6tables_rules
+
+        - name: Validate ipv6 firewall configuration
+          assert:
+            that:
+              - "'-A INPUT -s {{ hostvars[item]['nodepool']['public_ipv6'] }}/128 -j ACCEPT' in ip6tables_rules.stdout"
+          with_items: "{{ groups['all'] }}"
diff --git a/tests/multinode.yaml b/tests/multinode.yaml
index 5e42ad5a..066e7d5d 100644
--- a/tests/multinode.yaml
+++ b/tests/multinode.yaml
@@ -10,3 +10,4 @@
 - include: multi-node-hosts-file.yaml
 - include: multi-node-firewall.yaml
 - include: multi-node-bridge.yaml
+- include: multi-node-firewall-persistence.yaml
diff --git a/tests/vars/Debian.yaml b/tests/vars/Debian.yaml
new file mode 100644
index 00000000..0d16c8b7
--- /dev/null
+++ b/tests/vars/Debian.yaml
@@ -0,0 +1,2 @@
+iptables_service:
+  - netfilter-persistent
diff --git a/tests/vars/RedHat.yaml b/tests/vars/RedHat.yaml
new file mode 100644
index 00000000..08f39d64
--- /dev/null
+++ b/tests/vars/RedHat.yaml
@@ -0,0 +1,3 @@
+iptables_service:
+  - iptables
+  - ip6tables
diff --git a/tests/vars/Suse.yaml b/tests/vars/Suse.yaml
new file mode 100644
index 00000000..01bce50f
--- /dev/null
+++ b/tests/vars/Suse.yaml
@@ -0,0 +1,2 @@
+iptables_service:
+  - SuSEfirewall2
diff --git a/tests/vars/Ubuntu_trusty.yaml b/tests/vars/Ubuntu_trusty.yaml
new file mode 100644
index 00000000..c7935c85
--- /dev/null
+++ b/tests/vars/Ubuntu_trusty.yaml
@@ -0,0 +1,2 @@
+iptables_service:
+  - iptables-persistent
diff --git a/tests/vars/default.yaml b/tests/vars/default.yaml
new file mode 100644
index 00000000..e69de29b
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 69f6004c..043dfa34 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -60,6 +60,8 @@
       Runs roles that are included by default in the 'multinode' job in order
       to prevent regressions.
     parent: base-minimal
+    vars:
+      ara_generate_html: true
     required-projects:
       - openstack-infra/project-config
     roles: