diff --git a/ansible/library/docker_compose b/ansible/library/docker_compose
deleted file mode 100644
index 0f947e1202..0000000000
--- a/ansible/library/docker_compose
+++ /dev/null
@@ -1,301 +0,0 @@
-#!/usr/bin/python
-
-DOCUMENTATION = '''
----
-module: docker_compose
-version_added: 1.8.4
-short_description: Manage docker containers with docker-compose
-description:
-     - Manage the lifecycle of groups of docker containers with docker-compose
-options:
-  command:
-    description:
-      - Select the compose action to perform
-    required: true
-    choices: ['build', 'kill', 'pull', 'rm', 'scale', 'start', 'stop', 'restart', 'up']
-  compose_file:
-    description:
-      - Specify the compose file to build from
-    required: true
-    type: bool
-  insecure_registry:
-    description:
-      - Allow access to insecure registry (HTTP or TLS with a CA not known by the Docker daemon)
-    type: bool
-  kill_signal:
-    description:
-      - The SIG to send to the docker container process when killing it
-    default: SIGKILL
-  no_build:
-    description:
-      - Do not build an image, even if it's missing
-    type: bool
-  no_deps:
-    description:
-      - Don't start linked services
-    type: bool
-  no_recreate:
-    description:
-      - If containers already exist, don't recreate them
-    type: bool
-  project_name:
-    description:
-      - Specify project name (defaults to directory name of the compose file)
-    type: str
-  service_names:
-    description:
-      - Only modify services in this list (can be used in conjunction with no_deps)
-    type: list
-  stop_timeout:
-    description:
-      - The amount of time in seconds to wait for an instance to cleanly terminate before killing it (can be used in conjunction with stop_timeout)
-    default: 10
-    type: int
-
-author: Sam Yaple
-requirements: [ "docker-compose", "docker >= 1.3" ]
-'''
-
-EXAMPLES = '''
-Compose web application:
-
-- hosts: web
-  tasks:
-    - name: compose super important weblog
-      docker_compose: command="up" compose_file="/opt/compose/weblog.yml"
-
-Compose only mysql server from previous example:
-
-- hosts: web
-  tasks:
-    - name: compose mysql
-      docker_compose: command="up" compose_file="/opt/compose/weblog.yml" service_names=['mysql']
-
-Compose project with specified prefix:
-
-- hosts: web
-  tasks:
-    - name: compose weblog named "myproject_weblog_1"
-      docker_compose: command="up" compose_file="/opt/compose/weblog.yml" project_name="myproject"
-
-Compose project only if already built (or no build instructions). Explicitly refuse to build the container image(s):
-
-- hosts: web
-  tasks:
-    - name: compose weblog
-      docker_compose: command="up" compose_file="/opt/compose/weblog.yml" no_build=True
-
-Allow the container image to be pulled from an insecure registry (this requires the docker daemon to allow the insecure registry as well):
-
-- hosts: web
-  tasks:
-    - name: compose weblog from local registry
-      docker_compose: command="up" compose_file="/opt/compose/weblog.yml" insecure_registry=True
-
-Start the containers in the compose project, but do not create any:
-
-- hosts: web
-  tasks:
-    - name: compose weblog
-      docker_compose: command="start" compose_file="/opt/compose/weblog.yml"
-
-Removed all the containers associated with a project; only wait 5 seconds for the container to respond to a SIGTERM:
-
-- hosts: web
-  tasks:
-    - name: Destroy ALL containers for project "devweblog"
-      docker_compose: command="rm" stop_timeout=5 compose_file="/opt/compose/weblog.yml" project_name="devweblog"
-'''
-
-HAS_DOCKER_COMPOSE = True
-
-import re
-
-try:
-    from compose import config
-    from compose.cli.command import Command as compose_command
-    from compose.cli.docker_client import docker_client
-except ImportError, e:
-    HAS_DOCKER_COMPOSE = False
-
-TIMEMAP = {
-        'second': 0,
-        'seconds': 0,
-        'minute': 1,
-        'minutes': 1,
-        'hour': 2,
-        'hours': 2,
-        'weeks': 3,
-        'months': 4,
-        'years': 5,
-}
-
-class DockerComposer:
-    def __init__(self, module):
-        self.module = module
-
-        self.compose_file = self.module.params.get('compose_file')
-        self.insecure_registry = self.module.params.get('insecure_registry')
-        self.no_build = self.module.params.get('no_build')
-        self.no_cache = self.module.params.get('no_cache')
-        self.no_deps = self.module.params.get('no_deps')
-        self.no_recreate = self.module.params.get('no_recreate')
-        self.project_name = self.module.params.get('project_name')
-        self.stop_timeout = self.module.params.get('stop_timeout')
-        self.scale = self.module.params.get('scale')
-        self.service_names = self.module.params.get('service_names')
-
-
-        self.project = compose_command.get_project(compose_command(),
-                                                   self.compose_file,
-                                                   self.project_name,
-                                                   )
-        self.containers = self.project.client.containers(all=True)
-
-
-    def build(self):
-        self.project.build(no_cache = self.no_cache,
-                           service_names = self.service_names,
-                           )
-
-    def kill(self):
-        self.project.kill(signal = self.kill_signal,
-                          service_names = self.service_names,
-                          )
-
-    def pull(self):
-        self.project.pull(insecure_registry = self.insecure_registry,
-                          service_names = self.service_names,
-                          )
-
-    def rm(self):
-        self.stop()
-        self.project.remove_stopped(service_names = self.service_names)
-
-    def scale(self):
-        for s in self.service_names:
-            try:
-                num = int(self.scale[s])
-            except ValueError:
-                msg = ('Value for scaling service "%s" should be an int, but '
-                       'value "%s" was recieved' % (s, self.scale[s]))
-                module.fail_json(msg=msg, failed=True)
-
-            try:
-                project.get_service(s).scale(num)
-            except CannotBeScaledError:
-                msg = ('Service "%s" cannot be scaled because it specifies a '
-                       'port on the host.' % s)
-                module.fail_json(msg=msg, failed=True)
-
-    def start(self):
-        self.project.start(service_names = self.service_names)
-
-    def stop(self):
-        self.project.stop(service_names = self.service_names,
-                          timeout = self.stop_timeout,
-                          )
-
-    def restart(self):
-        self.project.restart(service_names = self.service_names)
-
-    def up(self):
-        self.project_contains = self.project.up(
-                                    do_build = not self.no_build,
-                                    insecure_registry = self.insecure_registry,
-                                    allow_recreate = not self.no_recreate,
-                                    service_names = self.service_names,
-                                    start_deps = not self.no_deps,
-                                    )
-
-    def check_if_changed(self):
-        new_containers = self.project.client.containers(all=True)
-
-        for pc in self.project_contains:
-            old_container = None
-            new_container = None
-            name = '/' + re.split(' |>',str(pc))[1]
-
-            for c in self.containers:
-                if c['Names'][0] == name:
-                    old_container = c
-
-            for c in new_containers:
-                if c['Names'][0] == name:
-                    new_container = c
-
-            if not old_container or not new_container:
-                return True
-
-            if old_container['Created'] != new_container['Created']:
-                return True
-
-            old_status = re.split(' ', old_container['Status'])
-            new_status = re.split(' ', new_container['Status'])
-
-            if old_status[0] != new_status[0]:
-                return True
-
-            if old_status[0] == 'Up':
-                if TIMEMAP[old_status[-1]] > TIMEMAP[new_status[-1]]:
-                    return True
-            else:
-                if TIMEMAP[old_status[-2]] < TIMEMAP[new_status[-2]]:
-                    return True
-
-        return False
-
-def check_dependencies(module):
-    if not HAS_DOCKER_COMPOSE:
-        msg = ('`docker-compose` does not seem to be installed, but is required '
-               'by the Ansible docker-compose module.')
-        module.fail_json(failed=True, msg=msg)
-
-def main():
-    module = AnsibleModule(
-        argument_spec = dict(
-            command         = dict(required=True,
-                                   choices=['build', 'kill', 'pull', 'rm',
-                                            'scale', 'start', 'stop',
-                                            'restart', 'up']
-                                   ),
-            compose_file    = dict(required=True, type='str'),
-            insecure_registry = dict(type='bool'),
-            kill_signal     = dict(default='SIGKILL'),
-            no_build        = dict(type='bool'),
-            no_cache        = dict(type='bool'),
-            no_deps         = dict(type='bool'),
-            no_recreate     = dict(type='bool'),
-            project_name    = dict(type='str'),
-            scale           = dict(type='dict'),
-            service_names   = dict(type='list'),
-            stop_timeout    = dict(default=10, type='int')
-        )
-    )
-
-    check_dependencies(module)
-
-
-    try:
-        composer = DockerComposer(module)
-        command = getattr(composer, module.params.get('command'))
-
-        command()
-
-        changed = composer.check_if_changed()
-
-        module.exit_json(changed=changed)
-    except Exception, e:
-        try:
-            changed = composer.check_if_changed()
-        except Exception:
-            changed = True
-
-        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/library/kolla_keystone_service.py b/ansible/library/kolla_keystone_service.py
new file mode 100644
index 0000000000..455aaf578e
--- /dev/null
+++ b/ansible/library/kolla_keystone_service.py
@@ -0,0 +1,84 @@
+#!/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.
+
+# This file is a barebones file needed to file a gap until Ansible 2.0. No error
+# checking, no deletions, no updates. Idempotent creation only.
+
+# If you look closely, you will see we arent _really_ using the shade module
+# we just use it to slightly abstract the authentication model. As patches land
+# in upstream shade we will be able to use more of the shade module. Until then
+# if we want to be 'stable' we really need to be using it as a passthrough
+
+import shade
+
+def main():
+    module = AnsibleModule(
+        argument_spec = openstack_full_argument_spec(
+            description = dict(required=True, type='str'),
+            service_name = dict(required=True, type='str'),
+            service_type = dict(required=True, type='str'),
+            admin_url = dict(required=True, type='str'),
+            internal_url = dict(required=True, type='str'),
+            public_url = dict(required=True, type='str'),
+            endpoint_region = dict(required=True, type='str')
+        )
+    )
+
+    try:
+        description = module.params.pop('description')
+        service_name = module.params.pop('service_name')
+        service_type = module.params.pop('service_type')
+        admin_url = module.params.pop('admin_url')
+        internal_url = module.params.pop('internal_url')
+        public_url = module.params.pop('public_url')
+        endpoint_region = module.params.pop('endpoint_region')
+
+        changed = False
+        service = None
+        endpoint = None
+
+        cloud = shade.operator_cloud(**module.params)
+
+        for _service in cloud.keystone_client.services.list():
+            if _service.type == service_type:
+                service = _service
+
+        if service is not None:
+            for _endpoint in cloud.keystone_client.endpoints.list():
+                if _endpoint.service_id == service.id:
+                    endpoint = _endpoint
+        else:
+            service = cloud.keystone_client.services.create(name=service_name,
+                                                            service_type=service_type,
+                                                            description=description)
+
+        if endpoint is None:
+            changed = True
+            cloud.keystone_client.endpoints.create(service_id=service.id,
+                                                   adminurl=admin_url,
+                                                   internalurl=public_url,
+                                                   publicurl=public_url,
+                                                   region=endpoint_region)
+
+        module.exit_json(changed=changed)
+    except Exception as e:
+        module.exit_json(failed=True, changed=True, msg=e)
+
+# import module snippets
+from ansible.module_utils.basic import *
+from ansible.module_utils.openstack import *
+if __name__ == '__main__':
+    main()
diff --git a/ansible/library/kolla_keystone_user.py b/ansible/library/kolla_keystone_user.py
new file mode 100644
index 0000000000..5d295c1e27
--- /dev/null
+++ b/ansible/library/kolla_keystone_user.py
@@ -0,0 +1,83 @@
+#!/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.
+
+# This file is a barebones file needed to file a gap until Ansible 2.0. No error
+# checking, no deletions, no updates. Idempotent creation only.
+
+# If you look closely, you will see we arent _really_ using the shade module
+# we just use it to slightly abstract the authentication model. As patches land
+# in upstream shade we will be able to use more of the shade module. Until then
+# if we want to be 'stable' we really need to be using it as a passthrough
+
+import shade
+
+def main():
+    module = AnsibleModule(
+        argument_spec = openstack_full_argument_spec(
+            password = dict(required=True, type='str'),
+            project = dict(required=True, type='str'),
+            role = dict(required=True, type='str'),
+            user = dict(required=True, type='str')
+        )
+    )
+
+    try:
+        password = module.params.pop('password')
+        project_name = module.params.pop('project')
+        role_name = module.params.pop('role')
+        user_name = module.params.pop('user')
+
+        changed = False
+        project = None
+        role = None
+        user = None
+
+        cloud = shade.operator_cloud(**module.params)
+
+        for _project in cloud.keystone_client.tenants.list():
+            if _project.name == project_name:
+                project = _project
+
+        for _role in cloud.keystone_client.roles.list():
+            if _role.name == role_name:
+                role = _role
+
+        for _user in cloud.keystone_client.users.list():
+            if _user.name == user_name:
+                user = _user
+
+        if not project:
+            changed = True
+            project = cloud.keystone_client.tenants.create(tenant_name=project_name)
+
+        if not role:
+            changed = True
+            role = cloud.keystone_client.roles.create(name=role_name)
+
+        if not user:
+            changed = True
+            user = cloud.keystone_client.users.create(name=user_name, password=password, tenant_id=project.id)
+            cloud.keystone_client.roles.add_user_role(role=role.id, user=user.id, tenant=project.id)
+
+        module.exit_json(changed=changed)
+    except Exception as e:
+        module.exit_json(failed=True, changed=True, msg=e)
+
+# import module snippets
+from ansible.module_utils.basic import *
+from ansible.module_utils.openstack import *
+if __name__ == '__main__':
+    main()
diff --git a/ansible/library/merge_configs b/ansible/library/merge_configs.py
similarity index 100%
rename from ansible/library/merge_configs
rename to ansible/library/merge_configs.py
diff --git a/ansible/roles/glance/tasks/main.yml b/ansible/roles/glance/tasks/main.yml
index 2821641c4b..5c48120b7c 100644
--- a/ansible/roles/glance/tasks/main.yml
+++ b/ansible/roles/glance/tasks/main.yml
@@ -1,8 +1,8 @@
 ---
+- include: register.yml
+
 - include: config.yml
 
 - include: bootstrap.yml
 
 - include: start.yml
-
-#- include: register.yml
diff --git a/ansible/roles/glance/tasks/register.yml b/ansible/roles/glance/tasks/register.yml
index 8ee20320bb..711ea5ff97 100644
--- a/ansible/roles/glance/tasks/register.yml
+++ b/ansible/roles/glance/tasks/register.yml
@@ -1,12 +1,21 @@
 ---
-# NB: Not an Attorney
-#
-# Upstream ansible will have all of the new modules we need based on
-# the shade library. They are written, but the keystone modules haven't3
-# been merged yet. None of the modules will land before Ansible 2.0.
-#
-# These new modules will be relicensed using ASL2.0 as the result of a
-# gentlemen's agreement that the Kolla authors will not alter the Shade code.
-# This does not place additional restrictions on the license of this work.  The
-# relicense agreement is based upon trust, not something legally binding and
-# has no binding impact on the license of Kolla..
+- name: Creating the Glance service and endpoint
+  kolla_keystone_service:
+    service_name: "glance"
+    service_type: "image"
+    description: "Openstack Image"
+    endpoint_region: "{{ openstack_region_name }}"
+    admin_url: "http://{{ kolla_internal_address }}:{{ glance_api_port }}"
+    internal_url: "http://{{ kolla_internal_address }}:{{ glance_api_port }}"
+    public_url: "http://{{ kolla_external_address }}:{{ glance_api_port }}"
+    auth: "{{ openstack_auth_v2 }}"
+    region_name: "{{ openstack_region_name }}"
+
+- name: Creating the Glance project, user, and role
+  kolla_keystone_user:
+    project: "service"
+    user: "glance"
+    password: "{{ glance_keystone_password }}"
+    role: "admin"
+    auth: "{{ openstack_auth_v2 }}"
+    region_name: "{{ openstack_region_name }}"
diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml
index 3c0ae3b621..e90380990d 100644
--- a/etc/kolla/globals.yml
+++ b/etc/kolla/globals.yml
@@ -72,6 +72,20 @@ openstack_region_name: "RegionOne"
 keystone_public_port: "5000"
 keystone_admin_port: "35357"
 
+openstack_auth:
+    auth_url: "http://{{ kolla_internal_address }}:{{ keystone_admin_port }}"
+    username: "admin"
+    password: "{{ keystone_admin_password }}"
+    project_name: "admin"
+
+# This shouldn't be needed for long. It is only temporary until we get the
+# ansible modules sorted out
+openstack_auth_v2:
+    auth_url: "http://{{ kolla_internal_address }}:{{ keystone_admin_port }}/v2.0"
+    username: "admin"
+    password: "{{ keystone_admin_password }}"
+    project_name: "admin"
+
 
 ####################
 # RabbitMQ options