From ed82afa8e928ac7c9f5ad2162be2c27eaab8e2e6 Mon Sep 17 00:00:00 2001
From: SamYaple <sam@yaple.net>
Date: Fri, 18 Dec 2015 19:40:48 +0000
Subject: [PATCH] Simplify config creation

Convert config creation from a playbook to an action_plugin. This
reduces the complexity and confusion while retaining the same augment
structure and flexibility.

This allows us to remove the 0-byte files as requirements. They will
still be used if they are present (this means we require additional
documentation around them).

DocImpact
Closes-Bug: #1528430
Change-Id: I2c789f6be9f195c7771ca093a6d59499564b4740
---
 ansible/action_plugins/merge_configs.py       |  90 ++++
 ansible/library/merge_configs.py              |  46 --
 ansible/roles/ceph/tasks/config.yml           |  51 +-
 ansible/roles/cinder/tasks/config.yml         | 135 ++----
 ansible/roles/common/tasks/config.yml         |  18 +-
 ansible/roles/config.yml                      |  24 -
 ansible/roles/glance/tasks/config.yml         |  75 ++-
 ansible/roles/haproxy/tasks/config.yml        |  41 +-
 ansible/roles/heat/tasks/config.yml           |  90 ++--
 ansible/roles/horizon/tasks/config.yml        |  20 +-
 ansible/roles/ironic/tasks/config.yml         | 112 ++---
 ansible/roles/keystone/tasks/config.yml       |  43 +-
 ansible/roles/magnum/tasks/config.yml         |  75 ++-
 ansible/roles/mariadb/tasks/config.yml        |  33 +-
 ansible/roles/memcached/tasks/config.yml      |  16 +-
 ansible/roles/murano/tasks/config.yml         |  77 ++-
 ansible/roles/neutron/tasks/config.yml        | 259 ++++------
 ansible/roles/nova/tasks/config.yml           | 251 ++--------
 ansible/roles/rabbitmq/tasks/config.yml       |  35 +-
 ansible/roles/swift/tasks/config.yml          | 457 ++++++------------
 ...account-server.conf.j2 => account.conf.j2} |   0
 ...ainer-server.conf.j2 => container.conf.j2} |   0
 .../{object-server.conf.j2 => object.conf.j2} |   0
 .../templates/swift-account-auditor.json.j2   |   8 +-
 .../templates/swift-account-reaper.json.j2    |   8 +-
 .../swift-account-replicator.json.j2          |   8 +-
 .../templates/swift-account-server.json.j2    |   8 +-
 .../templates/swift-container-auditor.json.j2 |   8 +-
 .../swift-container-replicator.json.j2        |   8 +-
 .../templates/swift-container-server.json.j2  |   8 +-
 .../templates/swift-container-updater.json.j2 |  12 +-
 .../templates/swift-object-auditor.json.j2    |  12 +-
 .../templates/swift-object-expirer.json.j2    |  12 +-
 .../templates/swift-object-replicator.json.j2 |  12 +-
 .../templates/swift-object-server.json.j2     |  12 +-
 .../templates/swift-object-updater.json.j2    |  12 +-
 .../templates/swift-proxy-server.json.j2      |  12 +-
 etc/kolla/config/ceph.conf                    |   0
 etc/kolla/config/cinder.conf                  |   0
 etc/kolla/config/cinder/cinder-api.conf       |   0
 etc/kolla/config/cinder/cinder-backup.conf    |   0
 etc/kolla/config/cinder/cinder-scheduler.conf |   0
 etc/kolla/config/cinder/cinder-volume.conf    |   0
 etc/kolla/config/database.conf                |   0
 etc/kolla/config/discoverd.conf               |   0
 etc/kolla/config/glance.conf                  |   0
 etc/kolla/config/glance/glance-api.conf       |   0
 etc/kolla/config/glance/glance-registry.conf  |   0
 etc/kolla/config/global.conf                  |   0
 etc/kolla/config/heat.conf                    |   0
 etc/kolla/config/heat/heat-api-cfn.conf       |   0
 etc/kolla/config/heat/heat-api.conf           |   0
 etc/kolla/config/heat/heat-engine.conf        |   0
 etc/kolla/config/ironic.conf                  |   0
 etc/kolla/config/ironic/discoverd.conf        |   0
 etc/kolla/config/ironic/ironic-api.conf       |   0
 etc/kolla/config/ironic/ironic-conductor.conf |   0
 etc/kolla/config/keystone.conf                |   0
 etc/kolla/config/keystone/keystone.conf       |   0
 etc/kolla/config/magnum.conf                  |   0
 etc/kolla/config/magnum/magnum-api.conf       |   0
 etc/kolla/config/magnum/magnum-conductor.conf |   0
 etc/kolla/config/messaging.conf               |   0
 etc/kolla/config/murano.conf                  |   0
 etc/kolla/config/murano/murano-api.conf       |   0
 etc/kolla/config/murano/murano-engine.conf    |   0
 etc/kolla/config/neutron.conf                 |   0
 etc/kolla/config/neutron/dhcp_agent.ini       |   0
 etc/kolla/config/neutron/l3_agent.ini         |   0
 etc/kolla/config/neutron/metadata_agent.ini   |   0
 etc/kolla/config/neutron/ml2_conf.ini         |   0
 etc/kolla/config/neutron/neutron-agents.conf  |   0
 .../neutron/neutron-linuxbridge-agent.conf    |   0
 .../neutron/neutron-openvswitch-agent.conf    |   0
 etc/kolla/config/neutron/neutron-server.conf  |   0
 etc/kolla/config/nova.conf                    |   0
 etc/kolla/config/nova/nova-api.conf           |   0
 etc/kolla/config/nova/nova-compute.conf       |   0
 etc/kolla/config/nova/nova-conductor.conf     |   0
 etc/kolla/config/nova/nova-consoleauth.conf   |   0
 etc/kolla/config/nova/nova-novncproxy.conf    |   0
 etc/kolla/config/nova/nova-scheduler.conf     |   0
 .../config/nova/nova-spicehtml5proxy.conf     |   0
 etc/kolla/config/swift.conf                   |   0
 etc/kolla/config/swift/account-auditor.conf   |   0
 etc/kolla/config/swift/account-reaper.conf    |   0
 .../config/swift/account-replicator.conf      |   0
 etc/kolla/config/swift/account-server.conf    |   0
 etc/kolla/config/swift/container-auditor.conf |   0
 .../config/swift/container-replicator.conf    |   0
 etc/kolla/config/swift/container-server.conf  |   0
 etc/kolla/config/swift/container-updater.conf |   0
 etc/kolla/config/swift/object-auditor.conf    |   0
 etc/kolla/config/swift/object-expirer.conf    |   0
 etc/kolla/config/swift/object-replicator.conf |   0
 etc/kolla/config/swift/object-server.conf     |   0
 etc/kolla/config/swift/object-updater.conf    |   0
 etc/kolla/config/swift/proxy-server.conf      |   0
 etc/kolla/config/swift/swift.conf             |   0
 tox.ini                                       |   2 +-
 100 files changed, 761 insertions(+), 1329 deletions(-)
 create mode 100644 ansible/action_plugins/merge_configs.py
 delete mode 100644 ansible/roles/config.yml
 rename ansible/roles/swift/templates/{account-server.conf.j2 => account.conf.j2} (100%)
 rename ansible/roles/swift/templates/{container-server.conf.j2 => container.conf.j2} (100%)
 rename ansible/roles/swift/templates/{object-server.conf.j2 => object.conf.j2} (100%)
 delete mode 100644 etc/kolla/config/ceph.conf
 delete mode 100644 etc/kolla/config/cinder.conf
 delete mode 100644 etc/kolla/config/cinder/cinder-api.conf
 delete mode 100644 etc/kolla/config/cinder/cinder-backup.conf
 delete mode 100644 etc/kolla/config/cinder/cinder-scheduler.conf
 delete mode 100644 etc/kolla/config/cinder/cinder-volume.conf
 delete mode 100644 etc/kolla/config/database.conf
 delete mode 100644 etc/kolla/config/discoverd.conf
 delete mode 100644 etc/kolla/config/glance.conf
 delete mode 100644 etc/kolla/config/glance/glance-api.conf
 delete mode 100644 etc/kolla/config/glance/glance-registry.conf
 delete mode 100644 etc/kolla/config/global.conf
 delete mode 100644 etc/kolla/config/heat.conf
 delete mode 100644 etc/kolla/config/heat/heat-api-cfn.conf
 delete mode 100644 etc/kolla/config/heat/heat-api.conf
 delete mode 100644 etc/kolla/config/heat/heat-engine.conf
 delete mode 100644 etc/kolla/config/ironic.conf
 delete mode 100644 etc/kolla/config/ironic/discoverd.conf
 delete mode 100644 etc/kolla/config/ironic/ironic-api.conf
 delete mode 100644 etc/kolla/config/ironic/ironic-conductor.conf
 delete mode 100644 etc/kolla/config/keystone.conf
 delete mode 100644 etc/kolla/config/keystone/keystone.conf
 delete mode 100644 etc/kolla/config/magnum.conf
 delete mode 100644 etc/kolla/config/magnum/magnum-api.conf
 delete mode 100644 etc/kolla/config/magnum/magnum-conductor.conf
 delete mode 100644 etc/kolla/config/messaging.conf
 delete mode 100644 etc/kolla/config/murano.conf
 delete mode 100644 etc/kolla/config/murano/murano-api.conf
 delete mode 100644 etc/kolla/config/murano/murano-engine.conf
 delete mode 100644 etc/kolla/config/neutron.conf
 delete mode 100644 etc/kolla/config/neutron/dhcp_agent.ini
 delete mode 100644 etc/kolla/config/neutron/l3_agent.ini
 delete mode 100644 etc/kolla/config/neutron/metadata_agent.ini
 delete mode 100644 etc/kolla/config/neutron/ml2_conf.ini
 delete mode 100644 etc/kolla/config/neutron/neutron-agents.conf
 delete mode 100644 etc/kolla/config/neutron/neutron-linuxbridge-agent.conf
 delete mode 100644 etc/kolla/config/neutron/neutron-openvswitch-agent.conf
 delete mode 100644 etc/kolla/config/neutron/neutron-server.conf
 delete mode 100644 etc/kolla/config/nova.conf
 delete mode 100644 etc/kolla/config/nova/nova-api.conf
 delete mode 100644 etc/kolla/config/nova/nova-compute.conf
 delete mode 100644 etc/kolla/config/nova/nova-conductor.conf
 delete mode 100644 etc/kolla/config/nova/nova-consoleauth.conf
 delete mode 100644 etc/kolla/config/nova/nova-novncproxy.conf
 delete mode 100644 etc/kolla/config/nova/nova-scheduler.conf
 delete mode 100644 etc/kolla/config/nova/nova-spicehtml5proxy.conf
 delete mode 100644 etc/kolla/config/swift.conf
 delete mode 100644 etc/kolla/config/swift/account-auditor.conf
 delete mode 100644 etc/kolla/config/swift/account-reaper.conf
 delete mode 100644 etc/kolla/config/swift/account-replicator.conf
 delete mode 100644 etc/kolla/config/swift/account-server.conf
 delete mode 100644 etc/kolla/config/swift/container-auditor.conf
 delete mode 100644 etc/kolla/config/swift/container-replicator.conf
 delete mode 100644 etc/kolla/config/swift/container-server.conf
 delete mode 100644 etc/kolla/config/swift/container-updater.conf
 delete mode 100644 etc/kolla/config/swift/object-auditor.conf
 delete mode 100644 etc/kolla/config/swift/object-expirer.conf
 delete mode 100644 etc/kolla/config/swift/object-replicator.conf
 delete mode 100644 etc/kolla/config/swift/object-server.conf
 delete mode 100644 etc/kolla/config/swift/object-updater.conf
 delete mode 100644 etc/kolla/config/swift/proxy-server.conf
 delete mode 100644 etc/kolla/config/swift/swift.conf

diff --git a/ansible/action_plugins/merge_configs.py b/ansible/action_plugins/merge_configs.py
new file mode 100644
index 0000000000..622f6f91d2
--- /dev/null
+++ b/ansible/action_plugins/merge_configs.py
@@ -0,0 +1,90 @@
+#!/usr/bin/python
+
+# Copyright 2015 Sam Yaple
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from ConfigParser import ConfigParser
+from cStringIO import StringIO
+import os
+
+from ansible import utils
+from ansible.utils import template
+from ansible.runner.return_data import ReturnData
+
+
+class ActionModule(object):
+
+    TRANSFERS_FILES = True
+
+    def __init__(self, runner):
+        self.runner = runner
+
+    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
+        args = {}
+        if complex_args:
+            args.update(complex_args)
+        args.update(utils.parse_kv(module_args))
+
+        dest = args.get('dest')
+        extra_vars = args.get('vars')
+        sources = args.get('sources')
+
+        if extra_vars:
+            # Extend 'inject' args used in templating
+            if isinstance(extra_vars, dict):
+                inject.update(extra_vars)
+            else:
+                inject.update(utils.parse_kv(extra_vars))
+
+
+        # Catch the case where sources is a str()
+        if not isinstance(sources, list):
+            sources = [sources]
+
+        config = ConfigParser()
+
+        for source in sources:
+            # template the source string
+            source = template.template(self.runner.basedir, source, inject)
+
+            # Only use config if present
+            if os.access(source, os.R_OK):
+                # template the source data locally & get ready to transfer
+                try:
+                    resultant = template.template_from_file(self.runner.basedir, source, inject)
+                except Exception as e:
+                    return ReturnData(conn=conn, comm_ok=False, result={'failed': True, 'msg': str(e)})
+
+                # Read in new results and merge this with the existing config
+                fakefile = StringIO(resultant)
+                config.readfp(fakefile)
+                fakefile.close()
+
+        # Dump configparser to string via an emulated file
+        fakefile = StringIO()
+        config.write(fakefile)
+        # Template the file to fill out any variables
+        content = template.template(self.runner.basedir, fakefile.getvalue(), inject)
+        fakefile.close()
+
+        # Ship this content over to a new file for use with the copy module
+        xfered = self.runner._transfer_str(conn, tmp, 'source', content)
+
+        copy_module_args = dict(
+           src=xfered,
+           dest=dest,
+           original_basename=os.path.basename(source),
+           follow=True,
+        )
+        return self.runner._execute_module(conn, tmp, 'copy', '', inject=inject, complex_args=copy_module_args)
diff --git a/ansible/library/merge_configs.py b/ansible/library/merge_configs.py
index e894322ed5..5da09eed19 100644
--- a/ansible/library/merge_configs.py
+++ b/ansible/library/merge_configs.py
@@ -49,49 +49,3 @@ Merge multiple configs:
         dest:
           - "/etc/mysql/my.cnf"
 '''
-
-from ConfigParser import ConfigParser
-from cStringIO import StringIO
-
-def main():
-    module = AnsibleModule(
-        argument_spec = dict(
-            sources = dict(required=True, type='list'),
-            dest = dict(required=True, type='str'),
-        )
-    )
-
-    try:
-        sources = module.params.pop('sources')
-        dest = module.params.pop('dest')
-
-        changed = False
-
-        config = ConfigParser()
-
-        for source_file in sources:
-            config.read(source_file)
-
-        if os.path.exists(dest) and os.access(dest, os.R_OK):
-            fakedest = StringIO()
-            config.write(fakedest)
-            with open(dest, 'rb') as f:
-                files_match = f.read() == fakedest.getvalue()
-
-        else:
-            files_match = False
-
-        if not files_match:
-            changed = True
-            with open(dest, 'wb') as f:
-                config.write(f)
-
-        module.exit_json(changed=changed)
-    except Exception as e:
-        module.exit_json(failed=True, changed=changed, msg=repr(e))
-
-
-# import module snippets
-from ansible.module_utils.basic import *
-if __name__ == '__main__':
-    main()
diff --git a/ansible/roles/ceph/tasks/config.yml b/ansible/roles/ceph/tasks/config.yml
index a9f99e820a..891a0e7ef8 100644
--- a/ansible/roles/ceph/tasks/config.yml
+++ b/ansible/roles/ceph/tasks/config.yml
@@ -1,32 +1,29 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "ceph-mon"
-    config_source:
-      - "roles/ceph/templates/ceph.conf.j2"
-      - "/etc/kolla/config/ceph.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/ceph.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/ceph.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/ceph.conf"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "ceph-mon"
+    - "ceph-osd"
 
-- name: Copying over ceph-mon JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "ceph-mon.json.j2"
-    dest: "{{ node_config_directory }}/ceph-mon/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "ceph-mon"
+    - "ceph-osd"
 
-- include: ../../config.yml
-  vars:
-    service_name: "ceph-osd"
-    config_source:
-      - "roles/ceph/templates/ceph.conf.j2"
+- name: Copying over ceph.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/ceph.conf.j2"
       - "/etc/kolla/config/ceph.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/ceph.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/ceph.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/ceph.conf"
-
-- name: Copying over ceph-osd JSON configuration file
-  template:
-    src: "ceph-osd.json.j2"
-    dest: "{{ node_config_directory }}/ceph-osd/config.json"
+    dest: "{{ node_config_directory }}/{{ item }}/ceph.conf"
+  with_items:
+    - "ceph-mon"
+    - "ceph-osd"
diff --git a/ansible/roles/cinder/tasks/config.yml b/ansible/roles/cinder/tasks/config.yml
index 8112be4698..5c6e8305e1 100644
--- a/ansible/roles/cinder/tasks/config.yml
+++ b/ansible/roles/cinder/tasks/config.yml
@@ -1,104 +1,39 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "cinder-api"
-    config_source:
-      - "roles/{{ project_name }}/templates/cinder.conf.j2"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "cinder-api"
+    - "cinder-backup"
+    - "cinder-scheduler"
+    - "cinder-volume"
+
+- name: Copying over config.json files for services
+  template:
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "cinder-api"
+    - "cinder-backup"
+    - "cinder-scheduler"
+    - "cinder-volume"
+
+- name: Copying over cinder.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/cinder.conf.j2"
       - "/etc/kolla/config/global.conf"
       - "/etc/kolla/config/database.conf"
       - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/cinder.conf"
-  when: inventory_hostname in groups['cinder-api']
-
-- name: Copying Cinder API JSON configuration file
-  template:
-    src: "roles/cinder/templates/cinder-api.json.j2"
-    dest: "{{ node_config_directory }}/cinder-api/config.json"
-  when: inventory_hostname in groups['cinder-api']
-
-- include: ../../config.yml
-  vars:
-    service_name: "cinder-backup"
-    config_source:
-      - "roles/{{ project_name }}/templates/cinder.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/cinder.conf"
-  when: inventory_hostname in groups['cinder-backup']
-
-- name: Copying Cinder Backup JSON configuration file
-  template:
-    src: "roles/cinder/templates/cinder-backup.json.j2"
-    dest: "{{ node_config_directory }}/cinder-backup/config.json"
-  when: inventory_hostname in groups['cinder-backup']
-
-- include: ../../config.yml
-  vars:
-    service_name: "cinder-scheduler"
-    config_source:
-      - "roles/{{ project_name }}/templates/cinder.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/cinder.conf"
-  when: inventory_hostname in groups['cinder-scheduler']
-
-- name: Copying Cinder Scheduler JSON configuration file
-  template:
-    src: "roles/cinder/templates/cinder-scheduler.json.j2"
-    dest: "{{ node_config_directory }}/cinder-scheduler/config.json"
-  when: inventory_hostname in groups['cinder-scheduler']
-
-- include: ../../config.yml
-  vars:
-    service_name: "cinder-volume"
-    config_source:
-      - "roles/{{ project_name }}/templates/cinder.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/cinder.conf"
-  when: inventory_hostname in groups['cinder-volume']
-
-- name: Copying Cinder Volume JSON configuration file
-  template:
-    src: "roles/cinder/templates/cinder-volume.json.j2"
-    dest: "{{ node_config_directory }}/cinder-volume/config.json"
-  when: inventory_hostname in groups['cinder-volume']
+      - "/etc/kolla/config/cinder.conf"
+      - "/etc/kolla/config/cinder/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/cinder.conf"
+  with_items:
+    - "cinder-api"
+    - "cinder-backup"
+    - "cinder-scheduler"
+    - "cinder-volume"
diff --git a/ansible/roles/common/tasks/config.yml b/ansible/roles/common/tasks/config.yml
index 05587ca7f7..d9bc821f98 100755
--- a/ansible/roles/common/tasks/config.yml
+++ b/ansible/roles/common/tasks/config.yml
@@ -1,16 +1,20 @@
 ---
-- name: Ensuring config directory exists
+- name: Ensuring config directories exist
   file:
-    path: "{{ node_config_directory }}/rsyslog/"
+    path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
-    recurse: "yes"
+    recurse: yes
+  with_items:
+    - "rsyslog"
 
-- name: Copying over rsyslog JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "rsyslog.json.j2"
-    dest: "{{ node_config_directory }}/rsyslog/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "rsyslog"
 
-- name: Copying over config(s)
+- name: Copying over rsyslog.conf
   template:
     src: "rsyslog.conf.j2"
     dest: "{{ node_config_directory }}/rsyslog/rsyslog.conf"
diff --git a/ansible/roles/config.yml b/ansible/roles/config.yml
deleted file mode 100644
index a0cd5ea2ae..0000000000
--- a/ansible/roles/config.yml
+++ /dev/null
@@ -1,24 +0,0 @@
----
-- name: Ensuring templates config directory exists
-  file:
-    path: "{{ node_templates_directory }}/{{ service_name }}"
-    state: "directory"
-    recurse: yes
-
-- name: Ensuring config directory exists
-  file:
-    path: "{{ node_config_directory }}/{{ service_name }}"
-    state: "directory"
-
-- name: Copying over config(s)
-  template:
-    src: "{{ item.0 }}"
-    dest: "{{ item.1 }}"
-  with_together:
-    - config_source
-    - config_template_dest
-
-- name: Merging the config files and saving to the final destination
-  merge_configs:
-    sources: "{{ config_template_dest }}"
-    dest: "{{ config_dest }}"
diff --git a/ansible/roles/glance/tasks/config.yml b/ansible/roles/glance/tasks/config.yml
index 095559dbef..dccee18d39 100644
--- a/ansible/roles/glance/tasks/config.yml
+++ b/ansible/roles/glance/tasks/config.yml
@@ -1,48 +1,47 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "glance-registry"
-    config_source:
-      - "roles/glance/templates/glance-registry.conf.j2"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "glance-api"
+    - "glance-registry"
+
+- name: Copying over config.json files for services
+  template:
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "glance-api"
+    - "glance-registry"
+
+- name: Copying over glance-api.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/glance-api.conf.j2"
       - "/etc/kolla/config/global.conf"
       - "/etc/kolla/config/database.conf"
       - "/etc/kolla/config/messaging.conf"
       - "/etc/kolla/config/glance.conf"
-      - "/etc/kolla/config/glance/glance-registry.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/glance-registry/glance.conf_minimal"
-      - "{{ node_templates_directory }}/glance-registry/glance.conf_global"
-      - "{{ node_templates_directory }}/glance-registry/glance.conf_database"
-      - "{{ node_templates_directory }}/glance-registry/glance.conf_messaging"
-      - "{{ node_templates_directory }}/glance-registry/glance.conf_augment"
-      - "{{ node_templates_directory }}/glance-registry/glance-registry.conf_augment"
-    config_dest: "{{ node_config_directory }}/glance-registry/glance-registry.conf"
+      - "/etc/kolla/config/glance/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/glance-api.conf"
+  with_items:
+    - "glance-api"
 
-- name: Copying over Glance Registry JSON configuration file
-  template:
-    src: "roles/glance/templates/glance-registry.json.j2"
-    dest: "{{ node_config_directory }}/glance-registry/config.json"
-
-- include: ../../config.yml
-  vars:
-    service_name: "glance-api"
-    config_source:
-      - "roles/glance/templates/glance-api.conf.j2"
+- name: Copying over glance-registry.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/glance-registry.conf.j2"
       - "/etc/kolla/config/global.conf"
       - "/etc/kolla/config/database.conf"
       - "/etc/kolla/config/messaging.conf"
       - "/etc/kolla/config/glance.conf"
-      - "/etc/kolla/config/glance/glance-api.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/glance-api/glance.conf_minimal"
-      - "{{ node_templates_directory }}/glance-api/glance.conf_global"
-      - "{{ node_templates_directory }}/glance-api/glance.conf_database"
-      - "{{ node_templates_directory }}/glance-api/glance.conf_messaging"
-      - "{{ node_templates_directory }}/glance-api/glance.conf_augment"
-      - "{{ node_templates_directory }}/glance-api/glance-api.conf_augment"
-    config_dest: "{{ node_config_directory }}/glance-api/glance-api.conf"
-
-- name: Copying over Glance API JSON configuration file
-  template:
-    src: "roles/glance/templates/glance-api.json.j2"
-    dest: "{{ node_config_directory }}/glance-api/config.json"
+      - "/etc/kolla/config/glance/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/glance-registry.conf"
+  with_items:
+    - "glance-registry"
diff --git a/ansible/roles/haproxy/tasks/config.yml b/ansible/roles/haproxy/tasks/config.yml
index d5e3711a66..9df07fd1ec 100755
--- a/ansible/roles/haproxy/tasks/config.yml
+++ b/ansible/roles/haproxy/tasks/config.yml
@@ -1,36 +1,31 @@
 ---
-- name: Ensuring config directory exists
-  file:
-    path: "{{ node_config_directory }}/haproxy/"
-    state: "directory"
-    recurse: "yes"
-
-- name: Copying over config(s)
-  template:
-    src: "haproxy.cfg.j2"
-    dest: "{{ node_config_directory }}/haproxy/haproxy.cfg"
-
-- name: Copying haproxy JSON configuration file
-  template:
-    src: "haproxy.json.j2"
-    dest: "{{ node_config_directory }}/haproxy/config.json"
-
 - name: Allowing non-local IP binding
   sysctl: name="net.ipv4.ip_nonlocal_bind" value=1 sysctl_set=yes
   when: set_sysctl | bool
 
-- name: Ensuring config directory exists
+- name: Ensuring config directories exist
   file:
-    path: "{{ node_config_directory }}/keepalived/"
+    path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
-    recurse: "yes"
+    recurse: yes
+  with_items:
+    - "keepalived"
+    - "haproxy"
 
-- name: Copying keepalived JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "keepalived.json.j2"
-    dest: "{{ node_config_directory }}/keepalived/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "keepalived"
+    - "haproxy"
 
-- name: Copying over config(s)
+- name: Copying over haproxy.cfg
+  template:
+    src: "haproxy.cfg.j2"
+    dest: "{{ node_config_directory }}/haproxy/haproxy.cfg"
+
+- name: Copying over keepalived.conf
   template:
     src: "keepalived.conf.j2"
     dest: "{{ node_config_directory }}/keepalived/keepalived.conf"
diff --git a/ansible/roles/heat/tasks/config.yml b/ansible/roles/heat/tasks/config.yml
index 4bc8787c4f..543598694a 100644
--- a/ansible/roles/heat/tasks/config.yml
+++ b/ansible/roles/heat/tasks/config.yml
@@ -1,70 +1,36 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "heat-engine"
-    config_source:
-      - "roles/heat/templates/heat.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/heat.conf"
-      - "/etc/kolla/config/heat/heat-engine.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/heat-engine/heat.conf_minimal"
-      - "{{ node_templates_directory }}/heat-engine/heat.conf_global"
-      - "{{ node_templates_directory }}/heat-engine/heat.conf_database"
-      - "{{ node_templates_directory }}/heat-engine/heat.conf_augment"
-      - "{{ node_templates_directory }}/heat-engine/heat-engine.conf_augment"
-    config_dest: "{{ node_config_directory }}/heat-engine/heat.conf"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "heat-api"
+    - "heat-api-cfn"
+    - "heat-engine"
 
-- name: Copying Heat Engine JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "roles/heat/templates/heat-engine.json.j2"
-    dest: "{{ node_config_directory }}/heat-engine/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "heat-api"
+    - "heat-api-cfn"
+    - "heat-engine"
 
-- include: ../../config.yml
-  vars:
-    service_name: "heat-api"
-    config_source:
-      - "roles/heat/templates/heat.conf.j2"
+- name: Copying over heat.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/heat.conf.j2"
       - "/etc/kolla/config/global.conf"
       - "/etc/kolla/config/database.conf"
       - "/etc/kolla/config/messaging.conf"
       - "/etc/kolla/config/heat.conf"
-      - "/etc/kolla/config/heat/heat-api.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/heat-api/heat.conf_minimal"
-      - "{{ node_templates_directory }}/heat-api/heat.conf_global"
-      - "{{ node_templates_directory }}/heat-api/heat.conf_database"
-      - "{{ node_templates_directory }}/heat-api/heat.conf_messaging"
-      - "{{ node_templates_directory }}/heat-api/heat.conf_augment"
-      - "{{ node_templates_directory }}/heat-api/heat-api.conf_augment"
-    config_dest: "{{ node_config_directory }}/heat-api/heat.conf"
-
-- name: Copying Heat API JSON configuration file
-  template:
-    src: "roles/heat/templates/heat-api.json.j2"
-    dest: "{{ node_config_directory }}/heat-api/config.json"
-
-- include: ../../config.yml
-  vars:
-    service_name: "heat-api-cfn"
-    config_source:
-      - "roles/heat/templates/heat.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/heat.conf"
-      - "/etc/kolla/config/heat/heat-api-cfn.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/heat-api-cfn/heat.conf_minimal"
-      - "{{ node_templates_directory }}/heat-api-cfn/heat.conf_global"
-      - "{{ node_templates_directory }}/heat-api-cfn/heat.conf_database"
-      - "{{ node_templates_directory }}/heat-api-cfn/heat.conf_messaging"
-      - "{{ node_templates_directory }}/heat-api-cfn/heat.conf_augment"
-      - "{{ node_templates_directory }}/heat-api-cfn/heat-api-cfn.conf_augment"
-    config_dest: "{{ node_config_directory }}/heat-api-cfn/heat.conf"
-
-- name: Copying Heat-api-cfn JSON configuration file
-  template:
-    src: "roles/heat/templates/heat-api-cfn.json.j2"
-    dest: "{{ node_config_directory }}/heat-api-cfn/config.json"
+      - "/etc/kolla/config/heat/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/heat.conf"
+  with_items:
+    - "heat-api"
+    - "heat-api-cfn"
+    - "heat-engine"
diff --git a/ansible/roles/horizon/tasks/config.yml b/ansible/roles/horizon/tasks/config.yml
index 87ce2976e5..4018c439a1 100644
--- a/ansible/roles/horizon/tasks/config.yml
+++ b/ansible/roles/horizon/tasks/config.yml
@@ -1,21 +1,25 @@
 ---
-- name: Ensuring config directory exists
+- name: Ensuring config directories exist
   file:
-    path: "{{ node_config_directory }}/horizon/"
+    path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
-    recurse: "yes"
+    recurse: yes
+  with_items:
+    - "horizon"
 
-- name: Copying horizon JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "horizon.json.j2"
-    dest: "{{ node_config_directory }}/horizon/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "horizon"
 
-- name: Copying over config(s)
+- name: Copying over horizon.conf
   template:
     src: "horizon.conf.j2"
     dest: "{{ node_config_directory }}/horizon/horizon.conf"
 
-- name: Copying over config(s)
+- name: Copying over local_settings
   template:
     src: "local_settings.j2"
     dest: "{{ node_config_directory }}/horizon/local_settings"
diff --git a/ansible/roles/ironic/tasks/config.yml b/ansible/roles/ironic/tasks/config.yml
index 5216db27ad..416157762d 100644
--- a/ansible/roles/ironic/tasks/config.yml
+++ b/ansible/roles/ironic/tasks/config.yml
@@ -1,84 +1,38 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "ironic-api"
-    config_source:
-      - "roles/ironic/templates/ironic.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/ironic.conf"
-  when: inventory_hostname in groups['ironic-api']
-
-- name: Copying Ironic API JSON configuration file
-  template:
-    src: "roles/ironic/templates/ironic-api.json.j2"
-    dest: "{{ node_config_directory }}/ironic-api/config.json"
-
-- include: ../../config.yml
-  vars:
-    service_name: "ironic-conductor"
-    config_source:
-      - "roles/ironic/templates/ironic.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/ironic.conf"
-  when: inventory_hostname in groups['ironic-conductor']
-
-- name: Copying Ironic conductor JSON configuration file
-  template:
-    src: "roles/ironic/templates/ironic-conductor.json.j2"
-    dest: "{{ node_config_directory }}/ironic-conductor/config.json"
-
-- include: ../../config.yml
-  vars:
-    service_name: "ironic-discoverd"
-    config_source:
-      - "roles/ironic/templates/discoverd.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}/discoverd.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/discoverd.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/discoverd.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/discoverd.conf"
-  when: inventory_hostname in groups['ironic-discoverd']
-
-- name: Copying Ironic discoverd JSON configuration file
-  template:
-    src: "roles/ironic/templates/ironic-discoverd.json.j2"
-    dest: "{{ node_config_directory }}/ironic-discoverd/config.json"
-
-- name: Ensuring config directory exists
+- name: Ensuring config directories exist
   file:
-    path: "{{ node_config_directory }}/ironic-pxe/"
+    path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
-    recurse: "yes"
+    recurse: yes
+  with_items:
+    - "ironic-api"
+    - "ironic-conductor"
+    - "ironic-discoverd"
+    - "ironic-pxe"
 
-- name: Copying Ironic PXE JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "roles/ironic/templates/ironic-pxe.json.j2"
-    dest: "{{ node_config_directory }}/ironic-pxe/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "ironic-api"
+    - "ironic-conductor"
+    - "ironic-discoverd"
+    - "ironic-pxe"
+
+- name: Copying over ironic.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/ironic.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/database.conf"
+      - "/etc/kolla/config/messaging.conf"
+      - "/etc/kolla/config/ironic.conf"
+      - "/etc/kolla/config/ironic/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/ironic.conf"
+  with_items:
+    - "ironic-api"
+    - "ironic-conductor"
+    - "ironic-discoverd"
diff --git a/ansible/roles/keystone/tasks/config.yml b/ansible/roles/keystone/tasks/config.yml
index f880236121..7cd81b0e1e 100644
--- a/ansible/roles/keystone/tasks/config.yml
+++ b/ansible/roles/keystone/tasks/config.yml
@@ -1,27 +1,34 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "keystone"
-    config_source:
-      - "roles/keystone/templates/keystone.conf.j2"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "keystone"
+
+- name: Copying over config.json files for services
+  template:
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "keystone"
+
+- name: Copying over keystone.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/keystone.conf.j2"
       - "/etc/kolla/config/global.conf"
       - "/etc/kolla/config/database.conf"
       - "/etc/kolla/config/messaging.conf"
       - "/etc/kolla/config/keystone.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/keystone/keystone.conf_minimal"
-      - "{{ node_templates_directory }}/keystone/keystone.conf_global"
-      - "{{ node_templates_directory }}/keystone/keystone.conf_database"
-      - "{{ node_templates_directory }}/keystone/keystone.conf_messaging"
-      - "{{ node_templates_directory }}/keystone/keystone.conf_augment"
-    config_dest: "{{ node_config_directory }}/keystone/keystone.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/keystone.conf"
+  with_items:
+    - "keystone"
 
-- name: Copying over Keystone JSON configuration file
-  template:
-    src: "roles/keystone/templates/keystone.json.j2"
-    dest: "{{ node_config_directory }}/keystone/config.json"
-
-- name: Copying over config(s)
+- name: Copying over wsgi-keystone.conf
   template:
     src: "wsgi-keystone.conf.j2"
     dest: "{{ node_config_directory }}/keystone/wsgi-keystone.conf"
diff --git a/ansible/roles/magnum/tasks/config.yml b/ansible/roles/magnum/tasks/config.yml
index 54166d3d61..a682766a59 100644
--- a/ansible/roles/magnum/tasks/config.yml
+++ b/ansible/roles/magnum/tasks/config.yml
@@ -1,50 +1,33 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "magnum-api"
-    config_source:
-      - "roles/{{ project_name }}/templates/magnum.conf.j2"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "magnum-api"
+    - "magnum-conductor"
+
+- name: Copying over config.json files for services
+  template:
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "magnum-api"
+    - "magnum-conductor"
+
+- name: Copying over magnum.conf
+  merge_configs:
+    vars:
+      service_name: "magnum-api"
+    sources:
+      - "{{ role_path }}/templates/magnum.conf.j2"
       - "/etc/kolla/config/global.conf"
       - "/etc/kolla/config/database.conf"
       - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/magnum.conf"
-  when: inventory_hostname in groups['magnum-api']
-
-- name: Copying over Magnum API JSON configuration file
-  template:
-    src: "roles/magnum/templates/magnum-api.json.j2"
-    dest: "{{ node_config_directory }}/magnum-api/config.json"
-
-- include: ../../config.yml
-  vars:
-    service_name: "magnum-conductor"
-    config_source:
-      - "roles/{{ project_name }}/templates/magnum.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/magnum.conf"
-  when: inventory_hostname in groups['magnum-conductor']
-
-- name: Copying over Magnum conductor JSON configuration file
-  template:
-    src: "roles/magnum/templates/magnum-conductor.json.j2"
-    dest: "{{ node_config_directory }}/magnum-conductor/config.json"
+      - "/etc/kolla/config/magnum.conf"
+      - "/etc/kolla/config/magnum/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/magnum.conf"
+  with_items:
+    - "magnum-api"
+    - "magnum-conductor"
diff --git a/ansible/roles/mariadb/tasks/config.yml b/ansible/roles/mariadb/tasks/config.yml
index e41da656ad..edee5cdc72 100644
--- a/ansible/roles/mariadb/tasks/config.yml
+++ b/ansible/roles/mariadb/tasks/config.yml
@@ -1,14 +1,25 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "mariadb"
-    config_source:
-      - "roles/mariadb/templates/galera.cnf.j2"
-    config_template_dest:
-      - "{{ node_templates_directory }}/mariadb/galera.cnf_minimal"
-    config_dest: "{{ node_config_directory }}/mariadb/galera.cnf"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "mariadb"
 
-- name: Copying Mariadb JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "roles/mariadb/templates/mariadb.json.j2"
-    dest: "{{ node_config_directory }}/mariadb/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "mariadb"
+
+- name: Copying over galera.cnf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/galera.cnf.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/galera.cnf"
+  with_items:
+    - "mariadb"
diff --git a/ansible/roles/memcached/tasks/config.yml b/ansible/roles/memcached/tasks/config.yml
index 4f97e364d4..f721633c7d 100644
--- a/ansible/roles/memcached/tasks/config.yml
+++ b/ansible/roles/memcached/tasks/config.yml
@@ -1,11 +1,15 @@
 ---
-- name: Ensuring config directory exists
+- name: Ensuring config directories exist
   file:
-    path: "{{ node_config_directory }}/memcached/"
+    path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
-    recurse: "yes"
+    recurse: yes
+  with_items:
+    - "memcached"
 
-- name: Copying over memcached JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "memcached.json.j2"
-    dest: "{{ node_config_directory }}/memcached/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "memcached"
diff --git a/ansible/roles/murano/tasks/config.yml b/ansible/roles/murano/tasks/config.yml
index 0033972ba1..edb848f103 100644
--- a/ansible/roles/murano/tasks/config.yml
+++ b/ansible/roles/murano/tasks/config.yml
@@ -1,52 +1,33 @@
 ---
-- include: ../../config.yml
-  vars:
-    service_name: "murano-engine"
-    config_source:
-      - "roles/{{ project_name }}/templates/murano.conf.j2"
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "murano-api"
+    - "murano-engine"
+
+- name: Copying over config.json files for services
+  template:
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "murano-api"
+    - "murano-engine"
+
+- name: Copying over murano.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/murano.conf.j2"
       - "/etc/kolla/config/global.conf"
       - "/etc/kolla/config/database.conf"
       - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/murano.conf"
-  when: inventory_hostname in groups['murano-engine']
-
-- name: Copying over murano-engine JSON configuration file
-  template:
-    src: "murano-engine.json.j2"
-    dest: "{{ node_config_directory }}/murano-engine/config.json"
-  when: inventory_hostname in groups['murano-engine']
-
-- include: ../../config.yml
-  vars:
-    service_name: "murano-api"
-    config_source:
-      - "roles/{{ project_name }}/templates/murano.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/murano.conf"
-  when: inventory_hostname in groups['murano-api']
-
-- name: Copying over murano-api JSON configuration file
-  template:
-    src: "murano-api.json.j2"
-    dest: "{{ node_config_directory }}/murano-api/config.json"
-  when: inventory_hostname in groups['murano-api']
+      - "/etc/kolla/config/murano.conf"
+      - "/etc/kolla/config/murano/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/murano.conf"
+  with_items:
+    - "murano-api"
+    - "murano-engine"
diff --git a/ansible/roles/neutron/tasks/config.yml b/ansible/roles/neutron/tasks/config.yml
index a0fe2f92c1..62aaa3e104 100644
--- a/ansible/roles/neutron/tasks/config.yml
+++ b/ansible/roles/neutron/tasks/config.yml
@@ -14,190 +14,97 @@
     - set_sysctl | bool
     - inventory_hostname in groups['neutron-agents']
 
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-server"
-    config_source:
-      - "roles/{{ project_name }}/templates/neutron.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/neutron.conf"
-  when: inventory_hostname in groups['neutron-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-server"
-    config_source:
-      - "roles/{{ project_name }}/templates/ml2_conf.ini.j2"
-      - "/etc/kolla/config/{{ project_name }}/ml2_conf.ini"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/ml2_conf.ini_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/ml2_conf.ini_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/ml2_conf.ini"
-  when: inventory_hostname in groups['neutron-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-agents"
-    config_source:
-      - "roles/{{ project_name }}/templates/neutron.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/neutron.conf"
-  when: inventory_hostname in groups['neutron-agents']
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-agents"
-    config_source:
-      - "roles/{{ project_name }}/templates/dhcp_agent.ini.j2"
-      - "/etc/kolla/config/{{ project_name }}/dhcp_agent.ini"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/dhcp_agent.ini_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/dhcp_agent.ini_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/dhcp_agent.ini"
-  when: inventory_hostname in groups['neutron-agents']
-
-- name: Copying over config(s)
-  template:
-    src: "dnsmasq.conf.j2"
-    dest: "{{ node_config_directory }}/neutron-agents/dnsmasq.conf"
-  when: inventory_hostname in groups['neutron-agents']
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-agents"
-    config_source:
-      - "roles/{{ project_name }}/templates/l3_agent.ini.j2"
-      - "/etc/kolla/config/{{ project_name }}/l3_agent.ini"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/l3_agent.ini_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/l3_agent.ini_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/l3_agent.ini"
-  when: inventory_hostname in groups['neutron-agents']
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-agents"
-    config_source:
-      - "roles/{{ project_name }}/templates/metadata_agent.ini.j2"
-      - "/etc/kolla/config/{{ project_name }}/metadata_agent.ini"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/metadata_agent.ini_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/metadata_agent.ini_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/metadata_agent.ini"
-  when: inventory_hostname in groups['neutron-agents']
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-agents"
-    config_source:
-      - "roles/{{ project_name }}/templates/ml2_conf.ini.j2"
-      - "/etc/kolla/config/{{ project_name }}/ml2_conf.ini"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/ml2_conf.ini_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/ml2_conf.ini_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/ml2_conf.ini"
-  when: inventory_hostname in groups['neutron-agents']
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-{{ neutron_plugin_agent }}-agent"
-    config_source:
-      - "roles/{{ project_name }}/templates/neutron.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/neutron.conf"
-  when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents'])
-
-- include: ../../config.yml
-  vars:
-    service_name: "neutron-{{ neutron_plugin_agent }}-agent"
-    config_source:
-      - "roles/{{ project_name }}/templates/ml2_conf.ini.j2"
-      - "/etc/kolla/config/{{ project_name }}/ml2_conf.ini"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/ml2_conf.ini_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/ml2_conf.ini_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/ml2_conf.ini"
-  when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents'])
-
-- name: Copying Neutron Agents JSON configuration file
-  template:
-    src: "roles/neutron/templates/neutron-agents.json.j2"
-    dest: "{{ node_config_directory }}/neutron-agents/config.json"
-  when: inventory_hostname in groups['neutron-agents']
-
-- name: Copying Neutron Server JSON configuration file
-  template:
-    src: "roles/neutron/templates/neutron-server.json.j2"
-    dest: "{{ node_config_directory }}/neutron-server/config.json"
-  when: inventory_hostname in groups['neutron-server']
-
-- name: Copying Neutron OpenVSwitch JSON configuration file
-  template:
-    src: "roles/neutron/templates/neutron-openvswitch-agent.json.j2"
-    dest: "{{ node_config_directory }}/neutron-openvswitch-agent/config.json"
-  when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents'])
-        and neutron_plugin_agent == "openvswitch"
-
-- name: Ensuring config directories exists
+- name: Ensuring config directories exist
   file:
     path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
+    recurse: yes
   with_items:
+    - "neutron-agents"
+    - "neutron-linuxbridge-agent"
+    - "neutron-openvswitch-agent"
+    - "neutron-server"
     - "openvswitch-db-server"
     - "openvswitch-vswitchd"
-  when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents'])
-        and neutron_plugin_agent == "openvswitch"
 
-- name: Copying openvswitch-db-server JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "openvswitch-db-server.json.j2"
-    dest: "{{ node_config_directory }}/openvswitch-db-server/config.json"
-  when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents'])
-        and neutron_plugin_agent == "openvswitch"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "neutron-agents"
+    - "neutron-linuxbridge-agent"
+    - "neutron-openvswitch-agent"
+    - "neutron-server"
+    - "openvswitch-db-server"
+    - "openvswitch-vswitchd"
 
-- name: Copying openvswitch-vswitchd JSON configuration file
-  template:
-    src: "openvswitch-vswitchd.json.j2"
-    dest: "{{ node_config_directory }}/openvswitch-vswitchd/config.json"
-  when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents'])
-        and neutron_plugin_agent == "openvswitch"
+- name: Copying over neutron.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/neutron.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/database.conf"
+      - "/etc/kolla/config/messaging.conf"
+      - "/etc/kolla/config/neutron.conf"
+      - "/etc/kolla/config/neutron/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/neutron.conf"
+  with_items:
+    - "neutron-agents"
+    - "neutron-linuxbridge-agent"
+    - "neutron-openvswitch-agent"
+    - "neutron-server"
 
-- name: Copying Neutron Linuxbridge JSON configuration file
+- name: Copying over ml2_conf.ini
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/ml2_conf.ini.j2"
+      - "/etc/kolla/config/neutron/ml2_conf.ini"
+    dest: "{{ node_config_directory }}/{{ item }}/ml2_conf.ini"
+  with_items:
+    - "neutron-server"
+    - "neutron-agents"
+    - "neutron-linuxbridge-agent"
+    - "neutron-openvswitch-agent"
+
+- name: Copying over dhcp_agent.ini
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/dhcp_agent.ini.j2"
+      - "/etc/kolla/config/neutron/dhcp_agent.ini"
+    dest: "{{ node_config_directory }}/{{ item }}/dhcp_agent.ini"
+  with_items:
+    - "neutron-agents"
+
+- name: Copying over dnsmasq.conf
   template:
-    src: "roles/neutron/templates/neutron-server.json.j2"
-    dest: "{{ node_config_directory }}/neutron-linuxbridge-agent/config.json"
-  when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents'])
-        and neutron_plugin_agent == "linuxbridge"
+    src: "dnsmasq.conf.j2"
+    dest: "{{ node_config_directory }}/neutron-agents/dnsmasq.conf"
+
+- name: Copying over l3_agent.ini
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/l3_agent.ini.j2"
+      - "/etc/kolla/config/neutron/l3_agent.ini"
+    dest: "{{ node_config_directory }}/{{ item }}/l3_agent.ini"
+  with_items:
+    - "neutron-agents"
+
+- name: Copying over metadata_agent.ini
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/metadata_agent.ini.j2"
+      - "/etc/kolla/config/neutron/metadata_agent.ini"
+    dest: "{{ node_config_directory }}/{{ item }}/metadata_agent.ini"
+  with_items:
+    - "neutron-agents"
diff --git a/ansible/roles/nova/tasks/config.yml b/ansible/roles/nova/tasks/config.yml
index 298270cbde..6d7a742d8a 100644
--- a/ansible/roles/nova/tasks/config.yml
+++ b/ansible/roles/nova/tasks/config.yml
@@ -17,210 +17,57 @@
     - set_sysctl | bool
     - inventory_hostname in groups['neutron-agents']
 
-- include: ../../config.yml
-  vars:
-    service_name: "nova-api"
-    config_source:
-      - "roles/{{ project_name }}/templates/nova.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when: inventory_hostname in groups['nova-api']
-
-- name: Copying Nova API JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-api.json.j2"
-    dest: "{{ node_config_directory }}/nova-api/config.json"
-  when: inventory_hostname in groups['nova-api']
-
-- include: ../../config.yml
-  vars:
-    service_name: "nova-conductor"
-    config_source:
-      - "roles/{{ project_name }}/templates/nova.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when: inventory_hostname in groups['nova-conductor']
-
-- name: Copying Nova Conductor JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-conductor.json.j2"
-    dest: "{{ node_config_directory }}/nova-conductor/config.json"
-  when: inventory_hostname in groups['nova-conductor']
-
-- include: ../../config.yml
-  vars:
-    service_name: "nova-consoleauth"
-    config_source:
-      - "roles/{{ project_name }}/templates/nova.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when: inventory_hostname in groups['nova-consoleauth']
-
-- name: Copying Nova Consoleauth JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-consoleauth.json.j2"
-    dest: "{{ node_config_directory }}/nova-consoleauth/config.json"
-  when: inventory_hostname in groups['nova-consoleauth']
-
-- include: ../../config.yml
-  vars:
-    service_name: "nova-scheduler"
-    config_source:
-      - "roles/{{ project_name }}/templates/nova.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when: inventory_hostname in groups['nova-scheduler']
-
-- name: Copying Nova Scheduler JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-scheduler.json.j2"
-    dest: "{{ node_config_directory }}/nova-scheduler/config.json"
-  when: inventory_hostname in groups['nova-scheduler']
-
-- include: ../../config.yml
-  vars:
-    service_name: "nova-compute"
-    config_source:
-      - "roles/{{ project_name }}/templates/nova.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when: inventory_hostname in groups['compute']
-
-- name: Copying Nova Compute JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-compute.json.j2"
-    dest: "{{ node_config_directory }}/nova-compute/config.json"
-  when: inventory_hostname in groups['compute']
-
-- include: ../../config.yml
-  vars:
-    service_name: "nova-novncproxy"
-    config_source:
-      - "roles/{{ project_name }}/templates/nova.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when:
-    - inventory_hostname in groups['nova-novncproxy']
-    - nova_console == 'novnc'
-
-- name: Copying Nova Novncproxy JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-novncproxy.json.j2"
-    dest: "{{ node_config_directory }}/nova-novncproxy/config.json"
-  when:
-    - inventory_hostname in groups['nova-novncproxy']
-    - nova_console == 'novnc'
-
-- include: ../../config.yml
-  vars:
-    service_name: "nova-spicehtml5proxy"
-    config_source:
-      - "roles/{{ project_name }}/templates/nova.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/database.conf"
-      - "/etc/kolla/config/messaging.conf"
-      - "/etc/kolla/config/{{ project_name }}.conf"
-      - "/etc/kolla/config/{{ project_name }}/{{ service_name }}.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_database"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_messaging"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ project_name }}.conf_augment"
-      - "{{ node_templates_directory }}/{{ service_name }}/{{ service_name }}.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/nova.conf"
-  when:
-    - inventory_hostname in groups['nova-spicehtml5proxy']
-    - nova_console == 'spice'
-
-- name: Copying Nova spicehtml5proxy JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-spicehtml5proxy.json.j2"
-    dest: "{{ node_config_directory }}/nova-spicehtml5proxy/config.json"
-  when:
-    - inventory_hostname in groups['nova-spicehtml5proxy']
-    - nova_console == 'spice'
-
-- name: Ensuring config directory exists
+- name: Ensuring config directories exist
   file:
-    path: "{{ node_config_directory }}/nova-libvirt"
+    path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
-  when: inventory_hostname in groups['compute']
+    recurse: yes
+  with_items:
+    - "nova-api"
+    - "nova-compute"
+    - "nova-conductor"
+    - "nova-consoleauth"
+    - "nova-libvirt"
+    - "nova-novncproxy"
+    - "nova-scheduler"
+    - "nova-spicehtml5proxy"
 
-- name: Copying over config(s)
+- name: Copying over config.json files for services
   template:
-    src: "libvirtd.conf.j2"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "nova-api"
+    - "nova-compute"
+    - "nova-conductor"
+    - "nova-consoleauth"
+    - "nova-libvirt"
+    - "nova-novncproxy"
+    - "nova-scheduler"
+    - "nova-spicehtml5proxy"
+
+- name: Copying over nova.conf
+  merge_configs:
+    vars:
+      service_name: "{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/nova.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/database.conf"
+      - "/etc/kolla/config/messaging.conf"
+      - "/etc/kolla/config/nova.conf"
+      - "/etc/kolla/config/nova/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/{{ item }}/nova.conf"
+  with_items:
+    - "nova-api"
+    - "nova-compute"
+    - "nova-conductor"
+    - "nova-consoleauth"
+    - "nova-novncproxy"
+    - "nova-scheduler"
+    - "nova-spicehtml5proxy"
+
+- name: Copying over libvirtd.conf
+  template:
+    src: "{{ role_path }}/templates/libvirtd.conf.j2"
     dest: "{{ node_config_directory }}/nova-libvirt/libvirtd.conf"
-  when: inventory_hostname in groups['compute']
-
-- name: Copying Nova Libvirt JSON configuration file
-  template:
-    src: "roles/nova/templates/nova-libvirt.json.j2"
-    dest: "{{ node_config_directory }}/nova-libvirt/config.json"
-  when: inventory_hostname in groups['compute']
diff --git a/ansible/roles/rabbitmq/tasks/config.yml b/ansible/roles/rabbitmq/tasks/config.yml
index 81d3eedb98..f0f6144a94 100644
--- a/ansible/roles/rabbitmq/tasks/config.yml
+++ b/ansible/roles/rabbitmq/tasks/config.yml
@@ -1,23 +1,24 @@
 ---
-- name: Ensuring config directory exists
+- name: Ensuring config directories exist
   file:
-    path: "{{ node_config_directory }}/rabbitmq/"
+    path: "{{ node_config_directory }}/{{ item }}"
     state: "directory"
-    recurse: "yes"
-
-- name: Copying over config(s)
-  template:
-    src: "{{ item.src }}"
-    dest: "{{ item.dest }}"
+    recurse: yes
   with_items:
-     - { src: "rabbitmq-env.conf.j2",
-         dest: "{{ node_config_directory }}/rabbitmq/rabbitmq-env.conf" }
-     - { src: "rabbitmq.config.j2",
-         dest: "{{ node_config_directory }}/rabbitmq/rabbitmq.config" }
-     - { src: "rabbitmq_clusterer.config.j2",
-         dest: "{{ node_config_directory }}/rabbitmq/rabbitmq_clusterer.config" }
+    - "rabbitmq"
 
-- name: Copying Rabbitmq JSON configuration file
+- name: Copying over config.json files for services
   template:
-    src: "roles/rabbitmq/templates/rabbitmq.json.j2"
-    dest: "{{ node_config_directory }}/rabbitmq/config.json"
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "rabbitmq"
+
+- name: Copying over rabbitmq*.conf
+  template:
+    src: "{{ item }}.j2"
+    dest: "{{ node_config_directory }}/rabbitmq/{{ item }}"
+  with_items:
+     - "rabbitmq-env.conf"
+     - "rabbitmq.config"
+     - "rabbitmq_clusterer.config"
diff --git a/ansible/roles/swift/tasks/config.yml b/ansible/roles/swift/tasks/config.yml
index 087c7042a4..29410f78a7 100644
--- a/ansible/roles/swift/tasks/config.yml
+++ b/ansible/roles/swift/tasks/config.yml
@@ -1,332 +1,149 @@
 ---
-# TODO(pbourke): There needs to be one swift.conf generated per service for updates to work
-# correctly. Figure out a way (with_items seems to not be allowed when using include)
-- include: ../../config.yml
-  vars:
-    service_name: "swift"
-    config_source:
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item }}"
+    state: "directory"
+    recurse: yes
+  with_items:
+    - "swift"
+    - "swift-account-auditor"
+    - "swift-account-reaper"
+    - "swift-account-replicator"
+    - "swift-account-server"
+    - "swift-container-auditor"
+    - "swift-container-replicator"
+    - "swift-container-server"
+    - "swift-container-updater"
+    - "swift-object-auditor"
+    - "swift-object-expirer"
+    - "swift-object-replicator"
+    - "swift-object-server"
+    - "swift-object-updater"
+    - "swift-proxy-server"
+    - "swift-rsyncd"
+
+- name: Copying over config.json files for services
+  template:
+    src: "{{ item }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item }}/config.json"
+  with_items:
+    - "swift-account-auditor"
+    - "swift-account-reaper"
+    - "swift-account-replicator"
+    - "swift-account-server"
+    - "swift-container-auditor"
+    - "swift-container-replicator"
+    - "swift-container-server"
+    - "swift-container-updater"
+    - "swift-object-auditor"
+    - "swift-object-expirer"
+    - "swift-object-replicator"
+    - "swift-object-server"
+    - "swift-object-updater"
+    - "swift-proxy-server"
+    - "swift-rsyncd"
+
+- name: Copying over swift.conf
+  merge_configs:
+    vars:
+      service_name: "swift-{{ item }}"
+    sources:
       - "roles/swift/templates/swift.conf.j2"
       - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/swift.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/swift.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/swift.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/swift.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/swift.conf"
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-proxy-server"
-    config_source:
-      - "roles/swift/templates/proxy-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/proxy-server.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/proxy-server.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/proxy-server.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/proxy-server.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/proxy-server.conf"
-  when: inventory_hostname in groups['swift-proxy-server']
-
-- name: Copying over swift-proxy-server JSON configuration file
-  template:
-    src: "swift-proxy-server.json.j2"
-    dest: "{{ node_config_directory }}/swift-proxy-server/config.json"
-  when: inventory_hostname in groups['swift-proxy-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-account-server"
-    config_source:
-      - "roles/swift/templates/account-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/account-server.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/account-server.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-server.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-server.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/account-server.conf"
-  when: inventory_hostname in groups['swift-account-server']
-
-- name: Copying over swift-account-server JSON configuration file
-  template:
-    src: "swift-account-server.json.j2"
-    dest: "{{ node_config_directory }}/swift-account-server/config.json"
-  when: inventory_hostname in groups['swift-account-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-account-auditor"
-    config_source:
-      - "roles/swift/templates/account-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/account-auditor.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/account-auditor.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-auditor.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-auditor.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/account-auditor.conf"
-  when: inventory_hostname in groups['swift-account-server']
-
-- name: Copying over swift-account-auditor JSON configuration file
-  template:
-    src: "swift-account-auditor.json.j2"
-    dest: "{{ node_config_directory }}/swift-account-auditor/config.json"
-  when: inventory_hostname in groups['swift-account-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-account-replicator"
-    config_source:
-      - "roles/swift/templates/account-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/account-replicator.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/account-replicator.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-replicator.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-replicator.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/account-replicator.conf"
-  when: inventory_hostname in groups['swift-account-server']
-
-- name: Copying over swift-account-replicator JSON configuration file
-  template:
-    src: "swift-account-replicator.json.j2"
-    dest: "{{ node_config_directory }}/swift-account-replicator/config.json"
-  when: inventory_hostname in groups['swift-account-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-account-reaper"
-    config_source:
-      - "roles/swift/templates/account-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/account-reaper.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/account-reaper.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-reaper.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/account-reaper.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/account-reaper.conf"
-  when: inventory_hostname in groups['swift-account-server']
-
-- name: Copying over swift-account-reaper JSON configuration file
-  template:
-    src: "swift-account-reaper.json.j2"
-    dest: "{{ node_config_directory }}/swift-account-reaper/config.json"
-  when: inventory_hostname in groups['swift-account-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-container-server"
-    config_source:
-      - "roles/swift/templates/container-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/container-server.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/container-server.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-server.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-server.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/container-server.conf"
-  when: inventory_hostname in groups['swift-container-server']
-
-- name: Copying over swift-container-server JSON configuration file
-  template:
-    src: "swift-container-server.json.j2"
-    dest: "{{ node_config_directory }}/swift-container-server/config.json"
-  when: inventory_hostname in groups['swift-container-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-container-auditor"
-    config_source:
-      - "roles/swift/templates/container-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/container-auditor.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/container-auditor.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-auditor.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-auditor.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/container-auditor.conf"
-  when: inventory_hostname in groups['swift-container-server']
-
-- name: Copying over swift-container-auditor JSON configuration file
-  template:
-    src: "swift-container-auditor.json.j2"
-    dest: "{{ node_config_directory }}/swift-container-auditor/config.json"
-  when: inventory_hostname in groups['swift-container-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-container-replicator"
-    config_source:
-      - "roles/swift/templates/container-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/container-replicator.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/container-replicator.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-replicator.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-replicator.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/container-replicator.conf"
-  when: inventory_hostname in groups['swift-container-server']
-
-- name: Copying over swift-container-replicator JSON configuration file
-  template:
-    src: "swift-container-replicator.json.j2"
-    dest: "{{ node_config_directory }}/swift-container-replicator/config.json"
-  when: inventory_hostname in groups['swift-container-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-container-updater"
-    config_source:
-      - "roles/swift/templates/container-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/container-updater.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/container-updater.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-updater.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/container-updater.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/container-updater.conf"
-  when: inventory_hostname in groups['swift-container-server']
-
-- name: Copying over swift-container-updater JSON configuration file
-  template:
-    src: "swift-container-updater.json.j2"
-    dest: "{{ node_config_directory }}/swift-container-updater/config.json"
-  when: inventory_hostname in groups['swift-container-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-object-server"
-    config_source:
-      - "roles/swift/templates/object-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/object-server.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/object-server.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-server.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-server.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/object-server.conf"
-  when: inventory_hostname in groups['swift-object-server']
-
-- name: Copying over swift-object-server JSON configuration file
-  template:
-    src: "swift-object-server.json.j2"
-    dest: "{{ node_config_directory }}/swift-object-server/config.json"
-  when: inventory_hostname in groups['swift-object-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-object-auditor"
-    config_source:
-      - "roles/swift/templates/object-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/object-auditor.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/object-auditor.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-auditor.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-auditor.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/object-auditor.conf"
-  when: inventory_hostname in groups['swift-object-server']
-
-- name: Copying over swift-object-auditor JSON configuration file
-  template:
-    src: "swift-object-auditor.json.j2"
-    dest: "{{ node_config_directory }}/swift-object-auditor/config.json"
-  when: inventory_hostname in groups['swift-object-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-object-replicator"
-    config_source:
-      - "roles/swift/templates/object-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/object-replicator.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/object-replicator.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-replicator.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-replicator.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/object-replicator.conf"
-  when: inventory_hostname in groups['swift-object-server']
-
-- name: Copying over swift-object-replicator JSON configuration file
-  template:
-    src: "swift-object-replicator.json.j2"
-    dest: "{{ node_config_directory }}/swift-object-replicator/config.json"
-  when: inventory_hostname in groups['swift-object-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-object-updater"
-    config_source:
-      - "roles/swift/templates/object-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/object-updater.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/object-updater.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-updater.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-updater.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/object-updater.conf"
-  when: inventory_hostname in groups['swift-object-server']
-
-- name: Copying over swift-object-updater JSON configuration file
-  template:
-    src: "swift-object-updater.json.j2"
-    dest: "{{ node_config_directory }}/swift-object-updater/config.json"
-  when: inventory_hostname in groups['swift-object-server']
-
-- include: ../../config.yml
-  vars:
-    service_name: "swift-object-expirer"
-    config_source:
-      - "roles/swift/templates/object-server.conf.j2"
-      - "/etc/kolla/config/global.conf"
-      - "/etc/kolla/config/swift/object-expirer.conf"
-    config_template_dest:
-      - "{{ node_templates_directory }}/{{ service_name }}/object-expirer.conf_minimal"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-expirer.conf_global"
-      - "{{ node_templates_directory }}/{{ service_name }}/object-expirer.conf_augment"
-    config_dest: "{{ node_config_directory }}/{{ service_name }}/object-expirer.conf"
-  when: inventory_hostname in groups['swift-object-server']
-
-- name: Copying over swift-object-expirer JSON configuration file
-  template:
-    src: "swift-object-expirer.json.j2"
-    dest: "{{ node_config_directory }}/swift-object-expirer/config.json"
-  when: inventory_hostname in groups['swift-object-server']
-
-- name: Copying over Swift ring files
-  copy:
-    src: "{{ item.src }}"
-    dest: "{{ item.dest }}"
-    backup: yes
+      - "/etc/kolla/config/swift.conf"
+      - "/etc/kolla/config/swift/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/swift-{{ item }}/swift.conf"
   with_items:
-    - { src: "/etc/kolla/config/swift/object.ring.gz",
-        dest: "{{ node_config_directory }}/swift/object.ring.gz" }
-    - { src: "/etc/kolla/config/swift/object.builder",
-        dest: "{{ node_config_directory }}/swift/object.builder" }
+    - "account-auditor"
+    - "account-reaper"
+    - "account-replicator"
+    - "account-server"
+    - "container-auditor"
+    - "container-replicator"
+    - "container-server"
+    - "container-updater"
+    - "object-auditor"
+    - "object-expirer"
+    - "object-replicator"
+    - "object-server"
+    - "object-updater"
+    - "proxy-server"
 
-    - { src: "/etc/kolla/config/swift/container.ring.gz",
-        dest: "{{ node_config_directory }}/swift/container.ring.gz" }
-    - { src: "/etc/kolla/config/swift/container.builder",
-        dest: "{{ node_config_directory }}/swift/container.builder" }
+- name: Copying over account-*.conf
+  merge_configs:
+    vars:
+      service_name: "swift-{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/account.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/swift/account.conf"
+      - "/etc/kolla/config/swift/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/swift-{{ item }}/{{ item }}.conf"
+  with_items:
+    - "account-auditor"
+    - "account-reaper"
+    - "account-replicator"
+    - "account-server"
 
-    - { src: "/etc/kolla/config/swift/account.ring.gz",
-        dest: "{{ node_config_directory }}/swift/account.ring.gz" }
-    - { src: "/etc/kolla/config/swift/account.builder",
-        dest: "{{ node_config_directory }}/swift/account.builder" }
+- name: Copying over container-*.conf
+  merge_configs:
+    vars:
+      service_name: "swift-{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/container.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/swift/container.conf"
+      - "/etc/kolla/config/swift/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/swift-{{ item }}/{{ item }}.conf"
+  with_items:
+    - "container-auditor"
+    - "container-replicator"
+    - "container-server"
+    - "container-updater"
 
-- name: Ensuring swift-rsyncd config directory exists
-  file:
-    path: "{{ node_config_directory }}/swift-rsyncd/"
-    state: "directory"
-    recurse: "yes"
+- name: Copying over object-*.conf
+  merge_configs:
+    vars:
+      service_name: "swift-{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/object.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/swift/object.conf"
+      - "/etc/kolla/config/swift/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/swift-{{ item }}/{{ item }}.conf"
+  with_items:
+    - "object-auditor"
+    - "object-expirer"
+    - "object-replicator"
+    - "object-server"
+    - "object-updater"
 
-- name: Copying over swift-rsyncd config(s)
+- name: Copying over proxy-server.conf
+  merge_configs:
+    vars:
+      service_name: "swift-{{ item }}"
+    sources:
+      - "{{ role_path }}/templates/proxy-server.conf.j2"
+      - "/etc/kolla/config/global.conf"
+      - "/etc/kolla/config/swift/{{ item }}.conf"
+    dest: "{{ node_config_directory }}/swift-{{ item }}/{{ item }}.conf"
+  with_items:
+    - "proxy-server"
+
+- name: Copying over rsyncd.conf
   template:
     src: "rsyncd.conf.j2"
     dest: "{{ node_config_directory }}/swift-rsyncd/rsyncd.conf"
 
-- name: Copying over swift-rsyncd JSON configuration file
-  template:
-    src: "swift-rsyncd.json.j2"
-    dest: "{{ node_config_directory }}/swift-rsyncd/config.json"
+- name: Copying over Swift ring files
+  copy:
+    src: "/etc/kolla/config/swift/{{ item }}"
+    dest: "{{ node_config_directory }}/swift/{{ item }}"
+    backup: yes
+  with_items:
+    - "account.ring"
+    - "account.ring.gz"
+    - "container.ring.gz"
+    - "container.ring"
+    - "object.ring"
+    - "object.ring.gz"
diff --git a/ansible/roles/swift/templates/account-server.conf.j2 b/ansible/roles/swift/templates/account.conf.j2
similarity index 100%
rename from ansible/roles/swift/templates/account-server.conf.j2
rename to ansible/roles/swift/templates/account.conf.j2
diff --git a/ansible/roles/swift/templates/container-server.conf.j2 b/ansible/roles/swift/templates/container.conf.j2
similarity index 100%
rename from ansible/roles/swift/templates/container-server.conf.j2
rename to ansible/roles/swift/templates/container.conf.j2
diff --git a/ansible/roles/swift/templates/object-server.conf.j2 b/ansible/roles/swift/templates/object.conf.j2
similarity index 100%
rename from ansible/roles/swift/templates/object-server.conf.j2
rename to ansible/roles/swift/templates/object.conf.j2
diff --git a/ansible/roles/swift/templates/swift-account-auditor.json.j2 b/ansible/roles/swift/templates/swift-account-auditor.json.j2
index 490120d717..ccdd21a429 100644
--- a/ansible/roles/swift/templates/swift-account-auditor.json.j2
+++ b/ansible/roles/swift/templates/swift-account-auditor.json.j2
@@ -2,14 +2,14 @@
     "command": "swift-account-auditor /etc/swift/account-auditor.conf --verbose",
     "config_files": [
         {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
+            "source": "/var/lib/kolla/swift/account.ring.gz",
+            "dest": "/etc/swift/account.ring.gz",
             "owner": "swift",
             "perm": "0640"
         },
         {
-            "source": "/var/lib/kolla/swift/account.ring.gz",
-            "dest": "/etc/swift/account.ring.gz",
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
             "owner": "swift",
             "perm": "0640"
         },
diff --git a/ansible/roles/swift/templates/swift-account-reaper.json.j2 b/ansible/roles/swift/templates/swift-account-reaper.json.j2
index 4933cee3f8..9471bfd502 100644
--- a/ansible/roles/swift/templates/swift-account-reaper.json.j2
+++ b/ansible/roles/swift/templates/swift-account-reaper.json.j2
@@ -2,14 +2,14 @@
     "command": "swift-account-reaper /etc/swift/account-reaper.conf --verbose",
     "config_files": [
         {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
+            "source": "/var/lib/kolla/swift/account.ring.gz",
+            "dest": "/etc/swift/account.ring.gz",
             "owner": "swift",
             "perm": "0640"
         },
         {
-            "source": "/var/lib/kolla/swift/account.ring.gz",
-            "dest": "/etc/swift/account.ring.gz",
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
             "owner": "swift",
             "perm": "0640"
         },
diff --git a/ansible/roles/swift/templates/swift-account-replicator.json.j2 b/ansible/roles/swift/templates/swift-account-replicator.json.j2
index d48121ef6d..a079cd13af 100644
--- a/ansible/roles/swift/templates/swift-account-replicator.json.j2
+++ b/ansible/roles/swift/templates/swift-account-replicator.json.j2
@@ -2,14 +2,14 @@
     "command": "swift-account-replicator /etc/swift/account-replicator.conf --verbose",
     "config_files": [
         {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
+            "source": "/var/lib/kolla/swift/account.ring.gz",
+            "dest": "/etc/swift/account.ring.gz",
             "owner": "swift",
             "perm": "0640"
         },
         {
-            "source": "/var/lib/kolla/swift/account.ring.gz",
-            "dest": "/etc/swift/account.ring.gz",
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
             "owner": "swift",
             "perm": "0640"
         },
diff --git a/ansible/roles/swift/templates/swift-account-server.json.j2 b/ansible/roles/swift/templates/swift-account-server.json.j2
index 8f7935df98..516c836d88 100644
--- a/ansible/roles/swift/templates/swift-account-server.json.j2
+++ b/ansible/roles/swift/templates/swift-account-server.json.j2
@@ -2,14 +2,14 @@
     "command": "swift-account-server /etc/swift/account-server.conf --verbose",
     "config_files": [
         {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
+            "source": "/var/lib/kolla/swift/account.ring.gz",
+            "dest": "/etc/swift/account.ring.gz",
             "owner": "swift",
             "perm": "0640"
         },
         {
-            "source": "/var/lib/kolla/swift/account.ring.gz",
-            "dest": "/etc/swift/account.ring.gz",
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
             "owner": "swift",
             "perm": "0640"
         },
diff --git a/ansible/roles/swift/templates/swift-container-auditor.json.j2 b/ansible/roles/swift/templates/swift-container-auditor.json.j2
index a1ed9e3478..05ed8105a2 100644
--- a/ansible/roles/swift/templates/swift-container-auditor.json.j2
+++ b/ansible/roles/swift/templates/swift-container-auditor.json.j2
@@ -2,14 +2,14 @@
     "command": "swift-container-auditor /etc/swift/container-auditor.conf --verbose",
     "config_files": [
         {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
+            "source": "/var/lib/kolla/swift/container.ring.gz",
+            "dest": "/etc/swift/container.ring.gz",
             "owner": "swift",
             "perm": "0640"
         },
         {
-            "source": "/var/lib/kolla/swift/container.ring.gz",
-            "dest": "/etc/swift/container.ring.gz",
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
             "owner": "swift",
             "perm": "0640"
         },
diff --git a/ansible/roles/swift/templates/swift-container-replicator.json.j2 b/ansible/roles/swift/templates/swift-container-replicator.json.j2
index 98be79be3b..5821930a29 100644
--- a/ansible/roles/swift/templates/swift-container-replicator.json.j2
+++ b/ansible/roles/swift/templates/swift-container-replicator.json.j2
@@ -2,14 +2,14 @@
     "command": "swift-container-replicator /etc/swift/container-replicator.conf --verbose",
     "config_files": [
         {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
+            "source": "/var/lib/kolla/swift/container.ring.gz",
+            "dest": "/etc/swift/container.ring.gz",
             "owner": "swift",
             "perm": "0640"
         },
         {
-            "source": "/var/lib/kolla/swift/container.ring.gz",
-            "dest": "/etc/swift/container.ring.gz",
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
             "owner": "swift",
             "perm": "0640"
         },
diff --git a/ansible/roles/swift/templates/swift-container-server.json.j2 b/ansible/roles/swift/templates/swift-container-server.json.j2
index b508ee4fe9..538001ee3d 100644
--- a/ansible/roles/swift/templates/swift-container-server.json.j2
+++ b/ansible/roles/swift/templates/swift-container-server.json.j2
@@ -2,14 +2,14 @@
     "command": "swift-container-server /etc/swift/container-server.conf --verbose",
     "config_files": [
         {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
+            "source": "/var/lib/kolla/swift/container.ring.gz",
+            "dest": "/etc/swift/container.ring.gz",
             "owner": "swift",
             "perm": "0640"
         },
         {
-            "source": "/var/lib/kolla/swift/container.ring.gz",
-            "dest": "/etc/swift/container.ring.gz",
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
             "owner": "swift",
             "perm": "0640"
         },
diff --git a/ansible/roles/swift/templates/swift-container-updater.json.j2 b/ansible/roles/swift/templates/swift-container-updater.json.j2
index 7df0847928..123c911cea 100644
--- a/ansible/roles/swift/templates/swift-container-updater.json.j2
+++ b/ansible/roles/swift/templates/swift-container-updater.json.j2
@@ -1,12 +1,6 @@
 {
     "command": "swift-container-updater /etc/swift/container-updater.conf --verbose",
     "config_files": [
-        {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
-            "owner": "swift",
-            "perm": "0640"
-        },
         {
             "source": "/var/lib/kolla/swift/account.ring.gz",
             "dest": "/etc/swift/account.ring.gz",
@@ -19,6 +13,12 @@
             "owner": "swift",
             "perm": "0640"
         },
+        {
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
+            "owner": "swift",
+            "perm": "0640"
+        },
         {
             "source": "{{ container_config_directory }}/container-updater.conf",
             "dest": "/etc/swift/container-updater.conf",
diff --git a/ansible/roles/swift/templates/swift-object-auditor.json.j2 b/ansible/roles/swift/templates/swift-object-auditor.json.j2
index 79df2d51ad..46b1ad5463 100644
--- a/ansible/roles/swift/templates/swift-object-auditor.json.j2
+++ b/ansible/roles/swift/templates/swift-object-auditor.json.j2
@@ -1,12 +1,6 @@
 {
     "command": "swift-object-auditor /etc/swift/object-auditor.conf --verbose",
     "config_files": [
-        {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
-            "owner": "swift",
-            "perm": "0640"
-        },
         {
             "source": "/var/lib/kolla/swift/container.ring.gz",
             "dest": "/etc/swift/container.ring.gz",
@@ -19,6 +13,12 @@
             "owner": "swift",
             "perm": "0640"
         },
+        {
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
+            "owner": "swift",
+            "perm": "0640"
+        },
         {
             "source": "{{ container_config_directory }}/object-auditor.conf",
             "dest": "/etc/swift/object-auditor.conf",
diff --git a/ansible/roles/swift/templates/swift-object-expirer.json.j2 b/ansible/roles/swift/templates/swift-object-expirer.json.j2
index 85c4c77c2c..5ebb4889e9 100644
--- a/ansible/roles/swift/templates/swift-object-expirer.json.j2
+++ b/ansible/roles/swift/templates/swift-object-expirer.json.j2
@@ -1,12 +1,6 @@
 {
     "command": "swift-object-expirer /etc/swift/object-expirer.conf --verbose",
     "config_files": [
-        {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
-            "owner": "swift",
-            "perm": "0640"
-        },
         {
             "source": "/var/lib/kolla/swift/account.ring.gz",
             "dest": "/etc/swift/account.ring.gz",
@@ -25,6 +19,12 @@
             "owner": "swift",
             "perm": "0640"
         },
+        {
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
+            "owner": "swift",
+            "perm": "0640"
+        },
         {
             "source": "{{ container_config_directory }}/object-expirer.conf",
             "dest": "/etc/swift/object-expirer.conf",
diff --git a/ansible/roles/swift/templates/swift-object-replicator.json.j2 b/ansible/roles/swift/templates/swift-object-replicator.json.j2
index 1b11cac50d..8fc5eb1594 100644
--- a/ansible/roles/swift/templates/swift-object-replicator.json.j2
+++ b/ansible/roles/swift/templates/swift-object-replicator.json.j2
@@ -1,12 +1,6 @@
 {
     "command": "swift-object-replicator /etc/swift/object-replicator.conf --verbose",
     "config_files": [
-        {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
-            "owner": "swift",
-            "perm": "0640"
-        },
         {
             "source": "/var/lib/kolla/swift/container.ring.gz",
             "dest": "/etc/swift/container.ring.gz",
@@ -19,6 +13,12 @@
             "owner": "swift",
             "perm": "0640"
         },
+        {
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
+            "owner": "swift",
+            "perm": "0640"
+        },
         {
             "source": "{{ container_config_directory }}/object-replicator.conf",
             "dest": "/etc/swift/object-replicator.conf",
diff --git a/ansible/roles/swift/templates/swift-object-server.json.j2 b/ansible/roles/swift/templates/swift-object-server.json.j2
index d49c622098..31913d4bb3 100644
--- a/ansible/roles/swift/templates/swift-object-server.json.j2
+++ b/ansible/roles/swift/templates/swift-object-server.json.j2
@@ -1,12 +1,6 @@
 {
     "command": "swift-object-server /etc/swift/object-server.conf --verbose",
     "config_files": [
-        {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
-            "owner": "swift",
-            "perm": "0640"
-        },
         {
             "source": "/var/lib/kolla/swift/container.ring.gz",
             "dest": "/etc/swift/container.ring.gz",
@@ -19,6 +13,12 @@
             "owner": "swift",
             "perm": "0640"
         },
+        {
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
+            "owner": "swift",
+            "perm": "0640"
+        },
         {
             "source": "{{ container_config_directory }}/object-server.conf",
             "dest": "/etc/swift/object-server.conf",
diff --git a/ansible/roles/swift/templates/swift-object-updater.json.j2 b/ansible/roles/swift/templates/swift-object-updater.json.j2
index 9cabfdbf71..d34130640a 100644
--- a/ansible/roles/swift/templates/swift-object-updater.json.j2
+++ b/ansible/roles/swift/templates/swift-object-updater.json.j2
@@ -1,12 +1,6 @@
 {
     "command": "swift-object-updater /etc/swift/object-updater.conf --verbose",
     "config_files": [
-        {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
-            "owner": "swift",
-            "perm": "0640"
-        },
         {
             "source": "/var/lib/kolla/swift/container.ring.gz",
             "dest": "/etc/swift/container.ring.gz",
@@ -19,6 +13,12 @@
             "owner": "swift",
             "perm": "0640"
         },
+        {
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
+            "owner": "swift",
+            "perm": "0640"
+        },
         {
             "source": "{{ container_config_directory }}/object-updater.conf",
             "dest": "/etc/swift/object-updater.conf",
diff --git a/ansible/roles/swift/templates/swift-proxy-server.json.j2 b/ansible/roles/swift/templates/swift-proxy-server.json.j2
index 1e80afa107..39e43fb5b8 100644
--- a/ansible/roles/swift/templates/swift-proxy-server.json.j2
+++ b/ansible/roles/swift/templates/swift-proxy-server.json.j2
@@ -1,12 +1,6 @@
 {
     "command": "swift-proxy-server /etc/swift/proxy-server.conf --verbose",
     "config_files": [
-        {
-            "source": "/var/lib/kolla/swift/swift.conf",
-            "dest": "/etc/swift/swift.conf",
-            "owner": "swift",
-            "perm": "0640"
-        },
         {
             "source": "/var/lib/kolla/swift/account.ring.gz",
             "dest": "/etc/swift/account.ring.gz",
@@ -25,6 +19,12 @@
             "owner": "swift",
             "perm": "0640"
         },
+        {
+            "source": "{{ container_config_directory }}/swift.conf",
+            "dest": "/etc/swift/swift.conf",
+            "owner": "swift",
+            "perm": "0640"
+        },
         {
             "source": "{{ container_config_directory }}/proxy-server.conf",
             "dest": "/etc/swift/proxy-server.conf",
diff --git a/etc/kolla/config/ceph.conf b/etc/kolla/config/ceph.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/cinder.conf b/etc/kolla/config/cinder.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/cinder/cinder-api.conf b/etc/kolla/config/cinder/cinder-api.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/cinder/cinder-backup.conf b/etc/kolla/config/cinder/cinder-backup.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/cinder/cinder-scheduler.conf b/etc/kolla/config/cinder/cinder-scheduler.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/cinder/cinder-volume.conf b/etc/kolla/config/cinder/cinder-volume.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/database.conf b/etc/kolla/config/database.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/discoverd.conf b/etc/kolla/config/discoverd.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/glance.conf b/etc/kolla/config/glance.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/glance/glance-api.conf b/etc/kolla/config/glance/glance-api.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/glance/glance-registry.conf b/etc/kolla/config/glance/glance-registry.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/global.conf b/etc/kolla/config/global.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/heat.conf b/etc/kolla/config/heat.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/heat/heat-api-cfn.conf b/etc/kolla/config/heat/heat-api-cfn.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/heat/heat-api.conf b/etc/kolla/config/heat/heat-api.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/heat/heat-engine.conf b/etc/kolla/config/heat/heat-engine.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/ironic.conf b/etc/kolla/config/ironic.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/ironic/discoverd.conf b/etc/kolla/config/ironic/discoverd.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/ironic/ironic-api.conf b/etc/kolla/config/ironic/ironic-api.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/ironic/ironic-conductor.conf b/etc/kolla/config/ironic/ironic-conductor.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/keystone.conf b/etc/kolla/config/keystone.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/keystone/keystone.conf b/etc/kolla/config/keystone/keystone.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/magnum.conf b/etc/kolla/config/magnum.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/magnum/magnum-api.conf b/etc/kolla/config/magnum/magnum-api.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/magnum/magnum-conductor.conf b/etc/kolla/config/magnum/magnum-conductor.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/messaging.conf b/etc/kolla/config/messaging.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/murano.conf b/etc/kolla/config/murano.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/murano/murano-api.conf b/etc/kolla/config/murano/murano-api.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/murano/murano-engine.conf b/etc/kolla/config/murano/murano-engine.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron.conf b/etc/kolla/config/neutron.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/dhcp_agent.ini b/etc/kolla/config/neutron/dhcp_agent.ini
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/l3_agent.ini b/etc/kolla/config/neutron/l3_agent.ini
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/metadata_agent.ini b/etc/kolla/config/neutron/metadata_agent.ini
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/ml2_conf.ini b/etc/kolla/config/neutron/ml2_conf.ini
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/neutron-agents.conf b/etc/kolla/config/neutron/neutron-agents.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/neutron-linuxbridge-agent.conf b/etc/kolla/config/neutron/neutron-linuxbridge-agent.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/neutron-openvswitch-agent.conf b/etc/kolla/config/neutron/neutron-openvswitch-agent.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/neutron/neutron-server.conf b/etc/kolla/config/neutron/neutron-server.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova.conf b/etc/kolla/config/nova.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova/nova-api.conf b/etc/kolla/config/nova/nova-api.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova/nova-compute.conf b/etc/kolla/config/nova/nova-compute.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova/nova-conductor.conf b/etc/kolla/config/nova/nova-conductor.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova/nova-consoleauth.conf b/etc/kolla/config/nova/nova-consoleauth.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova/nova-novncproxy.conf b/etc/kolla/config/nova/nova-novncproxy.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova/nova-scheduler.conf b/etc/kolla/config/nova/nova-scheduler.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/nova/nova-spicehtml5proxy.conf b/etc/kolla/config/nova/nova-spicehtml5proxy.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift.conf b/etc/kolla/config/swift.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/account-auditor.conf b/etc/kolla/config/swift/account-auditor.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/account-reaper.conf b/etc/kolla/config/swift/account-reaper.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/account-replicator.conf b/etc/kolla/config/swift/account-replicator.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/account-server.conf b/etc/kolla/config/swift/account-server.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/container-auditor.conf b/etc/kolla/config/swift/container-auditor.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/container-replicator.conf b/etc/kolla/config/swift/container-replicator.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/container-server.conf b/etc/kolla/config/swift/container-server.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/container-updater.conf b/etc/kolla/config/swift/container-updater.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/object-auditor.conf b/etc/kolla/config/swift/object-auditor.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/object-expirer.conf b/etc/kolla/config/swift/object-expirer.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/object-replicator.conf b/etc/kolla/config/swift/object-replicator.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/object-server.conf b/etc/kolla/config/swift/object-server.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/object-updater.conf b/etc/kolla/config/swift/object-updater.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/proxy-server.conf b/etc/kolla/config/swift/proxy-server.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/etc/kolla/config/swift/swift.conf b/etc/kolla/config/swift/swift.conf
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/tox.ini b/tox.ini
index e56cb14fd1..ec7eca5598 100644
--- a/tox.ini
+++ b/tox.ini
@@ -104,4 +104,4 @@ commands =
 
 [flake8]
 show-source = True
-exclude=.eggs,.git,.tox,doc,ansible/library,docker/kolla-ansible
+exclude=.eggs,.git,.tox,doc,ansible/library,ansible/action_plugins,docker/kolla-ansible