diff --git a/ansible.cfg b/ansible.cfg
index a6f17123227b219116849ce168449510e0b1ebef..769f2dcc6e3be2ebe687e47c5b1826861558cbf1 100644
--- a/ansible.cfg
+++ b/ansible.cfg
@@ -8,3 +8,4 @@ gathering = smart
 fact_caching = jsonfile
 fact_caching_connection = /tmp
 stdout_callback = skippy
+library = ./library
diff --git a/cluster.yml b/cluster.yml
index 24da63500c6cae723c506c81fdea9d86b0a902c6..becad3b6d26280771384c2ff48adb3eae85681d5 100644
--- a/cluster.yml
+++ b/cluster.yml
@@ -46,7 +46,6 @@
   any_errors_fatal: true
   roles:
     - { role: kubernetes/master, tags: master }
-    - { role: kubernetes-apps/lib, tags: apps }
     - { role: kubernetes-apps/network_plugin, tags: network }
 
 - hosts: calico-rr
@@ -63,5 +62,4 @@
 - hosts: kube-master[0]
   any_errors_fatal: true
   roles:
-    - { role: kubernetes-apps/lib, tags: apps }
     - { role: kubernetes-apps, tags: apps }
diff --git a/contrib/network-storage/glusterfs/roles/kubernetes-pv/lib b/contrib/network-storage/glusterfs/roles/kubernetes-pv/lib
deleted file mode 120000
index d095c1569ca72d7aa4079c1fc26820ba27f81ee1..0000000000000000000000000000000000000000
--- a/contrib/network-storage/glusterfs/roles/kubernetes-pv/lib
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../roles/kubernetes-apps/lib
\ No newline at end of file
diff --git a/roles/dnsmasq/library/kube.py b/library/kube.py
similarity index 100%
rename from roles/dnsmasq/library/kube.py
rename to library/kube.py
diff --git a/roles/kubernetes-apps/lib/library/kube.py b/roles/kubernetes-apps/lib/library/kube.py
deleted file mode 100644
index 2922c62129885156076b640ac275e2234e62d5bd..0000000000000000000000000000000000000000
--- a/roles/kubernetes-apps/lib/library/kube.py
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-DOCUMENTATION = """
----
-module: kube
-short_description: Manage Kubernetes Cluster
-description:
-  - Create, replace, remove, and stop resources within a Kubernetes Cluster
-version_added: "2.0"
-options:
-  name:
-    required: false
-    default: null
-    description:
-      - The name associated with resource
-  filename:
-    required: false
-    default: null
-    description:
-      - The path and filename of the resource(s) definition file.
-  kubectl:
-    required: false
-    default: null
-    description:
-      - The path to the kubectl bin
-  namespace:
-    required: false
-    default: null
-    description:
-      - The namespace associated with the resource(s)
-  resource:
-    required: false
-    default: null
-    description:
-      - The resource to perform an action on. pods (po), replicationControllers (rc), services (svc)
-  label:
-    required: false
-    default: null
-    description:
-      - The labels used to filter specific resources.
-  server:
-    required: false
-    default: null
-    description:
-      - The url for the API server that commands are executed against.
-  force:
-    required: false
-    default: false
-    description:
-      - A flag to indicate to force delete, replace, or stop.
-  all:
-    required: false
-    default: false
-    description:
-      - A flag to indicate delete all, stop all, or all namespaces when checking exists.
-  log_level:
-    required: false
-    default: 0
-    description:
-      - Indicates the level of verbosity of logging by kubectl.
-  state:
-    required: false
-    choices: ['present', 'absent', 'latest', 'reloaded', 'stopped']
-    default: present
-    description:
-      - present handles checking existence or creating if definition file provided,
-        absent handles deleting resource(s) based on other options,
-        latest handles creating ore updating based on existence,
-        reloaded handles updating resource(s) definition using definition file,
-        stopped handles stopping resource(s) based on other options.
-requirements:
-  - kubectl
-author: "Kenny Jones (@kenjones-cisco)"
-"""
-
-EXAMPLES = """
-- name: test nginx is present
-  kube: name=nginx resource=rc state=present
-
-- name: test nginx is stopped
-  kube: name=nginx resource=rc state=stopped
-
-- name: test nginx is absent
-  kube: name=nginx resource=rc state=absent
-
-- name: test nginx is present
-  kube: filename=/tmp/nginx.yml
-"""
-
-
-class KubeManager(object):
-
-    def __init__(self, module):
-
-        self.module = module
-
-        self.kubectl = module.params.get('kubectl')
-        if self.kubectl is None:
-            self.kubectl =  module.get_bin_path('kubectl', True)
-        self.base_cmd = [self.kubectl]
-
-        if module.params.get('server'):
-            self.base_cmd.append('--server=' + module.params.get('server'))
-
-        if module.params.get('log_level'):
-            self.base_cmd.append('--v=' + str(module.params.get('log_level')))
-
-        if module.params.get('namespace'):
-            self.base_cmd.append('--namespace=' + module.params.get('namespace'))
-
-        self.all = module.params.get('all')
-        self.force = module.params.get('force')
-        self.name = module.params.get('name')
-        self.filename = module.params.get('filename')
-        self.resource = module.params.get('resource')
-        self.label = module.params.get('label')
-
-    def _execute(self, cmd):
-        args = self.base_cmd + cmd
-        try:
-            rc, out, err = self.module.run_command(args)
-            if rc != 0:
-                self.module.fail_json(
-                    msg='error running kubectl (%s) command (rc=%d): %s' % (' '.join(args), rc, out or err))
-        except Exception as exc:
-            self.module.fail_json(
-                msg='error running kubectl (%s) command: %s' % (' '.join(args), str(exc)))
-        return out.splitlines()
-
-    def _execute_nofail(self, cmd):
-        args = self.base_cmd + cmd
-        rc, out, err = self.module.run_command(args)
-        if rc != 0:
-            return None
-        return out.splitlines()
-
-    def create(self, check=True):
-        if check and self.exists():
-            return []
-
-        cmd = ['create']
-
-        if not self.filename:
-            self.module.fail_json(msg='filename required to create')
-
-        cmd.append('--filename=' + self.filename)
-
-        return self._execute(cmd)
-
-    def replace(self):
-
-        if not self.force and not self.exists():
-            return []
-
-        cmd = ['replace']
-
-        if self.force:
-            cmd.append('--force')
-
-        if not self.filename:
-            self.module.fail_json(msg='filename required to reload')
-
-        cmd.append('--filename=' + self.filename)
-
-        return self._execute(cmd)
-
-    def delete(self):
-
-        if not self.force and not self.exists():
-            return []
-
-        cmd = ['delete']
-
-        if self.filename:
-            cmd.append('--filename=' + self.filename)
-        else:
-            if not self.resource:
-                self.module.fail_json(msg='resource required to delete without filename')
-
-            cmd.append(self.resource)
-
-            if self.name:
-                cmd.append(self.name)
-
-            if self.label:
-                cmd.append('--selector=' + self.label)
-
-            if self.all:
-                cmd.append('--all')
-
-            if self.force:
-                cmd.append('--ignore-not-found')
-
-        return self._execute(cmd)
-
-    def exists(self):
-        cmd = ['get']
-
-        if not self.resource:
-            return False
-
-        cmd.append(self.resource)
-
-        if self.name:
-            cmd.append(self.name)
-
-        cmd.append('--no-headers')
-
-        if self.label:
-            cmd.append('--selector=' + self.label)
-
-        if self.all:
-            cmd.append('--all-namespaces')
-
-        result = self._execute_nofail(cmd)
-        if not result:
-            return False
-        return True
-
-    def stop(self):
-
-        if not self.force and not self.exists():
-            return []
-
-        cmd = ['stop']
-
-        if self.filename:
-            cmd.append('--filename=' + self.filename)
-        else:
-            if not self.resource:
-                self.module.fail_json(msg='resource required to stop without filename')
-
-            cmd.append(self.resource)
-
-            if self.name:
-                cmd.append(self.name)
-
-            if self.label:
-                cmd.append('--selector=' + self.label)
-
-            if self.all:
-                cmd.append('--all')
-
-            if self.force:
-                cmd.append('--ignore-not-found')
-
-        return self._execute(cmd)
-
-
-def main():
-
-    module = AnsibleModule(
-        argument_spec=dict(
-            name=dict(),
-            filename=dict(),
-            namespace=dict(),
-            resource=dict(),
-            label=dict(),
-            server=dict(),
-            kubectl=dict(),
-            force=dict(default=False, type='bool'),
-            all=dict(default=False, type='bool'),
-            log_level=dict(default=0, type='int'),
-            state=dict(default='present', choices=['present', 'absent', 'latest', 'reloaded', 'stopped']),
-            )
-        )
-
-    changed = False
-
-    manager = KubeManager(module)
-    state = module.params.get('state')
-
-    if state == 'present':
-        result = manager.create()
-
-    elif state == 'absent':
-        result = manager.delete()
-
-    elif state == 'reloaded':
-        result = manager.replace()
-
-    elif state == 'stopped':
-        result = manager.stop()
-
-    elif state == 'latest':
-        if manager.exists():
-            manager.force = True
-            result = manager.replace()
-        else:
-            result = manager.create(check=False)
-
-    else:
-        module.fail_json(msg='Unrecognized state %s.' % state)
-
-    if result:
-        changed = True
-    module.exit_json(changed=changed,
-                     msg='success: %s' % (' '.join(result))
-                     )
-
-
-from ansible.module_utils.basic import *  # noqa
-if __name__ == '__main__':
-    main()