diff --git a/cluster.yml b/cluster.yml
index 4ccef19634d658c606f026094396db2fc3ef7468..0c75b21b93090ee432e33f7a2c17aedad5fa7f4f 100644
--- a/cluster.yml
+++ b/cluster.yml
@@ -14,3 +14,7 @@
 - hosts: k8s-cluster
   roles:
     - { role: dnsmasq, tags: dnsmasq }
+
+- hosts: kube-master[0]
+  roles:
+    - {role: kubernetes-apps, tags: apps}
diff --git a/inventory/group_vars/all.yml b/inventory/group_vars/all.yml
index b73fb66b2dfa73f81d8dc115b4399e416e86c2db..e82c8314733431066610706aa607f9f69471e372 100644
--- a/inventory/group_vars/all.yml
+++ b/inventory/group_vars/all.yml
@@ -134,3 +134,11 @@ dns_server: "{{ kube_service_addresses|ipaddr('net')|ipaddr(2)|ipaddr('address')
 ## An obvious use case is allowing insecure-registry access
 ## to self hosted registries like so:
 docker_options: "--insecure-registry={{ kube_service_addresses }}"
+
+# default packages to install within the cluster
+kpm_packages:
+  - name: kube-system/kubedns
+    namespace: kube-system
+    variables:
+      cluster_ip: "{{skydns_server}}"
+#  - name: kube-system/grafana
diff --git a/roles/kubernetes-apps/tasks/main.yaml b/roles/kubernetes-apps/tasks/main.yaml
index c74761dfc002a0aa115d958acc53e5f706824166..315c880ef64f372c09b77c7d49afd3a6394e7b60 100644
--- a/roles/kubernetes-apps/tasks/main.yaml
+++ b/roles/kubernetes-apps/tasks/main.yaml
@@ -1,3 +1,6 @@
+- name: install kpm
+  pip: name=kpm state=latest
+
 - name: manage kubernetes applications
   kpm:
     namespace: "{{item.namespace | default(kpm_namespace | default('default'))}}"