diff --git a/cluster.yml b/cluster.yml
index 6a9de14da1acedfa754498dccd73b2ad38bcc48d..249a04f1dcaa7bfbb9c64e4f1a20a68a12d64107 100644
--- a/cluster.yml
+++ b/cluster.yml
@@ -119,7 +119,7 @@
     - { role: kubernetes/preinstall, when: "dns_mode != 'none' and resolvconf_mode == 'host_resolvconf'", tags: resolvconf }
   environment: "{{proxy_env}}"
 
-- hosts: kube-master[0]
+- hosts: kube-master
   any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
   roles:
     - { role: kubespray-defaults}
diff --git a/roles/kubernetes-apps/helm/tasks/main.yml b/roles/kubernetes-apps/helm/tasks/main.yml
index bae058f2648bb799d17bb6e32dbb412cfec734a7..24614da32d7d34e48920515b6052b74802c29ad5 100644
--- a/roles/kubernetes-apps/helm/tasks/main.yml
+++ b/roles/kubernetes-apps/helm/tasks/main.yml
@@ -14,7 +14,9 @@
     - {name: tiller, file: tiller-sa.yml, type: sa}
     - {name: tiller, file: tiller-clusterrolebinding.yml, type: clusterrolebinding}
   register: manifests
-  when: dns_mode != 'none' and inventory_hostname == groups['kube-master'][0]
+  when:
+    - dns_mode != 'none'
+    - inventory_hostname == groups['kube-master'][0]
 
 - name: Helm | Apply Helm Manifests (RBAC)
   kube:
@@ -25,7 +27,9 @@
     filename: "{{kube_config_dir}}/{{item.item.file}}"
     state: "latest"
   with_items: "{{ manifests.results }}"
-  when: dns_mode != 'none' and inventory_hostname == groups['kube-master'][0]
+  when:
+    - dns_mode != 'none'
+    - inventory_hostname == groups['kube-master'][0]
 
 # Generate necessary certs for securing Helm and Tiller connection with TLS
 - name: Helm | Set up TLS
@@ -34,15 +38,20 @@
 
 - name: Helm | Install/upgrade helm
   command: >
-    {{ bin_dir }}/helm init --upgrade --tiller-image={{ tiller_image_repo }}:{{ tiller_image_tag }} --tiller-namespace={{ tiller_namespace }}
+    {{ bin_dir }}/helm init --tiller-namespace={{ tiller_namespace }}
     {% if helm_skip_refresh %} --skip-refresh{% endif %}
     {% if helm_stable_repo_url is defined %} --stable-repo-url {{ helm_stable_repo_url }}{% endif %}
+    {% if inventory_hostname == groups['kube-master'][0] %}
+    --upgrade --tiller-image={{ tiller_image_repo }}:{{ tiller_image_tag }}
     {% if rbac_enabled %} --service-account=tiller{% endif %}
     {% if tiller_node_selectors is defined %} --node-selectors {{ tiller_node_selectors }}{% endif %}
     {% if tiller_override is defined %} --override {{ tiller_override }}{% endif %}
     {% if tiller_max_history is defined %} --history-max={{ tiller_max_history }}{% endif %}
     {% if tiller_enable_tls %} --tiller-tls --tiller-tls-verify --tiller-tls-cert={{ tiller_tls_cert }} --tiller-tls-key={{ tiller_tls_key }} --tls-ca-cert={{ tiller_tls_ca_cert }} {% endif %}
     {% if tiller_secure_release_info %} --override 'spec.template.spec.containers[0].command'='{/tiller,--storage=secret}' {% endif %}
+    {% else %}
+    --client-only
+    {% endif %}
   register: install_helm
   changed_when: false
   environment: "{{proxy_env}}"
@@ -61,9 +70,13 @@
     {% if tiller_secure_release_info %} --override 'spec.template.spec.containers[0].command'='{/tiller,--storage=secret}' {% endif %}
     | kubectl apply -f -
   changed_when: false
-  when: tiller_override is defined
+  when:
+    - tiller_override is defined
+    - inventory_hostname == groups['kube-master'][0]
   environment: "{{proxy_env}}"
 
 - name: Helm | Set up bash completion
   shell: "umask 022 && {{ bin_dir }}/helm completion bash >/etc/bash_completion.d/helm.sh"
-  when: ((helm_container is defined and helm_container.changed) or (helm_task_result is defined and helm_task_result.changed)) and not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]
+  when:
+    - ((helm_container is defined and helm_container.changed) or (helm_task_result is defined and helm_task_result.changed))
+    - not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]
diff --git a/roles/kubernetes-apps/meta/main.yml b/roles/kubernetes-apps/meta/main.yml
index e75f073b0780b3e323bb8d2e7c77f3ae77402395..4a2982f2aa224a4ceb9e90a2c775d96df1957f18 100644
--- a/roles/kubernetes-apps/meta/main.yml
+++ b/roles/kubernetes-apps/meta/main.yml
@@ -1,34 +1,46 @@
 ---
 dependencies:
   - role: kubernetes-apps/ansible
+    when:
+      - inventory_hostname == groups['kube-master'][0]
     tags:
       - apps
 
   - role: kubernetes-apps/efk
-    when: efk_enabled
+    when:
+      - efk_enabled
+      - inventory_hostname == groups['kube-master'][0]
     tags:
       - apps
       - efk
 
   - role: kubernetes-apps/helm
-    when: helm_enabled
+    when:
+      - helm_enabled
     tags:
       - apps
       - helm
 
   - role: kubernetes-apps/registry
-    when: registry_enabled
+    when:
+      - registry_enabled
+      - inventory_hostname == groups['kube-master'][0]
     tags:
       - apps
       - registry
 
   - role: kubernetes-apps/persistent_volumes
-    when: persistent_volumes_enabled
+    when:
+      - persistent_volumes_enabled
+      - inventory_hostname == groups['kube-master'][0]
     tags:
       - apps
       - persistent_volumes
 
   - role: kubernetes-apps/cloud_controller/oci
-    when: cloud_provider is defined and cloud_provider == "oci"
+    when:
+      - cloud_provider is defined
+      - cloud_provider == "oci"
+      - inventory_hostname == groups['kube-master'][0]
     tags:
       - oci
diff --git a/upgrade-cluster.yml b/upgrade-cluster.yml
index 7d8534d782c82a7e2d64ef0613b13c9f7b003ae0..cbb59e93e3147c00aeb197444a40c446ec29b89e 100644
--- a/upgrade-cluster.yml
+++ b/upgrade-cluster.yml
@@ -124,8 +124,8 @@
     - { role: dnsmasq, when: "dns_mode == 'dnsmasq_kubedns'", tags: dnsmasq }
     - { role: kubernetes/preinstall, when: "dns_mode != 'none' and resolvconf_mode == 'host_resolvconf'", tags: resolvconf }
 
-- hosts: kube-master[0]
+- hosts: kube-master
   any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
   roles:
     - { role: kubespray-defaults}
-    - { role: kubernetes-apps, tags: apps }
\ No newline at end of file
+    - { role: kubernetes-apps, tags: apps }