diff --git a/playbooks/group_vars/firehose.yaml b/playbooks/group_vars/firehose.yaml
index c3c4486ff4..eff02f1243 100644
--- a/playbooks/group_vars/firehose.yaml
+++ b/playbooks/group_vars/firehose.yaml
@@ -1,11 +1,16 @@
 exim_local_domains: "@:firehose.openstack.org"
+# TODO(jeblair): have the cyrus router check to see if there is a
+# cyrus account.
 exim_routers:
+  - dnslookup: '{{ exim_dnslookup_router }}'
+  - system_aliases: '{{ exim_system_aliases_router }}'
   - cyrus: |
       driver = accept
       domains = +local_domains
       local_part_suffix = +*
       local_part_suffix_optional
       transport = cyrus
+  - localuser: '{{ exim_localuser_router }}'
 exim_transports:
   - cyrus: |
       driver = lmtp
diff --git a/playbooks/group_vars/storyboard.yaml b/playbooks/group_vars/storyboard.yaml
index 7f813d1a84..4733058078 100644
--- a/playbooks/group_vars/storyboard.yaml
+++ b/playbooks/group_vars/storyboard.yaml
@@ -1,4 +1,7 @@
 exim_routers:
+  - dnslookup: '{{ exim_dnslookup_router }}'
+  - system_aliases: '{{ exim_system_aliases_router }}'
+  - localuser: '{{ exim_localuser_router }}'
   - storyboard_verp_router: |
       driver = dnslookup
       # we only consider messages sent in through loopback
diff --git a/playbooks/host_vars/lists.katacontainers.io.yaml b/playbooks/host_vars/lists.katacontainers.io.yaml
index 976f7d5b63..6a2eed20d9 100644
--- a/playbooks/host_vars/lists.katacontainers.io.yaml
+++ b/playbooks/host_vars/lists.katacontainers.io.yaml
@@ -3,6 +3,9 @@ exim_local_domains: "@:{{ mm_domains }}"
 exim_aliases:
   root: "{{ ','.join(listadmins|default([])) }}"
 exim_routers:
+  - dnslookup: '{{ exim_dnslookup_router }}'
+  - system_aliases: '{{ exim_system_aliases_router }}'
+  - localuser: '{{ exim_localuser_router }}'
   - mailman_verp_router: |
       {% raw -%}
       driver = dnslookup
diff --git a/playbooks/host_vars/lists.openstack.org.yaml b/playbooks/host_vars/lists.openstack.org.yaml
index 0810924cae..3596ccd741 100644
--- a/playbooks/host_vars/lists.openstack.org.yaml
+++ b/playbooks/host_vars/lists.openstack.org.yaml
@@ -28,6 +28,9 @@ exim_aliases:
   women-of-openstack-owner: spam
   spam: ':fail: delivery temporarily disabled due to ongoing spam flood'
 exim_routers:
+  - dnslookup: '{{ exim_dnslookup_router }}'
+  - system_aliases: '{{ exim_system_aliases_router }}'
+  - localuser: '{{ exim_localuser_router }}'
   - mailman_verp_router: |
       {% raw -%}
       driver = dnslookup
diff --git a/playbooks/roles/exim/defaults/main.yaml b/playbooks/roles/exim/defaults/main.yaml
index 004babffb7..103e319931 100644
--- a/playbooks/roles/exim/defaults/main.yaml
+++ b/playbooks/roles/exim/defaults/main.yaml
@@ -2,5 +2,26 @@ exim_aliases: {}
 exim_local_domains: '@'
 exim_queue_interval: 30m
 exim_queue_run_max: 5
-exim_routers: []
+exim_dnslookup_router: |
+  driver = dnslookup
+  domains = ! +local_domains
+  transport = remote_smtp
+  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
+  no_more
+exim_system_aliases_router: |
+  driver = redirect
+  allow_fail
+  allow_defer
+  data = ${lookup{$local_part}lsearch{/etc/aliases}}
+  file_transport = address_file
+  pipe_transport = address_pipe
+exim_localuser_router: |
+  driver = accept
+  cannot_route_message = Unknown user
+  check_local_user
+  transport = local_delivery
+exim_routers:
+  - dnslookup: '{{ exim_dnslookup_router }}'
+  - system_aliases: '{{ exim_system_aliases_router }}'
+  - localuser: '{{ exim_localuser_router }}'
 exim_transports: []
diff --git a/playbooks/roles/exim/templates/exim4.conf.j2 b/playbooks/roles/exim/templates/exim4.conf.j2
index dc31b46e8b..5c3b2dceb2 100644
--- a/playbooks/roles/exim/templates/exim4.conf.j2
+++ b/playbooks/roles/exim/templates/exim4.conf.j2
@@ -542,93 +542,6 @@ acl_check_data:
 ######################################################################
 
 begin routers
-
-# This router routes to remote hosts over SMTP by explicit IP address,
-# when an email address is given in "domain literal" form, for example,
-# <user@[192.168.35.64]>. The RFCs require this facility. However, it is
-# little-known these days, and has been exploited by evil people seeking
-# to abuse SMTP relays. Consequently it is commented out in the default
-# configuration. If you uncomment this router, you also need to uncomment
-# allow_domain_literals above, so that Exim can recognize the syntax of
-# domain literal addresses.
-
-# domain_literal:
-#   driver = ipliteral
-#   domains = ! +local_domains
-#   transport = remote_smtp
-
-
-# This router routes addresses that are not in local domains by doing a DNS
-# lookup on the domain name. The exclamation mark that appears in "domains = !
-# +local_domains" is a negating operator, that is, it can be read as "not". The
-# recipient's domain must not be one of those defined by "domainlist
-# local_domains" above for this router to be used.
-#
-# If the router is used, any domain that resolves to 0.0.0.0 or to a loopback
-# interface address (127.0.0.0/8) is treated as if it had no DNS entry. Note
-# that 0.0.0.0 is the same as 0.0.0.0/32, which is commonly treated as the
-# local host inside the network stack. It is not 0.0.0.0/0, the default route.
-# If the DNS lookup fails, no further routers are tried because of the no_more
-# setting, and consequently the address is unrouteable.
-
-dnslookup:
-  driver = dnslookup
-  domains = ! +local_domains
-  transport = remote_smtp
-  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
-  no_more
-
-# The remaining routers handle addresses in the local domain(s), that is those
-# domains that are defined by "domainlist local_domains" above.
-
-
-# This router handles aliasing using a linearly searched alias file with the
-# name SYSTEM_ALIASES_FILE. When this configuration is installed automatically,
-# the name gets inserted into this file from whatever is set in Exim's
-# build-time configuration. The default path is the traditional /etc/aliases.
-# If you install this configuration by hand, you need to specify the correct
-# path in the "data" setting below.
-#
-##### NB  You must ensure that the alias file exists. It used to be the case
-##### NB  that every Unix had that file, because it was the Sendmail default.
-##### NB  These days, there are systems that don't have it. Your aliases
-##### NB  file should at least contain an alias for "postmaster".
-#
-# If any of your aliases expand to pipes or files, you will need to set
-# up a user and a group for these deliveries to run under. You can do
-# this by uncommenting the "user" option below (changing the user name
-# as appropriate) and adding a "group" option if necessary. Alternatively, you
-# can specify "user" on the transports that are used. Note that the transports
-# listed below are the same as are used for .forward files; you might want
-# to set up different ones for pipe and file deliveries from aliases.
-
-system_aliases:
-  driver = redirect
-  allow_fail
-  allow_defer
-  data = ${lookup{$local_part}lsearch{/etc/aliases}}
-# user = exim
-  file_transport = address_file
-  pipe_transport = address_pipe
-
-# .forward files are not supported --jeblair
-
-# This router matches local user mailboxes. If the router fails, the error
-# message is "Unknown user".
-
-# If you want this router to treat local parts with suffixes introduced by "-"
-# or "+" characters as if the suffixes did not exist, uncomment the two local_
-# part_suffix options. Then, for example, xxxx-foo@your.domain will be treated
-# in the same way as xxxx@your.domain by this router.
-
-localuser:
-  driver = accept
-  check_local_user
-# local_part_suffix = +* : -*
-# local_part_suffix_optional
-  transport = local_delivery
-  cannot_route_message = Unknown user
-
 {% for router in exim_routers %}
 {% for name, values in router.items() %}