diff --git a/Vagrantfile b/Vagrantfile
index 9db4be3a1b963449c434cc8f5bc0bb75e7d0e7f5..536bbff2bf123c606d4a632584b2e6203db172a7 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -3,7 +3,7 @@
 
 require 'fileutils'
 
-Vagrant.require_version ">= 1.9.0"
+Vagrant.require_version ">= 2.0.0"
 
 CONFIG = File.join(File.dirname(__FILE__), "vagrant/config.rb")
 
@@ -135,12 +135,6 @@ Vagrant.configure("2") do |config|
 
       config.vm.network :private_network, ip: ip
 
-      # workaround for Vagrant 1.9.1 and centos vm
-      # https://github.com/hashicorp/vagrant/issues/8096
-      if Vagrant::VERSION == "1.9.1" && $os == "centos"
-        config.vm.provision "shell", inline: "service network restart", run: "always"
-      end
-
       # Disable swap for each vm
       config.vm.provision "shell", inline: "swapoff -a"
 
@@ -164,7 +158,7 @@ Vagrant.configure("2") do |config|
           if File.exist?(File.join(File.dirname($inventory), "hosts"))
             ansible.inventory_path = $inventory
           end
-          ansible.sudo = true
+          ansible.become = true
           ansible.limit = "all"
           ansible.host_key_checking = false
           ansible.raw_arguments = ["--forks=#{$num_instances}", "--flush-cache"]
diff --git a/ansible.cfg b/ansible.cfg
index d3102a6f41ca0223d5b603ecf9350960493a66b4..6f381690e42d6dc890dc4d0ae1eeb075abba66c2 100644
--- a/ansible.cfg
+++ b/ansible.cfg
@@ -13,3 +13,4 @@ callback_whitelist = profile_tasks
 roles_path = roles:$VIRTUAL_ENV/usr/local/share/kubespray/roles:$VIRTUAL_ENV/usr/local/share/ansible/roles:/usr/share/kubespray/roles
 deprecation_warnings=False
 inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo, .creds
+jinja2_extensions = jinja2.ext.do
diff --git a/contrib/terraform/openstack/ansible_bastion_template.txt b/contrib/terraform/openstack/ansible_bastion_template.txt
index cdf0120668a54795d850369882e8d85705bd842d..a304b2c9d5dc1703df6e09990ab9b9ebe98762d7 100644
--- a/contrib/terraform/openstack/ansible_bastion_template.txt
+++ b/contrib/terraform/openstack/ansible_bastion_template.txt
@@ -1 +1 @@
-ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -W %h:%p -q USER@BASTION_ADDRESS"' 
+ansible_ssh_common_args: "-o ProxyCommand='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -W %h:%p -q USER@BASTION_ADDRESS {% if ansible_ssh_private_key_file is defined %}-i {{ ansible_ssh_private_key_file }}{% endif %}'"
diff --git a/contrib/terraform/openstack/modules/network/outputs.tf b/contrib/terraform/openstack/modules/network/outputs.tf
index a426202b9827f274bd7e5c330fca8a636855aa27..e56a792c21c2e4426b82bf4b7d15be786ba42d14 100644
--- a/contrib/terraform/openstack/modules/network/outputs.tf
+++ b/contrib/terraform/openstack/modules/network/outputs.tf
@@ -2,6 +2,6 @@ output "router_id" {
   value = "${openstack_networking_router_interface_v2.k8s.id}"
 }
 
-output "network_id" {
+output "subnet_id" {
   value = "${openstack_networking_subnet_v2.k8s.id}"
 }
diff --git a/docs/vagrant.md b/docs/vagrant.md
index 042e8137bd2973941ccbcec497945ecd958e87ae..de47159fa7358bf835e0bffc9a9bdb97131af391 100644
--- a/docs/vagrant.md
+++ b/docs/vagrant.md
@@ -1,7 +1,7 @@
 Vagrant Install
 =================
 
-Assuming you have Vagrant (1.9+) installed with virtualbox (it may work
+Assuming you have Vagrant (2.0+) installed with virtualbox (it may work
 with vmware, but is untested) you should be able to launch a 3 node
 Kubernetes cluster by simply running `$ vagrant up`.<br />
 
diff --git a/docs/vars.md b/docs/vars.md
index 5ea76b0e566500190f38681bb20e1cddaa8900d7..a4ae65678503d7e0e932d511fa89b82369c8713c 100644
--- a/docs/vars.md
+++ b/docs/vars.md
@@ -118,6 +118,14 @@ Stack](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/dns-st
 * *kubelet_cgroup_driver* - Allows manual override of the
   cgroup-driver option for Kubelet. By default autodetection is used
   to match Docker configuration.
+* *node_labels* - Labels applied to nodes via kubelet --node-labels parameter.
+  For example, labels can be set in the inventory as variables or more widely in group_vars.
+  *node_labels* must be defined as a dict:
+```
+node_labels:
+  label1_name: label1_value
+  label2_name: label2_value
+```
 
 ##### Custom flags for Kube Components
 For all kube components, custom flags can be passed in. This allows for edge cases where users need changes to the default deployment that may not be applicable to all deployments. This can be done by providing a list of flags. Example:
diff --git a/inventory/sample/group_vars/k8s-cluster.yml b/inventory/sample/group_vars/k8s-cluster.yml
index 3e208bdaf02e80084ee8b4034f2c2a9664038ce8..031108767faf692119ee1d9715f88091bc1d78a8 100644
--- a/inventory/sample/group_vars/k8s-cluster.yml
+++ b/inventory/sample/group_vars/k8s-cluster.yml
@@ -6,7 +6,6 @@
 kube_config_dir: /etc/kubernetes
 kube_script_dir: "{{ bin_dir }}/kubernetes-scripts"
 kube_manifest_dir: "{{ kube_config_dir }}/manifests"
-system_namespace: kube-system
 
 # This is where all the cert scripts and certs will be located
 kube_cert_dir: "{{ kube_config_dir }}/ssl"
@@ -214,6 +213,10 @@ ingress_nginx_enabled: false
 # ingress_nginx_configmap_udp_services:
 #   53: "kube-system/kube-dns:53"
 
+# Cert manager deployment
+cert_manager_enabled: false
+# cert_manager_namespace: "cert-manager"
+
 # Add Persistent Volumes Storage Class for corresponding cloud provider ( OpenStack is only supported now )
 persistent_volumes_enabled: false
 
diff --git a/roles/dnsmasq/tasks/main.yml b/roles/dnsmasq/tasks/main.yml
index b6574fd27f5c44d57053d95412447a1416d04a0d..8313301752fa3efcd3d38abd602d0cfdb6d3cb6b 100644
--- a/roles/dnsmasq/tasks/main.yml
+++ b/roles/dnsmasq/tasks/main.yml
@@ -91,7 +91,7 @@
 - name: Start Resources
   kube:
     name: "{{item.item.name}}"
-    namespace: "{{system_namespace}}"
+    namespace: "kube-system"
     kubectl: "{{bin_dir}}/kubectl"
     resource: "{{item.item.type}}"
     filename: "{{kube_config_dir}}/{{item.item.file}}"
diff --git a/roles/dnsmasq/templates/dnsmasq-clusterrolebinding.yml b/roles/dnsmasq/templates/dnsmasq-clusterrolebinding.yml
index 817de877b4d59b14c6ac561dad17c2e4c96ec2a2..0fa300989bb9977a756136d35f29ed365ceca595 100644
--- a/roles/dnsmasq/templates/dnsmasq-clusterrolebinding.yml
+++ b/roles/dnsmasq/templates/dnsmasq-clusterrolebinding.yml
@@ -3,11 +3,11 @@ kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: dnsmasq
-  namespace: "{{ system_namespace }}"
+  namespace: "kube-system"
 subjects:
   - kind: ServiceAccount
     name: dnsmasq
-    namespace: "{{ system_namespace}}"
+    namespace: "kube-system"
 roleRef:
   kind: ClusterRole
   name: cluster-admin
diff --git a/roles/dnsmasq/templates/dnsmasq-deploy.yml b/roles/dnsmasq/templates/dnsmasq-deploy.yml
index 838471050349fde9ca0b916a2ce3087496a3f4ce..0fb6045e8269ad4061a8d435412553e25a78c53d 100644
--- a/roles/dnsmasq/templates/dnsmasq-deploy.yml
+++ b/roles/dnsmasq/templates/dnsmasq-deploy.yml
@@ -3,7 +3,7 @@ apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: dnsmasq
-  namespace: "{{system_namespace}}"
+  namespace: "kube-system"
   labels:
     k8s-app: dnsmasq
     kubernetes.io/cluster-service: "true"
diff --git a/roles/dnsmasq/templates/dnsmasq-serviceaccount.yml b/roles/dnsmasq/templates/dnsmasq-serviceaccount.yml
index bce8a232f355fab0e34a6ede8356d851bc60693e..91e98feee88a75aa7263ceedc5497242dd70d035 100644
--- a/roles/dnsmasq/templates/dnsmasq-serviceaccount.yml
+++ b/roles/dnsmasq/templates/dnsmasq-serviceaccount.yml
@@ -3,6 +3,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: dnsmasq
-  namespace: "{{ system_namespace }}"
+  namespace: "kube-system"
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/dnsmasq/templates/dnsmasq-svc.yml b/roles/dnsmasq/templates/dnsmasq-svc.yml
index 54dc0aa9798f89673938a320bf804d18efb732dd..f00d3d3dd854019ae6eb062bbc8e4fe7123c05f7 100644
--- a/roles/dnsmasq/templates/dnsmasq-svc.yml
+++ b/roles/dnsmasq/templates/dnsmasq-svc.yml
@@ -6,7 +6,7 @@ metadata:
     kubernetes.io/cluster-service: 'true'
     k8s-app: dnsmasq
   name: dnsmasq
-  namespace: {{system_namespace}}
+  namespace: kube-system
 spec:
   ports:
     - port: 53
diff --git a/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml
index aa10371f5ba0f13a7aaa935f1566ff1117e24c8a..3ed3e9ce7668a00cf5f8fba9922eb019a5fd6796 100644
--- a/roles/docker/defaults/main.yml
+++ b/roles/docker/defaults/main.yml
@@ -21,6 +21,10 @@ docker_dns_servers_strict: yes
 
 docker_container_storage_setup: false
 
+# Used to override obsoletes=0
+yum_conf: /etc/yum.conf
+docker_yum_conf: /etc/yum_docker.conf
+
 # CentOS/RedHat docker-ce repo
 docker_rh_repo_base_url: 'https://download.docker.com/linux/centos/7/$basearch/stable'
 docker_rh_repo_gpgkey: 'https://download.docker.com/linux/centos/gpg'
diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml
index 80b9171147a6056180afaa28cda38567c83106d1..729397b449635a607c6faf318722c5f987da4fd1 100644
--- a/roles/docker/tasks/main.yml
+++ b/roles/docker/tasks/main.yml
@@ -30,6 +30,8 @@
   tags:
     - facts
 
+- import_tasks: pre-upgrade.yml
+
 - name: ensure docker-ce repository public key is installed
   action: "{{ docker_repo_key_info.pkg_key }}"
   args:
@@ -78,11 +80,27 @@
     dest: "/etc/yum.repos.d/docker.repo"
   when: ansible_distribution in ["CentOS","RedHat"] and not is_atomic
 
+- name: Copy yum.conf for editing
+  copy:
+    src: "{{ yum_conf }}"
+    dest: "{{ docker_yum_conf }}"
+    remote_src: yes
+  when: ansible_distribution in ["CentOS","RedHat"] and not is_atomic
+
+- name: Edit copy of yum.conf to set obsoletes=0
+  lineinfile:
+    path: "{{ docker_yum_conf }}"
+    state: present
+    regexp: '^obsoletes='
+    line: 'obsoletes=0'
+  when: ansible_distribution in ["CentOS","RedHat"] and not is_atomic
+
 - name: ensure docker packages are installed
   action: "{{ docker_package_info.pkg_mgr }}"
   args:
     pkg: "{{item.name}}"
     force: "{{item.force|default(omit)}}"
+    conf_file: "{{item.yum_conf|default(omit)}}"
     state: present
   register: docker_task_result
   until: docker_task_result|succeeded
diff --git a/roles/docker/tasks/pre-upgrade.yml b/roles/docker/tasks/pre-upgrade.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9315da30535fb3277b8cbcf2251942fa9f861604
--- /dev/null
+++ b/roles/docker/tasks/pre-upgrade.yml
@@ -0,0 +1,20 @@
+---
+- name: Ensure old versions of Docker are not installed. | Debian
+  package:
+    name: '{{ item }}'
+    state: absent
+  with_items:
+    - docker
+    - docker-engine
+  when: ansible_os_family == 'Debian' and (docker_versioned_pkg[docker_version | string] | search('docker-ce'))
+
+- name: Ensure old versions of Docker are not installed. | RedHat
+  package:
+    name: '{{ item }}'
+    state: absent
+  with_items:
+    - docker
+    - docker-common
+    - docker-engine
+    - docker-selinux
+  when: ansible_os_family == 'RedHat' and (docker_versioned_pkg[docker_version | string] | search('docker-ce'))
\ No newline at end of file
diff --git a/roles/docker/vars/redhat.yml b/roles/docker/vars/redhat.yml
index 39ba211d88cf64f0758465d5ead88d8869906a1e..cd53e284c8ec12cf6ccb5d7d2a20536be8ddfe2a 100644
--- a/roles/docker/vars/redhat.yml
+++ b/roles/docker/vars/redhat.yml
@@ -28,7 +28,9 @@ docker_package_info:
   pkg_mgr: yum
   pkgs:
     - name: "{{ docker_selinux_versioned_pkg[docker_selinux_version | string] }}"
+      yum_conf: "{{ docker_yum_conf }}"
     - name: "{{ docker_versioned_pkg[docker_version | string] }}"
+      yum_conf: "{{ docker_yum_conf }}"
 
 docker_repo_key_info:
   pkg_key: ''
diff --git a/roles/download/defaults/main.yml b/roles/download/defaults/main.yml
index 26f4c89e0e8e009541a5e2f358fe578ea6cfcc44..21b6bc72d6b9b41f84a52627bc0eddc057571838 100644
--- a/roles/download/defaults/main.yml
+++ b/roles/download/defaults/main.yml
@@ -70,8 +70,8 @@ calico_policy_image_repo: "quay.io/calico/kube-controllers"
 calico_policy_image_tag: "{{ calico_policy_version }}"
 calico_rr_image_repo: "quay.io/calico/routereflector"
 calico_rr_image_tag: "{{ calico_rr_version }}"
-hyperkube_image_repo: "quay.io/coreos/hyperkube"
-hyperkube_image_tag: "{{ kube_version }}_coreos.0"
+hyperkube_image_repo: "gcr.io/google-containers/hyperkube"
+hyperkube_image_tag: "{{ kube_version }}"
 pod_infra_image_repo: "gcr.io/google_containers/pause-amd64"
 pod_infra_image_tag: "{{ pod_infra_version }}"
 install_socat_image_repo: "xueshanf/install-socat"
@@ -124,7 +124,6 @@ fluentd_image_tag: "{{ fluentd_version }}"
 kibana_version: "v4.6.1"
 kibana_image_repo: "gcr.io/google_containers/kibana"
 kibana_image_tag: "{{ kibana_version }}"
-
 helm_version: "v2.8.1"
 helm_image_repo: "lachlanevenson/k8s-helm"
 helm_image_tag: "{{ helm_version }}"
@@ -132,6 +131,11 @@ tiller_image_repo: "gcr.io/kubernetes-helm/tiller"
 tiller_image_tag: "{{ helm_version }}"
 vault_image_repo: "vault"
 vault_image_tag: "{{ vault_version }}"
+cert_manager_version: "v0.2.3"
+cert_manager_controller_image_repo: "quay.io/jetstack/cert-manager-controller"
+cert_manager_controller_image_tag: "{{ cert_manager_version }}"
+cert_manager_ingress_shim_image_repo: "quay.io/jetstack/cert-manager-ingress-shim"
+cert_manager_ingress_shim_image_tag: "{{ cert_manager_version }}"
 
 downloads:
   netcheck_server:
@@ -140,18 +144,24 @@ downloads:
     repo: "{{ netcheck_server_img_repo }}"
     tag: "{{ netcheck_server_tag }}"
     sha256: "{{ netcheck_server_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   netcheck_agent:
     enabled: "{{ deploy_netchecker }}"
     container: true
     repo: "{{ netcheck_agent_img_repo }}"
     tag: "{{ netcheck_agent_tag }}"
     sha256: "{{ netcheck_agent_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   etcd:
     enabled: true
     container: true
     repo: "{{ etcd_image_repo }}"
     tag: "{{ etcd_image_tag }}"
     sha256: "{{ etcd_digest_checksum|default(None) }}"
+    groups:
+      - etcd
   kubeadm:
     enabled: "{{ kubeadm_enabled }}"
     file: true
@@ -163,6 +173,8 @@ downloads:
     unarchive: false
     owner: "root"
     mode: "0755"
+    groups:
+      - k8s-cluster
   istioctl:
     enabled: "{{ istio_enabled }}"
     file: true
@@ -174,140 +186,186 @@ downloads:
     unarchive: false
     owner: "root"
     mode: "0755"
+    groups:
+      - kube-master
   hyperkube:
     enabled: true
     container: true
     repo: "{{ hyperkube_image_repo }}"
     tag: "{{ hyperkube_image_tag }}"
     sha256: "{{ hyperkube_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   cilium:
     enabled: "{{ kube_network_plugin == 'cilium' }}"
     container: true
     repo: "{{ cilium_image_repo }}"
     tag: "{{ cilium_image_tag }}"
     sha256: "{{ cilium_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   flannel:
     enabled: "{{ kube_network_plugin == 'flannel' or kube_network_plugin == 'canal' }}"
     container: true
     repo: "{{ flannel_image_repo }}"
     tag: "{{ flannel_image_tag }}"
     sha256: "{{ flannel_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   flannel_cni:
     enabled: "{{ kube_network_plugin == 'flannel' }}"
     container: true
     repo: "{{ flannel_cni_image_repo }}"
     tag: "{{ flannel_cni_image_tag }}"
     sha256: "{{ flannel_cni_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   calicoctl:
     enabled: "{{ kube_network_plugin == 'calico' or kube_network_plugin == 'canal' }}"
     container: true
     repo: "{{ calicoctl_image_repo }}"
     tag: "{{ calicoctl_image_tag }}"
     sha256: "{{ calicoctl_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   calico_node:
     enabled: "{{ kube_network_plugin == 'calico' or kube_network_plugin == 'canal' }}"
     container: true
     repo: "{{ calico_node_image_repo }}"
     tag: "{{ calico_node_image_tag }}"
     sha256: "{{ calico_node_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   calico_cni:
     enabled: "{{ kube_network_plugin == 'calico' or kube_network_plugin == 'canal' }}"
     container: true
     repo: "{{ calico_cni_image_repo }}"
     tag: "{{ calico_cni_image_tag }}"
     sha256: "{{ calico_cni_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   calico_policy:
     enabled: "{{ enable_network_policy or kube_network_plugin == 'canal' }}"
     container: true
     repo: "{{ calico_policy_image_repo }}"
     tag: "{{ calico_policy_image_tag }}"
     sha256: "{{ calico_policy_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   calico_rr:
     enabled: "{{ peer_with_calico_rr is defined and peer_with_calico_rr and kube_network_plugin == 'calico' }}"
     container: true
     repo: "{{ calico_rr_image_repo }}"
     tag: "{{ calico_rr_image_tag }}"
     sha256: "{{ calico_rr_digest_checksum|default(None) }}"
+    groups:
+      - calico-rr
   weave_kube:
     enabled: "{{ kube_network_plugin == 'weave' }}"
     container: true
     repo: "{{ weave_kube_image_repo }}"
     tag: "{{ weave_kube_image_tag }}"
     sha256: "{{ weave_kube_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   weave_npc:
     enabled: "{{ kube_network_plugin == 'weave' }}"
     container: true
     repo: "{{ weave_npc_image_repo }}"
     tag: "{{ weave_npc_image_tag }}"
     sha256: "{{ weave_npc_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   contiv:
     enabled: "{{ kube_network_plugin == 'contiv' }}"
     container: true
     repo: "{{ contiv_image_repo }}"
     tag: "{{ contiv_image_tag }}"
     sha256: "{{ contiv_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   contiv_auth_proxy:
     enabled: "{{ kube_network_plugin == 'contiv' }}"
     container: true
     repo: "{{ contiv_auth_proxy_image_repo }}"
     tag: "{{ contiv_auth_proxy_image_tag }}"
     sha256: "{{ contiv_auth_proxy_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   pod_infra:
     enabled: true
     container: true
     repo: "{{ pod_infra_image_repo }}"
     tag: "{{ pod_infra_image_tag }}"
     sha256: "{{ pod_infra_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   install_socat:
     enabled: "{{ ansible_os_family in ['CoreOS', 'Container Linux by CoreOS'] }}"
     container: true
     repo: "{{ install_socat_image_repo }}"
     tag: "{{ install_socat_image_tag }}"
     sha256: "{{ install_socat_digest_checksum|default(None) }}"
+    groups:
+      - k8s-cluster
   nginx:
-    enabled: true
+    enabled: "{{ loadbalancer_apiserver_localhost }}"
     container: true
     repo: "{{ nginx_image_repo }}"
     tag: "{{ nginx_image_tag }}"
     sha256: "{{ nginx_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   dnsmasq:
     enabled: "{{ dns_mode == 'dnsmasq_kubedns' }}"
     container: true
     repo: "{{ dnsmasq_image_repo }}"
     tag: "{{ dnsmasq_image_tag }}"
     sha256: "{{ dnsmasq_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   kubedns:
     enabled: "{{ dns_mode in ['kubedns', 'dnsmasq_kubedns'] }}"
     container: true
     repo: "{{ kubedns_image_repo }}"
     tag: "{{ kubedns_image_tag }}"
     sha256: "{{ kubedns_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   coredns:
     enabled: "{{ dns_mode in ['coredns', 'coredns_dual'] }}"
     container: true
     repo: "{{ coredns_image_repo }}"
     tag: "{{ coredns_image_tag }}"
     sha256: "{{ coredns_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   dnsmasq_nanny:
     enabled: "{{ dns_mode in ['kubedns', 'dnsmasq_kubedns'] }}"
     container: true
     repo: "{{ dnsmasq_nanny_image_repo }}"
     tag: "{{ dnsmasq_nanny_image_tag }}"
     sha256: "{{ dnsmasq_nanny_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   dnsmasq_sidecar:
     enabled: "{{ dns_mode in ['kubedns', 'dnsmasq_kubedns'] }}"
     container: true
     repo: "{{ dnsmasq_sidecar_image_repo }}"
     tag: "{{ dnsmasq_sidecar_image_tag }}"
     sha256: "{{ dnsmasq_sidecar_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   kubednsautoscaler:
     enabled: "{{ dns_mode in ['kubedns', 'dnsmasq_kubedns'] }}"
     container: true
     repo: "{{ kubednsautoscaler_image_repo }}"
     tag: "{{ kubednsautoscaler_image_tag }}"
     sha256: "{{ kubednsautoscaler_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   testbox:
-    enabled: true
+    enabled: false
     container: true
     repo: "{{ test_image_repo }}"
     tag: "{{ test_image_tag }}"
@@ -318,30 +376,40 @@ downloads:
     repo: "{{ elasticsearch_image_repo }}"
     tag: "{{ elasticsearch_image_tag }}"
     sha256: "{{ elasticsearch_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   fluentd:
     enabled: "{{ efk_enabled }}"
     container: true
     repo: "{{ fluentd_image_repo }}"
     tag: "{{ fluentd_image_tag }}"
     sha256: "{{ fluentd_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   kibana:
     enabled: "{{ efk_enabled }}"
     container: true
     repo: "{{ kibana_image_repo }}"
     tag: "{{ kibana_image_tag }}"
     sha256: "{{ kibana_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   helm:
     enabled: "{{ helm_enabled }}"
     container: true
     repo: "{{ helm_image_repo }}"
     tag: "{{ helm_image_tag }}"
     sha256: "{{ helm_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   tiller:
     enabled: "{{ helm_enabled }}"
     container: true
     repo: "{{ tiller_image_repo }}"
     tag: "{{ tiller_image_tag }}"
     sha256: "{{ tiller_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
   vault:
     enabled: "{{ cert_management == 'vault' }}"
     container: "{{ vault_deployment_type != 'host' }}"
@@ -356,6 +424,24 @@ downloads:
     unarchive: true
     url: "{{ vault_download_url }}"
     version: "{{ vault_version }}"
+    groups:
+      - vault
+  cert_manager_controller:
+    enabled: "{{ cert_manager_enabled }}"
+    container: true
+    repo: "{{ cert_manager_controller_image_repo }}"
+    tag: "{{ cert_manager_controller_image_tag }}"
+    sha256: "{{ cert_manager_controller_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
+  cert_manager_ingress_shim:
+    enabled: "{{ cert_manager_enabled }}"
+    container: true
+    repo: "{{ cert_manager_ingress_shim_image_repo }}"
+    tag: "{{ cert_manager_ingress_shim_image_tag }}"
+    sha256: "{{ cert_manager_ingress_shim_digest_checksum|default(None) }}"
+    groups:
+      - kube-node
 
 download_defaults:
   container: false
diff --git a/roles/download/tasks/download_container.yml b/roles/download/tasks/download_container.yml
index bbf7cec85f307ea3c9634ea643ab07d8fc9068d3..a5659619c11e384c41f04e7cc8306b770c042c3d 100644
--- a/roles/download/tasks/download_container.yml
+++ b/roles/download/tasks/download_container.yml
@@ -7,6 +7,7 @@
   when:
     - download.enabled
     - download.container
+    - group_names | intersect(download.groups) | length
   tags:
     - facts
 
@@ -23,6 +24,7 @@
     - download.enabled
     - download.container
     - pull_required|default(download_always_pull)
+    - group_names | intersect(download.groups) | length
   delegate_to: "{{ download_delegate }}"
   delegate_facts: yes
   run_once: yes
@@ -38,3 +40,4 @@
     - download.enabled
     - download.container
     - pull_required|default(download_always_pull)
+    - group_names | intersect(download.groups) | length
diff --git a/roles/download/tasks/download_file.yml b/roles/download/tasks/download_file.yml
index 664fa4728580c822b801419a93cc2ea064261124..832fec41ea0a800abb89833dbad28630b26ae14d 100644
--- a/roles/download/tasks/download_file.yml
+++ b/roles/download/tasks/download_file.yml
@@ -13,6 +13,7 @@
   when:
     - download.enabled
     - download.file
+    - group_names | intersect(download.groups) | length
 
 - name: file_download | Download item
   get_url:
@@ -28,6 +29,7 @@
   when:
     - download.enabled
     - download.file
+    - group_names | intersect(download.groups) | length
 
 - name: file_download | Extract archives
   unarchive:
@@ -40,3 +42,4 @@
     - download.enabled
     - download.file
     - download.unarchive|default(False)
+    - group_names | intersect(download.groups) | length
diff --git a/roles/download/tasks/sync_container.yml b/roles/download/tasks/sync_container.yml
index a15f78cde44e41bf39fc680268e2dfa3d2fa7b50..1ca84ad671d7ef623f34476b616f074dc395d83f 100644
--- a/roles/download/tasks/sync_container.yml
+++ b/roles/download/tasks/sync_container.yml
@@ -7,6 +7,7 @@
   when:
     - download.enabled
     - download.container
+    - group_names | intersect(download.groups) | length
   tags:
     - facts
 
@@ -17,6 +18,7 @@
     - download.enabled
     - download.container
     - download_run_once
+    - group_names | intersect(download.groups) | length
   tags:
     - facts
 
@@ -27,6 +29,7 @@
     - download.enabled
     - download.container
     - download_run_once
+    - group_names | intersect(download.groups) | length
 
 - name: "container_download | Update the 'container_changed' fact"
   set_fact:
@@ -36,6 +39,7 @@
     - download.container
     - download_run_once
     - pull_required|default(download_always_pull)
+    - group_names | intersect(download.groups) | length
   run_once: "{{ download_run_once }}"
   tags:
     - facts
@@ -53,6 +57,7 @@
     - download.enabled
     - download.container
     - download_run_once
+    - group_names | intersect(download.groups) | length
   tags:
     - facts
 
@@ -68,6 +73,7 @@
     - download_run_once
     - (ansible_os_family not in ["CoreOS", "Container Linux by CoreOS"] or download_delegate == "localhost")
     - (container_changed or not img.stat.exists)
+    - group_names | intersect(download.groups) | length
 
 - name: container_download | copy container images to ansible host
   synchronize:
@@ -87,6 +93,7 @@
     - inventory_hostname == download_delegate
     - download_delegate != "localhost"
     - saved.changed
+    - group_names | intersect(download.groups) | length
 
 - name: container_download | upload container images to nodes
   synchronize:
@@ -108,6 +115,7 @@
     - (ansible_os_family not in ["CoreOS", "Container Linux by CoreOS"] and
       inventory_hostname != download_delegate or
       download_delegate == "localhost")
+    - group_names | intersect(download.groups) | length
   tags:
     - upload
     - upgrade
@@ -120,6 +128,7 @@
     - download_run_once
     - (ansible_os_family not in ["CoreOS", "Container Linux by CoreOS"] and
       inventory_hostname != download_delegate or download_delegate == "localhost")
+    - group_names | intersect(download.groups) | length
   tags:
     - upload
     - upgrade
diff --git a/roles/etcd/defaults/main.yml b/roles/etcd/defaults/main.yml
index 5f16db1d17036a52ed47befb49a722171e0e04ed..6c13810c525daecd5055c9f0a76431437b4edc98 100644
--- a/roles/etcd/defaults/main.yml
+++ b/roles/etcd/defaults/main.yml
@@ -12,9 +12,9 @@ etcd_cert_group: root
 # Note: This does not set up DNS entries. It simply adds the following DNS
 # entries to the certificate
 etcd_cert_alt_names:
-  - "etcd.{{ system_namespace }}.svc.{{ dns_domain }}"
-  - "etcd.{{ system_namespace }}.svc"
-  - "etcd.{{ system_namespace }}"
+  - "etcd.kube-system.svc.{{ dns_domain }}"
+  - "etcd.kube-system.svc"
+  - "etcd.kube-system"
   - "etcd"
 
 etcd_script_dir: "{{ bin_dir }}/etcd-scripts"
@@ -22,12 +22,12 @@ etcd_script_dir: "{{ bin_dir }}/etcd-scripts"
 etcd_heartbeat_interval: "250"
 etcd_election_timeout: "5000"
 
-#etcd_snapshot_count: "10000"
+# etcd_snapshot_count: "10000"
 
 # Parameters for ionice
 # -c takes an integer between 0 and 3 or one of the strings none, realtime, best-effort or idle.
 # -n takes an integer between 0 (highest priority) and 7 (lowest priority)
-#etcd_ionice: "-c2 -n0"
+# etcd_ionice: "-c2 -n0"
 
 etcd_metrics: "basic"
 
diff --git a/roles/etcd/handlers/backup.yml b/roles/etcd/handlers/backup.yml
index 247b2ae004c1fc0306f8020f83720394cabcdfba..a0a80e10899adbc967cef63b7f90dfff0aba22f0 100644
--- a/roles/etcd/handlers/backup.yml
+++ b/roles/etcd/handlers/backup.yml
@@ -48,7 +48,7 @@
       snapshot save {{ etcd_backup_directory }}/snapshot.db
   environment:
     ETCDCTL_API: 3
-    ETCDCTL_CERT: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
   retries: 3
   delay: "{{ retry_stagger | random + 3 }}"
diff --git a/roles/etcd/tasks/configure.yml b/roles/etcd/tasks/configure.yml
index d7d3920c65b6038613a1e9cf4540ee81bf80e876..d39ba62d4ff8a193f55c1e57722509d8f9720f97 100644
--- a/roles/etcd/tasks/configure.yml
+++ b/roles/etcd/tasks/configure.yml
@@ -9,8 +9,8 @@
   tags:
     - facts
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
 
 - name: Configure | Check if member is in etcd-events cluster
   shell: "{{ bin_dir }}/etcdctl --no-sync --endpoints={{ etcd_events_access_addresses }} member list | grep -q {{ etcd_access_address }}"
@@ -22,8 +22,8 @@
   tags:
     - facts
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
 
 - name: Configure | Copy etcd.service systemd file
   template:
diff --git a/roles/etcd/tasks/join_etcd-events_member.yml b/roles/etcd/tasks/join_etcd-events_member.yml
index 104ef22dfbfa312cf68867fe711361938857b70b..5a7061880e13a9b1371e7ae2d02152b4e8dc1bd7 100644
--- a/roles/etcd/tasks/join_etcd-events_member.yml
+++ b/roles/etcd/tasks/join_etcd-events_member.yml
@@ -7,8 +7,8 @@
   delay: "{{ retry_stagger | random + 3 }}"
   when: target_node == inventory_hostname
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
 
 - include_tasks: refresh_config.yml
   vars:
@@ -43,5 +43,5 @@
     - facts
   when: target_node == inventory_hostname
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
diff --git a/roles/etcd/tasks/join_etcd_member.yml b/roles/etcd/tasks/join_etcd_member.yml
index b7801f0c916c792a6a061ebaccfabbe91d744c31..d11037151f7451c2fcbb55e0af8c20c4261a585e 100644
--- a/roles/etcd/tasks/join_etcd_member.yml
+++ b/roles/etcd/tasks/join_etcd_member.yml
@@ -7,8 +7,8 @@
   delay: "{{ retry_stagger | random + 3 }}"
   when: target_node == inventory_hostname
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
 
 - include_tasks: refresh_config.yml
   vars:
@@ -43,5 +43,5 @@
     - facts
   when: target_node == inventory_hostname
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
diff --git a/roles/etcd/tasks/join_member.yml b/roles/etcd/tasks/join_member.yml
index b7801f0c916c792a6a061ebaccfabbe91d744c31..d11037151f7451c2fcbb55e0af8c20c4261a585e 100644
--- a/roles/etcd/tasks/join_member.yml
+++ b/roles/etcd/tasks/join_member.yml
@@ -7,8 +7,8 @@
   delay: "{{ retry_stagger | random + 3 }}"
   when: target_node == inventory_hostname
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
 
 - include_tasks: refresh_config.yml
   vars:
@@ -43,5 +43,5 @@
     - facts
   when: target_node == inventory_hostname
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
diff --git a/roles/etcd/tasks/main.yml b/roles/etcd/tasks/main.yml
index bb299126be4e18f67f679c2ea524c263cd431a17..a64d9b097d05229cdc3a86e5bde2f82466c15bdf 100644
--- a/roles/etcd/tasks/main.yml
+++ b/roles/etcd/tasks/main.yml
@@ -29,13 +29,13 @@
   tags:
     - upgrade
 
-- import_tasks: set_cluster_health.yml
+- include_tasks: set_cluster_health.yml
   when: is_etcd_master and etcd_cluster_setup
 
-- import_tasks: configure.yml
+- include_tasks: configure.yml
   when: is_etcd_master and etcd_cluster_setup
 
-- import_tasks: refresh_config.yml
+- include_tasks: refresh_config.yml
   when: is_etcd_master and etcd_cluster_setup
 
 - name: Restart etcd if certs changed
@@ -68,8 +68,8 @@
 # After etcd cluster is assembled, make sure that
 # initial state of the cluster is in `existing`
 # state insted of `new`.
-- import_tasks: set_cluster_health.yml
+- include_tasks: set_cluster_health.yml
   when: is_etcd_master and etcd_cluster_setup
 
-- import_tasks: refresh_config.yml
+- include_tasks: refresh_config.yml
   when: is_etcd_master and etcd_cluster_setup
diff --git a/roles/etcd/tasks/set_cluster_health.yml b/roles/etcd/tasks/set_cluster_health.yml
index 68e738031a58accfbf629774848a5e4439ee95e8..d0202943c481041a551983c33867056360978b40 100644
--- a/roles/etcd/tasks/set_cluster_health.yml
+++ b/roles/etcd/tasks/set_cluster_health.yml
@@ -9,8 +9,8 @@
   tags:
     - facts
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
 
 - name: Configure | Check if etcd-events cluster is healthy
   shell: "{{ bin_dir }}/etcdctl --endpoints={{ etcd_events_access_addresses }} cluster-health | grep -q 'cluster is healthy'"
@@ -22,5 +22,5 @@
   tags:
     - facts
   environment:
-    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem"
-    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/node-{{ inventory_hostname }}-key.pem"
+    ETCDCTL_CERT_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem"
+    ETCDCTL_KEY_FILE: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
diff --git a/roles/etcd/templates/openssl.conf.j2 b/roles/etcd/templates/openssl.conf.j2
index 48327f0bfa667bd4f325833a6b5e4cc553ba13c3..2f4f7e26275b42c058d42768860bf6be4ffa30ff 100644
--- a/roles/etcd/templates/openssl.conf.j2
+++ b/roles/etcd/templates/openssl.conf.j2
@@ -1,4 +1,4 @@
-[req]
+{% set counter = {'dns': 2,'ip': 1,} %}{% macro increment(dct, key, inc=1)%}{% if dct.update({key: dct[key] + inc}) %} {% endif %}{% endmacro %}[req]
 req_extensions = v3_req
 distinguished_name = req_distinguished_name
 
@@ -25,19 +25,18 @@ authorityKeyIdentifier=keyid:always,issuer
 [alt_names]
 DNS.1 = localhost
 {% for host in groups['etcd'] %}
-DNS.{{ 1 + loop.index }} = {{ host }}
+DNS.{{ counter["dns"] }} = {{ host }}{{ increment(counter, 'dns') }}
 {% endfor %}
-{% if loadbalancer_apiserver is defined %}
-{% set idx =  groups['etcd'] | length | int + 2 %}
-DNS.{{ idx | string }} = {{ apiserver_loadbalancer_domain_name }}
+{% if apiserver_loadbalancer_domain_name is defined %}
+DNS.{{ counter["dns"] }} = {{ apiserver_loadbalancer_domain_name }}{{ increment(counter, 'dns') }}
 {% endif %}
-{% set idx =  groups['etcd'] | length | int + 3 %}
 {% for etcd_alt_name in etcd_cert_alt_names %}
-DNS.{{ idx + 1 + loop.index }} = {{ etcd_alt_name }}
+DNS.{{ counter["dns"] }} = {{ etcd_alt_name }}{{ increment(counter, 'dns') }}
 {% endfor %}
 {% for host in groups['etcd'] %}
-IP.{{ 2 * loop.index - 1 }} = {{ hostvars[host]['access_ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}
-IP.{{ 2 * loop.index }} = {{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}
+{% if hostvars[host]['access_ip'] is defined  %}
+IP.{{ counter["ip"] }} = {{ hostvars[host]['access_ip'] }}{{ increment(counter, 'ip') }}
+{% endif %}
+IP.{{ counter["ip"] }} = {{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}{{ increment(counter, 'ip') }}
 {% endfor %}
-{% set idx =  groups['etcd'] | length | int * 2 + 1 %}
-IP.{{ idx }} = 127.0.0.1
+IP.{{ counter["ip"] }} = 127.0.0.1
diff --git a/roles/kubernetes-apps/ansible/tasks/cleanup_dns.yml b/roles/kubernetes-apps/ansible/tasks/cleanup_dns.yml
index 5f8356cf9f2ee7e0a954cd485c94a025e5b81861..e77f1e7991e677be6c3514c418fcaca4d8b44717 100644
--- a/roles/kubernetes-apps/ansible/tasks/cleanup_dns.yml
+++ b/roles/kubernetes-apps/ansible/tasks/cleanup_dns.yml
@@ -2,7 +2,7 @@
 - name: Kubernetes Apps | Delete old CoreDNS resources
   kube:
     name: "coredns"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{ bin_dir }}/kubectl"
     resource: "{{ item }}"
     state: absent
@@ -16,7 +16,7 @@
 - name: Kubernetes Apps | Delete kubeadm CoreDNS
   kube:
     name: "coredns"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{ bin_dir }}/kubectl"
     resource: "deploy"
     state: absent
@@ -28,7 +28,7 @@
 - name: Kubernetes Apps | Delete old KubeDNS resources
   kube:
     name: "kube-dns"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{ bin_dir }}/kubectl"
     resource: "{{ item }}"
     state: absent
@@ -41,7 +41,7 @@
 - name: Kubernetes Apps | Delete kubeadm KubeDNS
   kube:
     name: "kube-dns"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{ bin_dir }}/kubectl"
     resource: "{{ item }}"
     state: absent
diff --git a/roles/kubernetes-apps/ansible/tasks/dashboard.yml b/roles/kubernetes-apps/ansible/tasks/dashboard.yml
index ce56bd5d10a0cfc57cb9d94b1365abe96bcf3411..4c9ad5c7426f97074322b171d3b3d5866ad2ea71 100644
--- a/roles/kubernetes-apps/ansible/tasks/dashboard.yml
+++ b/roles/kubernetes-apps/ansible/tasks/dashboard.yml
@@ -22,7 +22,7 @@
 - name: Kubernetes Apps | Start dashboard
   kube:
     name: "{{ item.item.name }}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{ bin_dir }}/kubectl"
     resource: "{{ item.item.type }}"
     filename: "{{ kube_config_dir }}/{{ item.item.file }}"
diff --git a/roles/kubernetes-apps/ansible/tasks/main.yml b/roles/kubernetes-apps/ansible/tasks/main.yml
index 55d417982742ffe98bbac5f81ffca9f1870ad45b..ceb667f69dab1c72150ba8625bd2367bd155de1c 100644
--- a/roles/kubernetes-apps/ansible/tasks/main.yml
+++ b/roles/kubernetes-apps/ansible/tasks/main.yml
@@ -37,7 +37,7 @@
 - name: Kubernetes Apps | Start Resources
   kube:
     name: "{{ item.item.name }}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{ bin_dir }}/kubectl"
     resource: "{{ item.item.type }}"
     filename: "{{ kube_config_dir }}/{{ item.item.file }}"
@@ -50,6 +50,10 @@
     - dns_mode != 'none'
     - inventory_hostname == groups['kube-master'][0]
     - not item|skipped
+  register: resource_result
+  until: resource_result|succeeded
+  retries: 4
+  delay: 5
   tags:
     - dnsmasq
 
diff --git a/roles/kubernetes-apps/ansible/templates/coredns-clusterrolebinding.yml.j2 b/roles/kubernetes-apps/ansible/templates/coredns-clusterrolebinding.yml.j2
index 6c49d047f519b69361bbc973f294ee2d0bc6bc4e..89becd5b44b1ee2a767d4ebed83cc23ea52c9b7a 100644
--- a/roles/kubernetes-apps/ansible/templates/coredns-clusterrolebinding.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/coredns-clusterrolebinding.yml.j2
@@ -15,4 +15,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: coredns
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2 b/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2
index 983d2579feaed268ee3b9f87b951bfc873f710ad..360480c1e731a98d8eb878eceb9e7559f6bc6d5c 100644
--- a/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/coredns-config.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: ConfigMap
 metadata:
   name: coredns
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     addonmanager.kubernetes.io/mode: EnsureExists
 data:
diff --git a/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2 b/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2
index 30128d566d22d99b3da75a30c2399b4150dfc7ef..5cba6f1f09212d9ed2cee94900f230cd0513d008 100644
--- a/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/coredns-deployment.yml.j2
@@ -3,7 +3,7 @@ apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: coredns{{ coredns_ordinal_suffix | default('') }}
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: coredns{{ coredns_ordinal_suffix | default('') }}
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/ansible/templates/coredns-sa.yml.j2 b/roles/kubernetes-apps/ansible/templates/coredns-sa.yml.j2
index db5682354c9f106cd56b6899e09ba306fa79387c..64d9c4dae27d29ae9eeabd9c763861da69cb5d82 100644
--- a/roles/kubernetes-apps/ansible/templates/coredns-sa.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/coredns-sa.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: coredns
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
     addonmanager.kubernetes.io/mode: Reconcile
diff --git a/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2 b/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2
index c5b76b0b59bd7574085b9e33b414976a3a0a1f0d..193de10eb976c58f73285efe9aa20fe6b28740d8 100644
--- a/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/coredns-svc.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: Service
 metadata:
   name: coredns{{ coredns_ordinal_suffix | default('') }}
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: coredns{{ coredns_ordinal_suffix | default('') }}
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2 b/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2
index b1ba1481de20b95ebd54575cf1767f207e5a25d4..5f0a40cb3af70e8b68f1c1f147b0b0e3a2db5d8f 100644
--- a/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/dashboard.yml.j2
@@ -25,7 +25,7 @@ metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard-certs
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 type: Opaque
 
 ---
@@ -37,7 +37,7 @@ metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 
 ---
 # ------------------- Dashboard Role & Role Binding ------------------- #
@@ -46,7 +46,7 @@ kind: Role
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: kubernetes-dashboard-minimal
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 rules:
   # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
 - apiGroups: [""]
@@ -81,7 +81,7 @@ apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
   name: kubernetes-dashboard-minimal
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: Role
@@ -89,7 +89,7 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: kubernetes-dashboard
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 
 ---
 # ------------------- Gross Hack For anonymous auth through api proxy ------------------- #
@@ -103,7 +103,7 @@ rules:
   resources: ["services/proxy"]
   resourceNames: ["https:kubernetes-dashboard:"]
   verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
-- nonResourceURLs: ["/ui", "/ui/*", "/api/v1/namespaces/{{ system_namespace }}/services/https:kubernetes-dashboard:/proxy/*"]
+- nonResourceURLs: ["/ui", "/ui/*", "/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/*"]
   verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
 
 ---
@@ -128,7 +128,7 @@ metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 spec:
   replicas: 1
   revisionHistoryLimit: 10
@@ -200,7 +200,7 @@ metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 spec:
   ports:
     - port: 443
diff --git a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrole.yml.j2 b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrole.yml.j2
index f80d3d90c17f95a79b448dc41fcd5c891bf463b1..e29ed4dac54bb710f492d0be2046cf5863719004 100644
--- a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrole.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrole.yml.j2
@@ -17,7 +17,7 @@ kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: cluster-proportional-autoscaler
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 rules:
   - apiGroups: [""]
     resources: ["nodes"]
diff --git a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrolebinding.yml.j2 b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrolebinding.yml.j2
index eb76f2d4ecbcbf5b3623cde5c1b0c864c47cbbc7..3b11c6b9fcb1a8912188b7cbe8579d5e7de375d4 100644
--- a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrolebinding.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-clusterrolebinding.yml.j2
@@ -17,11 +17,11 @@ kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: cluster-proportional-autoscaler
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 subjects:
   - kind: ServiceAccount
     name: cluster-proportional-autoscaler
-    namespace: {{ system_namespace }}
+    namespace: kube-system
 roleRef:
   kind: ClusterRole
   name: cluster-proportional-autoscaler
diff --git a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-sa.yml.j2 b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-sa.yml.j2
index 542ae86cec4c8af60cd6eba5efc5fc33a3213912..4c440f653f134e2bde87fcf330ad9ef6c9a60f82 100644
--- a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-sa.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler-sa.yml.j2
@@ -17,4 +17,4 @@ kind: ServiceAccount
 apiVersion: v1
 metadata:
   name: cluster-proportional-autoscaler
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler.yml.j2 b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler.yml.j2
index df92ee6156bc9411445eb3b402854d2f06922b6f..d7c30ecebcaa9a507542a85f1eeab89ccf8a1980 100644
--- a/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/kubedns-autoscaler.yml.j2
@@ -17,7 +17,7 @@ apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: kubedns-autoscaler
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: kubedns-autoscaler
     kubernetes.io/cluster-service: "true"
@@ -40,7 +40,7 @@ spec:
             memory: "10Mi"
         command:
         - /cluster-proportional-autoscaler
-        - --namespace={{ system_namespace }}
+        - --namespace=kube-system
         - --configmap=kubedns-autoscaler
         # Should keep target in sync with cluster/addons/dns/kubedns-controller.yaml.base
         - --target=Deployment/kube-dns
diff --git a/roles/kubernetes-apps/ansible/templates/kubedns-deploy.yml.j2 b/roles/kubernetes-apps/ansible/templates/kubedns-deploy.yml.j2
index 682bdf49130050e9c74a5dbda7cb8e0bc0a0acce..cfce65f0efe6b8843b691e3074e478efa44dca3f 100644
--- a/roles/kubernetes-apps/ansible/templates/kubedns-deploy.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/kubedns-deploy.yml.j2
@@ -3,7 +3,7 @@ apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: kube-dns
-  namespace: "{{system_namespace}}"
+  namespace: kube-system
   labels:
     k8s-app: kube-dns
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/ansible/templates/kubedns-sa.yml.j2 b/roles/kubernetes-apps/ansible/templates/kubedns-sa.yml.j2
index f399fd6f4b400453aaece8f61807b5cad5b55b28..296a3a938201181734d041e404d637bdd6e738c7 100644
--- a/roles/kubernetes-apps/ansible/templates/kubedns-sa.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/kubedns-sa.yml.j2
@@ -3,6 +3,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: kube-dns
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/ansible/templates/kubedns-svc.yml.j2 b/roles/kubernetes-apps/ansible/templates/kubedns-svc.yml.j2
index 1c4710db13b20db82fba293c29a0f92b1fbec7e0..6bc5f9240e13469410a80eb613a2e4ed32f1e3c5 100644
--- a/roles/kubernetes-apps/ansible/templates/kubedns-svc.yml.j2
+++ b/roles/kubernetes-apps/ansible/templates/kubedns-svc.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: Service
 metadata:
   name: kube-dns
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: kube-dns
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/cluster_roles/tasks/main.yml b/roles/kubernetes-apps/cluster_roles/tasks/main.yml
index c576586a20dc1ce041ccc0200988e2d85a31b6ba..fefa7caeb078ff96c54d84ee4e18373dca693bb9 100644
--- a/roles/kubernetes-apps/cluster_roles/tasks/main.yml
+++ b/roles/kubernetes-apps/cluster_roles/tasks/main.yml
@@ -126,32 +126,3 @@
     - kube_version | version_compare('v1.9.3', '<=')
     - inventory_hostname == groups['kube-master'][0]
   tags: vsphere
-
-# This is not a cluster role, but should be run after kubeconfig is set on master
-- name: Write kube system namespace manifest
-  template:
-    src: namespace.j2
-    dest: "{{kube_config_dir}}/{{system_namespace}}-ns.yml"
-  when: inventory_hostname == groups['kube-master'][0]
-  tags:
-    - apps
-
-- name: Check if kube system namespace exists
-  command: "{{ bin_dir }}/kubectl get ns {{system_namespace}}"
-  register: 'kubesystem'
-  changed_when: False
-  failed_when: False
-  when: inventory_hostname == groups['kube-master'][0]
-  tags:
-    - apps
-
-- name: Create kube system namespace
-  command: "{{ bin_dir }}/kubectl create -f {{kube_config_dir}}/{{system_namespace}}-ns.yml"
-  retries: 4
-  delay: "{{ retry_stagger | random + 3 }}"
-  register: create_system_ns
-  until: create_system_ns.rc == 0
-  changed_when: False
-  when: inventory_hostname == groups['kube-master'][0] and kubesystem.rc != 0
-  tags:
-    - apps
diff --git a/roles/kubernetes-apps/cluster_roles/templates/namespace.j2 b/roles/kubernetes-apps/cluster_roles/templates/namespace.j2
index 9bdf201a21a84c558b75a5763480bb6407ca5388..f2e115a6acfc27b9c7b33bfa58161487678c63e1 100644
--- a/roles/kubernetes-apps/cluster_roles/templates/namespace.j2
+++ b/roles/kubernetes-apps/cluster_roles/templates/namespace.j2
@@ -1,4 +1,4 @@
 apiVersion: v1
 kind: Namespace
 metadata:
-  name: "{{system_namespace}}"
+  name: "kube-system"
diff --git a/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml b/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml
index 8abbe231711db90d374cab33288cea594764dfd3..b6055132b00de1c2e840a77a40410202972fedce 100644
--- a/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml
+++ b/roles/kubernetes-apps/efk/elasticsearch/tasks/main.yml
@@ -10,7 +10,7 @@
   when: rbac_enabled
 
 - name: "ElasticSearch | Create Serviceaccount and Clusterrolebinding (RBAC)"
-  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/{{ item }} -n {{ system_namespace }}"
+  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/{{ item }} -n kube-system"
   with_items:
     - "efk-sa.yml"
     - "efk-clusterrolebinding.yml"
@@ -24,7 +24,7 @@
   register: es_deployment_manifest
 
 - name: "ElasticSearch | Create ES deployment"
-  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/elasticsearch-deployment.yaml -n {{ system_namespace }}"
+  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/elasticsearch-deployment.yaml -n kube-system"
   run_once: true
   when: es_deployment_manifest.changed
 
@@ -35,6 +35,6 @@
   register: es_service_manifest
 
 - name: "ElasticSearch | Create ES service"
-  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/elasticsearch-service.yaml -n {{ system_namespace }}"
+  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/elasticsearch-service.yaml -n kube-system"
   run_once: true
   when: es_service_manifest.changed
diff --git a/roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml
index a5aba61aef5500c5fbfc6486fa3171275b75a3e6..dd5b9b630f9d4c6561b6f84452e42516da591134 100644
--- a/roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml
+++ b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-clusterrolebinding.yml
@@ -3,11 +3,11 @@ kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: efk
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 subjects:
   - kind: ServiceAccount
     name: efk
-    namespace: {{ system_namespace }}
+    namespace: kube-system
 roleRef:
   kind: ClusterRole
   name: cluster-admin
diff --git a/roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml
index e79e26be87f8045a1e17a820c45bcd20a1f74596..75d75f6508c7badb071657bc007cf52cfe90db8f 100644
--- a/roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml
+++ b/roles/kubernetes-apps/efk/elasticsearch/templates/efk-sa.yml
@@ -3,6 +3,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: efk
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2 b/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2
index 6d5382e09ada726fcb317f02b293d0130a176a5e..ee2eb8b21484fc6d6885ab7967c6df0992fbe8e3 100644
--- a/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2
+++ b/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-deployment.yml.j2
@@ -4,7 +4,7 @@ apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: elasticsearch-logging-v1
-  namespace: "{{ system_namespace }}"
+  namespace: kube-system
   labels:
     k8s-app: elasticsearch-logging
     version: "{{ elasticsearch_image_tag }}"
diff --git a/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-service.yml.j2 b/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-service.yml.j2
index b7558f9d938cf01d812a9b15cfd5f8f2f329700d..789ecb215a09500001d4541bbc1c373ef8cda42c 100644
--- a/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-service.yml.j2
+++ b/roles/kubernetes-apps/efk/elasticsearch/templates/elasticsearch-service.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: Service
 metadata:
   name: elasticsearch-logging
-  namespace: "{{ system_namespace }}"
+  namespace: "kube-system"
   labels:
     k8s-app: elasticsearch-logging
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/efk/fluentd/tasks/main.yml b/roles/kubernetes-apps/efk/fluentd/tasks/main.yml
index c91bf68276e8a7af6837a719f743aa935dde8b3a..f444c79b62f7a9db4e28aa1de0d899fa8fbbd358 100644
--- a/roles/kubernetes-apps/efk/fluentd/tasks/main.yml
+++ b/roles/kubernetes-apps/efk/fluentd/tasks/main.yml
@@ -17,6 +17,6 @@
   register: fluentd_ds_manifest
 
 - name: "Fluentd | Create fluentd daemonset"
-  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/fluentd-ds.yaml -n {{ system_namespace }}"
+  command: "{{ bin_dir }}/kubectl apply -f {{ kube_config_dir }}/fluentd-ds.yaml -n kube-system"
   run_once: true
   when: fluentd_ds_manifest.changed
diff --git a/roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2 b/roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2
index 8a8ebbceca88cf0be62612e86a900d16ef3828f6..b7de44dc03340534374d2c6a0adcd1ec5c7732de 100644
--- a/roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2
+++ b/roles/kubernetes-apps/efk/fluentd/templates/fluentd-config.yml.j2
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: ConfigMap
 metadata:
   name: fluentd-config
-  namespace: "{{ system_namespace }}"
+  namespace: "kube-system"
 data:
   {{ fluentd_config_file }}: |
     # This configuration file for Fluentd / td-agent is used
diff --git a/roles/kubernetes-apps/efk/fluentd/templates/fluentd-ds.yml.j2 b/roles/kubernetes-apps/efk/fluentd/templates/fluentd-ds.yml.j2
index 960a79e89e7a1a3301c8e54ba36262f73af9ff5d..f23a8851c502cadb6e1ec1e1c174af2c41b3603b 100644
--- a/roles/kubernetes-apps/efk/fluentd/templates/fluentd-ds.yml.j2
+++ b/roles/kubernetes-apps/efk/fluentd/templates/fluentd-ds.yml.j2
@@ -4,7 +4,7 @@ apiVersion: extensions/v1beta1
 kind: DaemonSet
 metadata:
   name: "fluentd-es-v{{ fluentd_version }}"
-  namespace: "{{ system_namespace }}"
+  namespace: "kube-system"
   labels:
     k8s-app: fluentd-es
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/efk/kibana/tasks/main.yml b/roles/kubernetes-apps/efk/kibana/tasks/main.yml
index ea85682864be14591cca46f1a21dc4f7a8bbf85d..424b313b80c96830915b922100276f66a3b4c243 100644
--- a/roles/kubernetes-apps/efk/kibana/tasks/main.yml
+++ b/roles/kubernetes-apps/efk/kibana/tasks/main.yml
@@ -10,7 +10,7 @@
     filename: "{{kube_config_dir}}/kibana-deployment.yaml"
     kubectl: "{{bin_dir}}/kubectl"
     name: "kibana-logging"
-    namespace: "{{system_namespace}}"
+    namespace: "kube-system"
     resource: "deployment"
     state: "latest"
   with_items: "{{ kibana_deployment_manifest.changed }}"
@@ -27,7 +27,7 @@
     filename: "{{kube_config_dir}}/kibana-service.yaml"
     kubectl: "{{bin_dir}}/kubectl"
     name: "kibana-logging"
-    namespace: "{{system_namespace}}"
+    namespace: "kube-system"
     resource: "svc"
     state: "latest"
   with_items: "{{ kibana_service_manifest.changed }}"
diff --git a/roles/kubernetes-apps/efk/kibana/templates/kibana-deployment.yml.j2 b/roles/kubernetes-apps/efk/kibana/templates/kibana-deployment.yml.j2
index c48413bd0e8769e5b1f27a861fb08c3e8cbe9e2a..4fdf54c042112941fdee778f9cb3ebe42bcc9674 100644
--- a/roles/kubernetes-apps/efk/kibana/templates/kibana-deployment.yml.j2
+++ b/roles/kubernetes-apps/efk/kibana/templates/kibana-deployment.yml.j2
@@ -4,7 +4,7 @@ apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: kibana-logging
-  namespace: "{{ system_namespace  }}"
+  namespace: "kube-system"
   labels:
     k8s-app: kibana-logging
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/efk/kibana/templates/kibana-service.yml.j2 b/roles/kubernetes-apps/efk/kibana/templates/kibana-service.yml.j2
index 241b896f05155a661fcbfabd9220463eabf26e39..5cff3c628094e0cad46e5251a3ecb74d16536136 100644
--- a/roles/kubernetes-apps/efk/kibana/templates/kibana-service.yml.j2
+++ b/roles/kubernetes-apps/efk/kibana/templates/kibana-service.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: Service
 metadata:
   name: kibana-logging
-  namespace: "{{ system_namespace }}"
+  namespace: "kube-system"
   labels:
     k8s-app: kibana-logging
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/defaults/main.yml b/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/defaults/main.yml
index 9a3bca1ef8116808a85c93fc3ecef84a6be053fb..3b80ecbb2f023dd18977dd5d0c254fc9e00b419b 100644
--- a/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/defaults/main.yml
+++ b/roles/kubernetes-apps/external_provisioner/cephfs_provisioner/defaults/main.yml
@@ -2,7 +2,7 @@
 cephfs_provisioner_image_repo: quay.io/kubespray/cephfs-provisioner
 cephfs_provisioner_image_tag: 92295a30
 
-cephfs_provisioner_namespace: "{{ system_namespace }}"
+cephfs_provisioner_namespace: "kube-system"
 cephfs_provisioner_cluster: ceph
 cephfs_provisioner_monitors: []
 cephfs_provisioner_admin_id: admin
diff --git a/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml b/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml
index dd2e8a14744cd977f4081512c735334f35d08cda..ea5dcb079b486cb1d37f108e5b46e4b850b71594 100644
--- a/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml
+++ b/roles/kubernetes-apps/external_provisioner/local_volume_provisioner/defaults/main.yml
@@ -2,7 +2,7 @@
 local_volume_provisioner_image_repo: quay.io/external_storage/local-volume-provisioner
 local_volume_provisioner_image_tag: v2.0.0
 
-local_volume_provisioner_namespace: "{{ system_namespace }}"
+local_volume_provisioner_namespace: "kube-system"
 local_volume_provisioner_base_dir: /mnt/disks
 local_volume_provisioner_mount_dir: /mnt/disks
 local_volume_provisioner_storage_class: local-storage
diff --git a/roles/kubernetes-apps/helm/tasks/main.yml b/roles/kubernetes-apps/helm/tasks/main.yml
index 06e97aff24210f82078ab5cca7982929e70a39a9..e7b3879446fd71a22c474adc660ff1e64ea39830 100644
--- a/roles/kubernetes-apps/helm/tasks/main.yml
+++ b/roles/kubernetes-apps/helm/tasks/main.yml
@@ -18,7 +18,7 @@
 - name: Helm | Apply Helm Manifests (RBAC)
   kube:
     name: "{{item.item.name}}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{bin_dir}}/kubectl"
     resource: "{{item.item.type}}"
     filename: "{{kube_config_dir}}/{{item.item.file}}"
@@ -28,7 +28,7 @@
 
 - name: Helm | Install/upgrade helm
   command: >
-    {{ bin_dir }}/helm init --upgrade --tiller-image={{ tiller_image_repo }}:{{ tiller_image_tag }} --tiller-namespace={{ system_namespace }}
+    {{ bin_dir }}/helm init --upgrade --tiller-image={{ tiller_image_repo }}:{{ tiller_image_tag }} --tiller-namespace=kube-system
     {% if helm_skip_refresh %} --skip-refresh{% endif %}
     {% if helm_stable_repo_url is defined %} --stable-repo-url {{ helm_stable_repo_url }}{% endif %}
     {% if rbac_enabled %} --service-account=tiller{% endif %}
diff --git a/roles/kubernetes-apps/helm/templates/tiller-clusterrolebinding.yml b/roles/kubernetes-apps/helm/templates/tiller-clusterrolebinding.yml
index 0c8db4c78fe4697caf6341b3667bef8295cb92f3..00694181e25a01d0d479f551f6e207105e4494d2 100644
--- a/roles/kubernetes-apps/helm/templates/tiller-clusterrolebinding.yml
+++ b/roles/kubernetes-apps/helm/templates/tiller-clusterrolebinding.yml
@@ -3,11 +3,11 @@ kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: tiller
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 subjects:
   - kind: ServiceAccount
     name: tiller
-    namespace: {{ system_namespace }}
+    namespace: kube-system
 roleRef:
   kind: ClusterRole
   name: cluster-admin
diff --git a/roles/kubernetes-apps/helm/templates/tiller-sa.yml b/roles/kubernetes-apps/helm/templates/tiller-sa.yml
index 26e575fb6a338703903eb09aaa772f55554df4c9..606dbb1471598d0c1333238564c183900793cdd4 100644
--- a/roles/kubernetes-apps/helm/templates/tiller-sa.yml
+++ b/roles/kubernetes-apps/helm/templates/tiller-sa.yml
@@ -3,6 +3,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: tiller
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/README.md b/roles/kubernetes-apps/ingress_controller/cert_manager/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b0f008676a1c63fcc0a3da7dab4937b9e202d4fa
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/README.md
@@ -0,0 +1,17 @@
+Deployment files
+================
+
+This directory contains example deployment manifests for cert-manager that can
+be used in place of the official Helm chart.
+
+This is useful if you are deploying cert-manager into an environment without
+Helm, or want to inspect a 'bare minimum' deployment.
+
+Where do these come from?
+-------------------------
+
+The manifests in these subdirectories are generated from the Helm chart
+automatically. The `values.yaml` files used to configure cert-manager can be
+found in [`hack/deploy`](../../hack/deploy/).
+
+They are automatically generated by running `./hack/update-deploy-gen.sh`.
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/defaults/main.yml b/roles/kubernetes-apps/ingress_controller/cert_manager/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bc6bceb151eac7fa7ec872129decceec3e6a5cfc
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+cert_manager_namespace: "cert-manager"
+cert_manager_cpu_requests: 10m
+cert_manager_cpu_limits: 30m
+cert_manager_memory_requests: 32Mi
+cert_manager_memory_limits: 200Mi
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml b/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..eeb29da2d441a5af4a63520e4e54eb093936ce3e
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/tasks/main.yml
@@ -0,0 +1,38 @@
+---
+
+- name: Cert Manager | Create addon dir
+  file:
+    path: "{{ kube_config_dir }}/addons/cert_manager"
+    state: directory
+    owner: root
+    group: root
+    mode: 0755
+
+- name: Cert Manager | Create manifests
+  template:
+    src: "{{ item.file }}.j2"
+    dest: "{{ kube_config_dir }}/addons/cert_manager/{{ item.file }}"
+  with_items:
+    - { name: cert-manager-ns, file: cert-manager-ns.yml, type: ns }
+    - { name: cert-manager-sa, file: cert-manager-sa.yml, type: sa }
+    - { name: cert-manager-clusterrole, file: cert-manager-clusterrole.yml, type: clusterrole }
+    - { name: cert-manager-clusterrolebinding, file: cert-manager-clusterrolebinding.yml, type: clusterrolebinding }
+    - { name: cert-manager-issuer-crd, file: cert-manager-issuer-crd.yml, type: crd }
+    - { name: cert-manager-clusterissuer-crd, file: cert-manager-clusterissuer-crd.yml, type: crd }
+    - { name: cert-manager-certificate-crd, file: cert-manager-certificate-crd.yml, type: crd }
+    - { name: cert-manager-deploy, file: cert-manager-deploy.yml, type: deploy }
+  register: cert_manager_manifests
+  when:
+    - inventory_hostname == groups['kube-master'][0]
+
+- name: Cert Manager | Apply manifests
+  kube:
+    name: "{{ item.item.name }}"
+    namespace: "{{ cert_manager_namespace }}"
+    kubectl: "{{ bin_dir }}/kubectl"
+    resource: "{{ item.item.type }}"
+    filename: "{{ kube_config_dir }}/addons/cert_manager/{{ item.item.file }}"
+    state: "latest"
+  with_items: "{{ cert_manager_manifests.results }}"
+  when:
+    - inventory_hostname == groups['kube-master'][0]
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-certificate-crd.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-certificate-crd.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..48d0c5b49ea947e6673da6261dcaad4be950a1b7
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-certificate-crd.yml.j2
@@ -0,0 +1,21 @@
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: certificates.certmanager.k8s.io
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  group: certmanager.k8s.io
+  version: v1alpha1
+  scope: Namespaced
+  names:
+    kind: Certificate
+    plural: certificates
+    shortNames:
+      - cert
+      - certs
+      
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterissuer-crd.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterissuer-crd.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..86601e098d1f3f68f4d0559cf8dc5867738926c0
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterissuer-crd.yml.j2
@@ -0,0 +1,17 @@
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: clusterissuers.certmanager.k8s.io
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  group: certmanager.k8s.io
+  version: v1alpha1
+  names:
+    kind: ClusterIssuer
+    plural: clusterissuers
+  scope: Cluster
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrole.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrole.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..9d36de5cb123f678c2956358ccabd138a2aacc25
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrole.yml.j2
@@ -0,0 +1,25 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+  name: cert-manager
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+rules:
+  - apiGroups: ["certmanager.k8s.io"]
+    resources: ["certificates", "issuers", "clusterissuers"]
+    verbs: ["*"]
+  - apiGroups: [""]
+    # TODO: remove endpoints once 0.4 is released. We include it here in case
+    # users use the 'master' version of the Helm chart with a 0.2.x release of
+    # cert-manager that still performs leader election with Endpoint resources.
+    # We advise users don't do this, but some will anyway and this will reduce
+    # friction.
+    resources: ["endpoints", "configmaps", "secrets", "events", "services", "pods"]
+    verbs: ["*"]
+  - apiGroups: ["extensions"]
+    resources: ["ingresses"]
+    verbs: ["*"]
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrolebinding.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrolebinding.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..d0e481c6cc8aa4e2b386f11d20bbd2a8a76d0ea5
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-clusterrolebinding.yml.j2
@@ -0,0 +1,18 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  name: cert-manager
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cert-manager
+subjects:
+  - name: cert-manager
+    namespace: {{ cert_manager_namespace }}
+    kind: ServiceAccount
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-deploy.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-deploy.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..ef66bef0523d395e81ef3811b8913f959a3f9ce3
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-deploy.yml.j2
@@ -0,0 +1,51 @@
+---
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+  name: cert-manager
+  namespace: {{ cert_manager_namespace }}
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        k8s-app: cert-manager
+        release: cert-manager
+      annotations:
+    spec:
+      serviceAccountName: cert-manager
+      containers:
+        - name: cert-manager
+          image: {{ cert_manager_controller_image_repo }}:{{ cert_manager_controller_image_tag }}
+          imagePullPolicy: {{ k8s_image_pull_policy }}
+          args:
+            - --cluster-resource-namespace=$(POD_NAMESPACE)
+          env:
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          resources:
+            requests:
+              cpu: {{ cert_manager_cpu_requests }}
+              memory: {{ cert_manager_memory_requests }}
+            limits:
+              cpu: {{ cert_manager_cpu_limits }}
+              memory: {{ cert_manager_memory_limits }}
+            
+        - name: ingress-shim
+          image: {{ cert_manager_ingress_shim_image_repo }}:{{ cert_manager_ingress_shim_image_tag }}
+          imagePullPolicy: {{ k8s_image_pull_policy }}
+          resources:
+            requests:
+              cpu: {{ cert_manager_cpu_requests }}
+              memory: {{ cert_manager_memory_requests }}
+            limits:
+              cpu: {{ cert_manager_cpu_limits }}
+              memory: {{ cert_manager_memory_limits }}
+            
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-issuer-crd.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-issuer-crd.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..7e344d9f9a666f043f6a6cb3f3e3a89f5670446c
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-issuer-crd.yml.j2
@@ -0,0 +1,17 @@
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: issuers.certmanager.k8s.io
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
+spec:
+  group: certmanager.k8s.io
+  version: v1alpha1
+  names:
+    kind: Issuer
+    plural: issuers
+  scope: Namespaced
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-ns.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-ns.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..7cf3a282dc113c6b615406b050116b91df9f1db5
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-ns.yml.j2
@@ -0,0 +1,7 @@
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: {{ cert_manager_namespace }}
+  labels:
+    name: {{ cert_manager_namespace }}
diff --git a/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-sa.yml.j2 b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-sa.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..ccdd5f430c118fa7b37d3f923aa324bb77a92781
--- /dev/null
+++ b/roles/kubernetes-apps/ingress_controller/cert_manager/templates/cert-manager-sa.yml.j2
@@ -0,0 +1,11 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: cert-manager
+  namespace: {{ cert_manager_namespace }}
+  labels:
+    app: cert-manager
+    chart: cert-manager-0.2.5
+    release: cert-manager
+    heritage: Tiller
diff --git a/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ingress-nginx-controller-ds.yml.j2 b/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ingress-nginx-controller-ds.yml.j2
index b88bb9d6fa8cf5e242ebd3b92a833d0e577451bb..e65a440b04ec3322f9cd34a035478707def72822 100644
--- a/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ingress-nginx-controller-ds.yml.j2
+++ b/roles/kubernetes-apps/ingress_controller/ingress_nginx/templates/ingress-nginx-controller-ds.yml.j2
@@ -20,6 +20,9 @@ spec:
       labels:
         k8s-app: ingress-nginx
         version: v{{ ingress_nginx_controller_image_tag }}
+      annotations:
+        prometheus.io/port: '10254'
+        prometheus.io/scrape: 'true'
     spec:
 {% if ingress_nginx_host_network %}
       hostNetwork: true
@@ -78,3 +81,4 @@ spec:
 {% if rbac_enabled %}
       serviceAccountName: ingress-nginx
 {% endif %}
+
diff --git a/roles/kubernetes-apps/ingress_controller/meta/main.yml b/roles/kubernetes-apps/ingress_controller/meta/main.yml
index da2e03ecc0d30630cfb7b32c1806991891c9261e..617e9d9a7ccecc4e26d36025f11dc090dc41b7d8 100644
--- a/roles/kubernetes-apps/ingress_controller/meta/main.yml
+++ b/roles/kubernetes-apps/ingress_controller/meta/main.yml
@@ -6,3 +6,10 @@ dependencies:
       - apps
       - ingress-nginx
       - ingress-controller
+
+  - role: kubernetes-apps/ingress_controller/cert_manager
+    when: cert_manager_enabled
+    tags:
+      - apps
+      - cert-manager
+      - ingress-controller
diff --git a/roles/kubernetes-apps/network_plugin/calico/tasks/main.yml b/roles/kubernetes-apps/network_plugin/calico/tasks/main.yml
index f17e45c7abd7d16fb8a7f1f77e25de4b0965324e..4c8295c1e37038b3b0d234b3bff2c3c468c15c75 100644
--- a/roles/kubernetes-apps/network_plugin/calico/tasks/main.yml
+++ b/roles/kubernetes-apps/network_plugin/calico/tasks/main.yml
@@ -2,7 +2,7 @@
 - name: Start Calico resources
   kube:
     name: "{{item.item.name}}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{bin_dir}}/kubectl"
     resource: "{{item.item.type}}"
     filename: "{{kube_config_dir}}/{{item.item.file}}"
diff --git a/roles/kubernetes-apps/network_plugin/canal/tasks/main.yml b/roles/kubernetes-apps/network_plugin/canal/tasks/main.yml
index cbe4f0ac7e1103fc07f6ffb3a52906f2cf60ed99..3640fe762eec1aa9385d89993ce8608825e2802f 100644
--- a/roles/kubernetes-apps/network_plugin/canal/tasks/main.yml
+++ b/roles/kubernetes-apps/network_plugin/canal/tasks/main.yml
@@ -2,7 +2,7 @@
 - name: Canal | Start Resources
   kube:
     name: "{{item.item.name}}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{bin_dir}}/kubectl"
     resource: "{{item.item.type}}"
     filename: "{{kube_config_dir}}/{{item.item.file}}"
diff --git a/roles/kubernetes-apps/network_plugin/cilium/tasks/main.yml b/roles/kubernetes-apps/network_plugin/cilium/tasks/main.yml
index 2359fe2d496689a61e6c9da6e82d783637d7d41a..5d90bdb018257a0fbf43933701903bb174c174ad 100755
--- a/roles/kubernetes-apps/network_plugin/cilium/tasks/main.yml
+++ b/roles/kubernetes-apps/network_plugin/cilium/tasks/main.yml
@@ -2,7 +2,7 @@
 - name: Cilium | Start Resources
   kube:
     name: "{{item.item.name}}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{bin_dir}}/kubectl"
     resource: "{{item.item.type}}"
     filename: "{{kube_config_dir}}/{{item.item.file}}"
@@ -11,7 +11,7 @@
   when: inventory_hostname == groups['kube-master'][0] and not item|skipped
 
 - name: Cilium | Wait for pods to run
-  command: "{{bin_dir}}/kubectl -n {{system_namespace}} get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.status.containerStatuses[0].ready==false)].metadata.name}'"
+  command: "{{bin_dir}}/kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.status.containerStatuses[0].ready==false)].metadata.name}'"
   register: pods_not_ready
   until: pods_not_ready.stdout.find("cilium")==-1
   retries: 30
diff --git a/roles/kubernetes-apps/network_plugin/contiv/tasks/main.yml b/roles/kubernetes-apps/network_plugin/contiv/tasks/main.yml
index 330acc1cd0464d698819c7bedf2ea8de29a59bb4..5289296dc65104d528d6625aba235e2d3f99d345 100644
--- a/roles/kubernetes-apps/network_plugin/contiv/tasks/main.yml
+++ b/roles/kubernetes-apps/network_plugin/contiv/tasks/main.yml
@@ -3,7 +3,7 @@
 - name: Contiv | Create Kubernetes resources
   kube:
     name: "{{ item.item.name }}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{ bin_dir }}/kubectl"
     resource: "{{ item.item.type }}"
     filename: "{{ contiv_config_dir }}/{{ item.item.file }}"
diff --git a/roles/kubernetes-apps/network_plugin/flannel/tasks/main.yml b/roles/kubernetes-apps/network_plugin/flannel/tasks/main.yml
index 09603a79430e04d2e904419673f70c9d25c43255..bdf954bf99d673bb628a8db1d562e82ed265882b 100644
--- a/roles/kubernetes-apps/network_plugin/flannel/tasks/main.yml
+++ b/roles/kubernetes-apps/network_plugin/flannel/tasks/main.yml
@@ -2,7 +2,7 @@
 - name: Flannel | Start Resources
   kube:
     name: "{{item.item.name}}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{bin_dir}}/kubectl"
     resource: "{{item.item.type}}"
     filename: "{{kube_config_dir}}/{{item.item.file}}"
diff --git a/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml b/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml
index 66d900d55e028fb881e2a23d69a0581b10fbf095..53ad953b53a2a7f371964171a0662010c88e70bd 100644
--- a/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml
+++ b/roles/kubernetes-apps/network_plugin/weave/tasks/main.yml
@@ -5,7 +5,7 @@
     kubectl: "{{ bin_dir }}/kubectl"
     filename: "{{ kube_config_dir }}/weave-net.yml"
     resource: "ds"
-    namespace: "{{system_namespace}}"
+    namespace: "kube-system"
     state: "latest"
   when: inventory_hostname == groups['kube-master'][0]
 
diff --git a/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml b/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml
index ba11627992c13ac62ee3ed061eff6f5bbc0e3432..62e929f413d7b2ec28619d9d1f3cb02171708a0d 100644
--- a/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml
+++ b/roles/kubernetes-apps/policy_controller/calico/tasks/main.yml
@@ -12,7 +12,7 @@
     name: calico-policy-controller
     kubectl: "{{bin_dir}}/kubectl"
     resource: rs
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     state: absent
   run_once: true
 
@@ -32,7 +32,7 @@
 - name: Start of Calico kube controllers
   kube:
     name: "{{item.item.name}}"
-    namespace: "{{ system_namespace }}"
+    namespace: "kube-system"
     kubectl: "{{bin_dir}}/kubectl"
     resource: "{{item.item.type}}"
     filename: "{{kube_config_dir}}/{{item.item.file}}"
diff --git a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2 b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2
index 7e1311b9286cd1f3f3b2200e7ed474017e4e3991..d7083e3e6b30f6b38d2668d43381f4e326bf7bd7 100644
--- a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2
+++ b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-controllers.yml.j2
@@ -2,7 +2,7 @@ apiVersion: apps/v1beta2
 kind: Deployment
 metadata:
   name: calico-kube-controllers
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: calico-kube-controllers
     kubernetes.io/cluster-service: "true"
@@ -15,7 +15,7 @@ spec:
   template:
     metadata:
       name: calico-kube-controllers
-      namespace: {{ system_namespace }}
+      namespace: kube-system
       labels:
         kubernetes.io/cluster-service: "true"
         k8s-app: calico-kube-controllers
diff --git a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-cr.yml.j2 b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-cr.yml.j2
index 82c2f3e44a978e78872ccfb84679d47285b5353b..d05e986a4c52033b4f821776dd22c2f40d2a3cc5 100644
--- a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-cr.yml.j2
+++ b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-cr.yml.j2
@@ -3,7 +3,7 @@ kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: calico-kube-controllers
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 rules:
   - apiGroups:
     - ""
diff --git a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-crb.yml.j2 b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-crb.yml.j2
index 38853a413575446c583a6609b00e433af0bb42b1..2e51184811e4f177da80366344dccb62dce0f786 100644
--- a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-crb.yml.j2
+++ b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-crb.yml.j2
@@ -10,4 +10,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: calico-kube-controllers
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-sa.yml.j2 b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-sa.yml.j2
index bf8958976d859a2b67ba021954dcb95300900be1..e42e89d1894628f9cd5931c2b721038d1f938b57 100644
--- a/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-sa.yml.j2
+++ b/roles/kubernetes-apps/policy_controller/calico/templates/calico-kube-sa.yml.j2
@@ -3,6 +3,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: calico-kube-controllers
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/kubernetes-apps/registry/defaults/main.yml b/roles/kubernetes-apps/registry/defaults/main.yml
index 93d1cfa2ae9ef3561ca6878a317baf40cf10ba52..a626435d51d169feec8b674f599dc680a49b1693 100644
--- a/roles/kubernetes-apps/registry/defaults/main.yml
+++ b/roles/kubernetes-apps/registry/defaults/main.yml
@@ -4,6 +4,6 @@ registry_image_tag: 2.6
 registry_proxy_image_repo: gcr.io/google_containers/kube-registry-proxy
 registry_proxy_image_tag: 0.4
 
-registry_namespace: "{{ system_namespace }}"
+registry_namespace: "kube-system"
 registry_storage_class: ""
 registry_disk_size: "10Gi"
diff --git a/roles/kubernetes-apps/rotate_tokens/tasks/main.yml b/roles/kubernetes-apps/rotate_tokens/tasks/main.yml
index 52101ae16c1284fd5f2882484045c4bce945eddf..3884a3a65336c0f22cf33f73e8d5392ee14ca1d8 100644
--- a/roles/kubernetes-apps/rotate_tokens/tasks/main.yml
+++ b/roles/kubernetes-apps/rotate_tokens/tasks/main.yml
@@ -44,5 +44,5 @@
   when: needs_rotation
 
 - name: Rotate Tokens | Delete pods in system namespace
-  command: "{{ bin_dir }}/kubectl delete pods -n {{ system_namespace }} --all"
+  command: "{{ bin_dir }}/kubectl delete pods -n kube-system --all"
   when: needs_rotation
diff --git a/roles/kubernetes/master/defaults/main.yml b/roles/kubernetes/master/defaults/main.yml
index 303c1a88a366bd74810d39746c274229d109d152..6325bb31cedcdc7b4ddb194d3f72893426c822fe 100644
--- a/roles/kubernetes/master/defaults/main.yml
+++ b/roles/kubernetes/master/defaults/main.yml
@@ -96,4 +96,5 @@ volume_cross_zone_attachment: false
 ## Encrypting Secret Data at Rest
 kube_encrypt_secret_data: false
 kube_encrypt_token: "{{ lookup('password', inventory_dir + '/credentials/kube_encrypt_token.creds length=32 chars=ascii_letters,digits') }}"
-kube_encryption_algorithm: "aescbc" # Must be either: aescbc, secretbox or aesgcm
+# Must be either: aescbc, secretbox or aesgcm
+kube_encryption_algorithm: "aescbc"
diff --git a/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml b/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml
index a9f9383185e29461f26e5b3a049a5570d4e45881..58eaaa66f7bf469b52aa873d96a7e815ea1e8ce6 100644
--- a/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml
+++ b/roles/kubernetes/master/tasks/kubeadm-migrate-certs.yml
@@ -9,4 +9,6 @@
     - {src: apiserver-key.pem, dest: apiserver.key}
     - {src: ca.pem, dest: ca.crt}
     - {src: ca-key.pem, dest: ca.key}
+    - {src: service-account-key.pem, dest: sa.pub}
+    - {src: service-account-key.pem, dest: sa.key}
   register: kubeadm_copy_old_certs
diff --git a/roles/kubernetes/master/tasks/pre-upgrade.yml b/roles/kubernetes/master/tasks/pre-upgrade.yml
index 3a9fe64174ab48d93792960c63a40df1d5409561..56e57b015d98eb1270d536c20d430889bf21f15d 100644
--- a/roles/kubernetes/master/tasks/pre-upgrade.yml
+++ b/roles/kubernetes/master/tasks/pre-upgrade.yml
@@ -30,4 +30,7 @@
   with_items:
     - ["kube-apiserver", "kube-controller-manager", "kube-scheduler"]
   when: kube_apiserver_manifest_replaced.changed
-  run_once: true
+  register: remove_master_container
+  retries: 4
+  until: remove_master_container.rc == 0
+  delay: 5
\ No newline at end of file
diff --git a/roles/kubernetes/master/templates/kubeadm-config.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
index 844421d329db4851da2b69f20c1baea84ad1c544..0eccb4918545bbc21c2f07b9a8e82f1c6052264b 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
@@ -38,7 +38,7 @@ apiServerExtraArgs:
   apiserver-count: "{{ kube_apiserver_count }}"
 {% if kube_version | version_compare('v1.9', '>=') %}
   endpoint-reconciler-type: lease
-{% endif %}  
+{% endif %}
   service-node-port-range: {{ kube_apiserver_node_port_range }}
   kubelet-preferred-address-types: "{{ kubelet_preferred_address_types }}"
 {% if kube_basic_auth|default(true) %}
@@ -90,3 +90,6 @@ apiServerCertSANs:
 {% endfor %}
 certificatesDir: {{ kube_config_dir }}/ssl
 unifiedControlPlaneImage: "{{ hyperkube_image_repo }}:{{ hyperkube_image_tag }}"
+{% if kube_override_hostname|default('') %}
+nodeName: {{ kube_override_hostname }}
+{% endif %}
diff --git a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
index 350a27a180723f724eefa09ec97f629870472e46..687ca415d3e21337e74d8e0007b0e0ef46777dec 100644
--- a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
+++ b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: Pod
 metadata:
   name: kube-apiserver
-  namespace: {{system_namespace}}
+  namespace: kube-system
   labels:
     k8s-app: kube-apiserver
     kubespray: v2
@@ -63,7 +63,7 @@ spec:
 {% if kube_token_auth|default(true) %}
     - --token-auth-file={{ kube_token_dir }}/known_tokens.csv
 {% endif %}
-    - --service-account-key-file={{ kube_cert_dir }}/apiserver-key.pem
+    - --service-account-key-file={{ kube_cert_dir }}/service-account-key.pem
 {% if kube_oidc_auth|default(false) and kube_oidc_url is defined and kube_oidc_client_id is defined %}
     - --oidc-issuer-url={{ kube_oidc_url }}
     - --oidc-client-id={{ kube_oidc_client_id }}
diff --git a/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2
index 2b4282a2e3b3927bf48553826cde1961dd1eb7e8..0123724967e3a4bc62d7e3078df3a6f37a45ebd1 100644
--- a/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2
+++ b/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: Pod
 metadata:
   name: kube-controller-manager
-  namespace: {{system_namespace}}
+  namespace: kube-system
   labels:
     k8s-app: kube-controller-manager
   annotations:
@@ -29,7 +29,7 @@ spec:
     - controller-manager
     - --kubeconfig={{ kube_config_dir }}/kube-controller-manager-kubeconfig.yaml
     - --leader-elect=true
-    - --service-account-private-key-file={{ kube_cert_dir }}/apiserver-key.pem
+    - --service-account-private-key-file={{ kube_cert_dir }}/service-account-key.pem
     - --root-ca-file={{ kube_cert_dir }}/ca.pem
     - --cluster-signing-cert-file={{ kube_cert_dir }}/ca.pem
     - --cluster-signing-key-file={{ kube_cert_dir }}/ca-key.pem
diff --git a/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2
index b13fc7fa32d259e7747817c38a768d5295f966bf..a4023365e885342c16cb3a1855082192edf70511 100644
--- a/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2
+++ b/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: Pod
 metadata:
   name: kube-scheduler
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: kube-scheduler
   annotations:
diff --git a/roles/kubernetes/master/vars/main.yml b/roles/kubernetes/master/vars/main.yml
deleted file mode 100644
index a5eba4f2beb8e2ffd29feb1d06b0564fe438dd3f..0000000000000000000000000000000000000000
--- a/roles/kubernetes/master/vars/main.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-namespace_kubesystem:
-  apiVersion: v1
-  kind: Namespace
-  metadata:
-    name: "{{system_namespace}}"
diff --git a/roles/kubernetes/node/tasks/main.yml b/roles/kubernetes/node/tasks/main.yml
index 4d5fa5df541ef98ed4e1bd507b04242f510ad8df..78e6d92d616b8f9c7b5895578c528bfcf9c6d849 100644
--- a/roles/kubernetes/node/tasks/main.yml
+++ b/roles/kubernetes/node/tasks/main.yml
@@ -134,6 +134,19 @@
   tags:
     - kube-proxy
 
+- name: Write cloud-config
+  template:
+    src: "{{ cloud_provider }}-cloud-config.j2"
+    dest: "{{ kube_config_dir }}/cloud_config"
+    group: "{{ kube_cert_group }}"
+    mode: 0640
+  when:
+    - cloud_provider is defined
+    - cloud_provider in [ 'openstack', 'azure', 'vsphere' ]
+  notify: restart kubelet
+  tags:
+    - cloud-provider
+
 # reload-systemd
 - meta: flush_handlers
 
diff --git a/roles/kubernetes/node/templates/kubelet.standard.env.j2 b/roles/kubernetes/node/templates/kubelet.standard.env.j2
index 08fe1644be8a37ba19ff42e75991bbe1ecda824c..cd48fca9ce7c6a22111f58110159ebdc08495fc9 100644
--- a/roles/kubernetes/node/templates/kubelet.standard.env.j2
+++ b/roles/kubernetes/node/templates/kubelet.standard.env.j2
@@ -81,18 +81,26 @@ KUBELET_HOSTNAME="--hostname-override={{ kube_override_hostname }}"
 {% endif %}
 
 {# Kubelet node labels #}
+{% set role_node_labels = [] %}
 {% if inventory_hostname in groups['kube-master'] %}
-{%   set node_labels %}--node-labels=node-role.kubernetes.io/master=true{% endset %}
+{%   do role_node_labels.append('node-role.kubernetes.io/master=true') %}
 {%   if not standalone_kubelet|bool %}
-{%     set node_labels %}{{ node_labels }},node-role.kubernetes.io/node=true{% endset %}
+{%     do role_node_labels.append('node-role.kubernetes.io/node=true') %}
 {%   endif %}
 {% elif inventory_hostname in groups['kube-ingress']|default([]) %}
-{%   set node_labels %}--node-labels=node-role.kubernetes.io/ingress=true{% endset %}
+{%   do role_node_labels.append('node-role.kubernetes.io/ingress=true') %}
 {% else %}
-{%   set node_labels %}--node-labels=node-role.kubernetes.io/node=true{% endset %}
+{%   do role_node_labels.append('node-role.kubernetes.io/node=true') %}
 {% endif %}
+{% set inventory_node_labels = [] %}
+{% if node_labels is defined %}
+{% for labelname, labelvalue in node_labels.iteritems() %}
+{% do inventory_node_labels.append(labelname + '=' + labelvalue) %}
+{% endfor %}
+{% endif %}
+{% set all_node_labels = role_node_labels + inventory_node_labels %}
 
-KUBELET_ARGS="{{ kubelet_args_base }} {{ kubelet_args_dns }} {{ kubelet_args_kubeconfig }} {{ kube_reserved }} {{ node_labels }} {% if kube_feature_gates %} --feature-gates={{ kube_feature_gates|join(',') }} {% endif %} {% if kubelet_custom_flags is string %} {{kubelet_custom_flags}} {% else %}{% for flag in kubelet_custom_flags %} {{flag}} {% endfor %}{% endif %}"
+KUBELET_ARGS="{{ kubelet_args_base }} {{ kubelet_args_dns }} {{ kubelet_args_kubeconfig }} {{ kube_reserved }} --node-labels={{ all_node_labels | join(',') }} {% if kube_feature_gates %} --feature-gates={{ kube_feature_gates|join(',') }} {% endif %} {% if kubelet_custom_flags is string %} {{kubelet_custom_flags}} {% else %}{% for flag in kubelet_custom_flags %} {{flag}} {% endfor %}{% endif %}"
 {% if kube_network_plugin is defined and kube_network_plugin in ["calico", "canal", "flannel", "weave", "contiv", "cilium"] %}
 KUBELET_NETWORK_PLUGIN="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
 {% elif kube_network_plugin is defined and kube_network_plugin == "weave" %}
diff --git a/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2 b/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
index 7c8e0062d220dc85f654b1e5390920e64203aa82..18e51069f104725167cb14d3ab70779a749b3229 100644
--- a/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
+++ b/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: Pod
 metadata:
   name: kube-proxy
-  namespace: {{system_namespace}}
+  namespace: kube-system
   labels:
     k8s-app: kube-proxy
   annotations:
@@ -48,7 +48,6 @@ spec:
 {% elif kube_proxy_mode == 'ipvs' %}
     - --masquerade-all
     - --feature-gates=SupportIPVSProxyMode=true
-    - --proxy-mode=ipvs
     - --ipvs-min-sync-period=5s
     - --ipvs-sync-period=5s
     - --ipvs-scheduler=rr
diff --git a/roles/kubernetes/node/templates/manifests/nginx-proxy.manifest.j2 b/roles/kubernetes/node/templates/manifests/nginx-proxy.manifest.j2
index 2d566cad10ad144eb06d08333260c02d6ef544b6..a1e9a78156ade8abafc085be0d1ab9967d6aaedb 100644
--- a/roles/kubernetes/node/templates/manifests/nginx-proxy.manifest.j2
+++ b/roles/kubernetes/node/templates/manifests/nginx-proxy.manifest.j2
@@ -2,7 +2,7 @@ apiVersion: v1
 kind: Pod
 metadata:
   name: nginx-proxy
-  namespace: {{system_namespace}}
+  namespace: kube-system
   labels:
     k8s-app: kube-nginx
 spec:
diff --git a/roles/kubernetes/preinstall/tasks/main.yml b/roles/kubernetes/preinstall/tasks/main.yml
index f230407511676fa7c5d943b33c09b565b169655e..aca0c960653dcc50186c8b85166e54d95a344cb3 100644
--- a/roles/kubernetes/preinstall/tasks/main.yml
+++ b/roles/kubernetes/preinstall/tasks/main.yml
@@ -256,19 +256,6 @@
   tags:
     - bootstrap-os
 
-- name: Write cloud-config
-  template:
-    src: "{{ cloud_provider }}-cloud-config.j2"
-    dest: "{{ kube_config_dir }}/cloud_config"
-    group: "{{ kube_cert_group }}"
-    mode: 0640
-  when:
-    - inventory_hostname in groups['k8s-cluster']
-    - cloud_provider is defined
-    - cloud_provider in [ 'openstack', 'azure', 'vsphere' ]
-  tags:
-    - cloud-provider
-
 - import_tasks: etchosts.yml
   tags:
     - bootstrap-os
diff --git a/roles/kubernetes/secrets/files/make-ssl.sh b/roles/kubernetes/secrets/files/make-ssl.sh
index 724c6f36949c63a731b13a169e74410eddead4c7..1c34fc69dba0b67e46c1686acb6a3e9a52653e99 100755
--- a/roles/kubernetes/secrets/files/make-ssl.sh
+++ b/roles/kubernetes/secrets/files/make-ssl.sh
@@ -82,6 +82,17 @@ gen_key_and_cert() {
 
 # Admins
 if [ -n "$MASTERS" ]; then
+
+    # service-account
+    # If --service-account-private-key-file was previously configured to use apiserver-key.pem then copy that to the new dedicated service-account signing key location to avoid disruptions
+    if [ -e "$SSLDIR/apiserver-key.pem" ] && ! [ -e "$SSLDIR/service-account-key.pem" ]; then
+       cp $SSLDIR/apiserver-key.pem $SSLDIR/service-account-key.pem
+    fi
+    # Generate dedicated service account signing key if one doesn't exist
+    if ! [ -e "$SSLDIR/apiserver-key.pem" ] && ! [ -e "$SSLDIR/service-account-key.pem" ]; then
+        openssl genrsa -out service-account-key.pem 2048 > /dev/null 2>&1
+    fi
+
     # kube-apiserver
     # Generate only if we don't have existing ca and apiserver certs
     if ! [ -e "$SSLDIR/ca-key.pem" ] || ! [ -e "$SSLDIR/apiserver-key.pem" ]; then
diff --git a/roles/kubernetes/secrets/tasks/check-certs.yml b/roles/kubernetes/secrets/tasks/check-certs.yml
index 6278897710c8814cac0a30ef3d931c1ded673491..4780b14d63e5f37540b5192453477b6430969395 100644
--- a/roles/kubernetes/secrets/tasks/check-certs.yml
+++ b/roles/kubernetes/secrets/tasks/check-certs.yml
@@ -105,9 +105,9 @@
       {%- set certs = {'sync': False} -%}
       {% if gen_node_certs[inventory_hostname] or
         (not kubecert_node.results[0].stat.exists|default(False)) or
-          (not kubecert_node.results[10].stat.exists|default(False)) or
-            (not kubecert_node.results[7].stat.exists|default(False)) or
-              (kubecert_node.results[10].stat.checksum|default('') != kubecert_master.files|selectattr("path", "equalto", kubecert_node.results[10].stat.path)|map(attribute="checksum")|first|default('')) -%}
+          (not kubecert_node.results[12].stat.exists|default(False)) or
+            (not kubecert_node.results[8].stat.exists|default(False)) or
+              (kubecert_node.results[12].stat.checksum|default('') != kubecert_master.files|selectattr("path", "equalto", kubecert_node.results[12].stat.path)|map(attribute="checksum")|first|default('')) -%}
                 {%- set _ = certs.update({'sync': True}) -%}
       {% endif %}
       {{ certs.sync }}
diff --git a/roles/kubernetes/secrets/tasks/gen_certs_script.yml b/roles/kubernetes/secrets/tasks/gen_certs_script.yml
index 011575358012198183355a7872d44dd08605d1cb..c39f606ad43f85ea29d7c4c0d7d016891412d378 100644
--- a/roles/kubernetes/secrets/tasks/gen_certs_script.yml
+++ b/roles/kubernetes/secrets/tasks/gen_certs_script.yml
@@ -75,6 +75,7 @@
                        'kube-controller-manager-key.pem',
                        'front-proxy-client.pem',
                        'front-proxy-client-key.pem',
+                       'service-account-key.pem',
                        {% for node in groups['kube-master'] %}
                        'admin-{{ node }}.pem',
                        'admin-{{ node }}-key.pem',
@@ -86,6 +87,7 @@
                       'apiserver-key.pem',
                       'front-proxy-client.pem',
                       'front-proxy-client-key.pem',
+                      'service-account-key.pem',
                       'kube-scheduler.pem',
                       'kube-scheduler-key.pem',
                       'kube-controller-manager.pem',
diff --git a/roles/kubernetes/secrets/templates/openssl.conf.j2 b/roles/kubernetes/secrets/templates/openssl.conf.j2
index adc875ba6bf9b540627c8ec7edecfaefd513a229..38902aeef20f25c13dd4d23b3cc7cca5e78c38c8 100644
--- a/roles/kubernetes/secrets/templates/openssl.conf.j2
+++ b/roles/kubernetes/secrets/templates/openssl.conf.j2
@@ -1,4 +1,4 @@
-[req]
+{% set counter = {'dns': 6,'ip': 1,} %}{% macro increment(dct, key, inc=1)%}{% if dct.update({key: dct[key] + inc}) %} {% endif %}{% endmacro %}[req]
 req_extensions = v3_req
 distinguished_name = req_distinguished_name
 [req_distinguished_name]
@@ -13,31 +13,30 @@ DNS.3 = kubernetes.default.svc
 DNS.4 = kubernetes.default.svc.{{ dns_domain }}
 DNS.5 = localhost
 {% for host in groups['kube-master'] %}
-DNS.{{ 5 + loop.index }} = {{ host }}
+DNS.{{ counter["dns"] }} = {{ host }}{{ increment(counter, 'dns') }}
 {% endfor %}
-{% set idns = groups['kube-master'] | length | int + 5 %}
-{% if loadbalancer_apiserver is defined  %}
-{% set idns = idns + 1 %}
-DNS.{{ idns | string }} = {{ apiserver_loadbalancer_domain_name }}
+{% if apiserver_loadbalancer_domain_name is defined  %}
+DNS.{{ counter["dns"] }} = {{ apiserver_loadbalancer_domain_name }}{{ increment(counter, 'dns') }}
 {% endif %}
 {% for host in groups['kube-master'] %}
-IP.{{ 2 * loop.index - 1 }} = {{ hostvars[host]['access_ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}
-IP.{{ 2 * loop.index }} = {{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}
+{% if hostvars[host]['access_ip'] is defined  %}
+IP.{{ counter["ip"] }} = {{ hostvars[host]['access_ip'] }}{{ increment(counter, 'ip') }}
+{% endif %}
+IP.{{ counter["ip"] }} = {{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}{{ increment(counter, 'ip') }}
 {% endfor %}
-{% set idx =  groups['kube-master'] | length | int * 2 + 1 %}
-IP.{{ idx }} = {{ kube_apiserver_ip }}
-{% if loadbalancer_apiserver is defined  %}
-IP.{{ idx + 1 }} = {{ loadbalancer_apiserver.address }}
-{% set idx = idx + 1 %}
+{% if kube_apiserver_ip is defined  %}
+IP.{{ counter["ip"] }} = {{ kube_apiserver_ip }}{{ increment(counter, 'ip') }}
+{% endif %}
+{% if loadbalancer_apiserver is defined and loadbalancer_apiserver.address is defined  %}
+IP.{{ counter["ip"] }} = {{ loadbalancer_apiserver.address }}{{ increment(counter, 'ip') }}
 {% endif %}
-IP.{{ idx + 1 }} = 127.0.0.1
 {% if supplementary_addresses_in_ssl_keys is defined %}
-{% set is = idx + 1 %}
 {% for addr in supplementary_addresses_in_ssl_keys %}
 {% if addr | ipaddr %}
-IP.{{ is + loop.index }} = {{ addr }}
+IP.{{ counter["ip"] }} = {{ addr }}{{ increment(counter, 'ip') }}
 {% else %}
-DNS.{{ idns + loop.index }} = {{ addr }}
+DNS.{{ counter["dns"] }} = {{ addr }}{{ increment(counter, 'dns') }}
 {% endif %}
 {% endfor %}
 {% endif %}
+IP.{{ counter["ip"] }} = 127.0.0.1
diff --git a/roles/kubespray-defaults/defaults/main.yaml b/roles/kubespray-defaults/defaults/main.yaml
index 4828de6af137fe5ba6994516115c8722dd03e399..d6217d654e6011d458fc5b7c29547397672a461a 100644
--- a/roles/kubespray-defaults/defaults/main.yaml
+++ b/roles/kubespray-defaults/defaults/main.yaml
@@ -61,7 +61,6 @@ dns_domain: "{{ cluster_name }}"
 kube_config_dir: /etc/kubernetes
 kube_script_dir: "{{ bin_dir }}/kubernetes-scripts"
 kube_manifest_dir: "{{ kube_config_dir }}/manifests"
-system_namespace: kube-system
 
 # This is where all the cert scripts and certs will be located
 kube_cert_dir: "{{ kube_config_dir }}/ssl"
@@ -175,6 +174,7 @@ local_volume_provisioner_enabled: "{{ local_volumes_enabled | default('false') }
 persistent_volumes_enabled: false
 cephfs_provisioner_enabled: false
 ingress_nginx_enabled: false
+cert_manager_enabled: false
 
 ## When OpenStack is used, Cinder version can be explicitly specified if autodetection fails (Fixed in 1.9: https://github.com/kubernetes/kubernetes/issues/50461)
 # openstack_blockstorage_version: "v1/v2/auto (default)"
@@ -241,6 +241,7 @@ weave_peers: uninitialized
 
 ## Set no_proxy to all assigned cluster IPs and hostnames
 no_proxy: >-
+  {%- if http_proxy is defined or https_proxy is defined %}
   {%- if loadbalancer_apiserver is defined -%}
   {{ apiserver_loadbalancer_domain_name| default('') }},
   {{ loadbalancer_apiserver.address | default('') }},
@@ -254,11 +255,12 @@ no_proxy: >-
   {{ item }},{{ item }}.{{ dns_domain }},
   {%- endfor -%}
   127.0.0.1,localhost
+  {%- endif %}
 
 proxy_env:
   http_proxy: "{{ http_proxy| default ('') }}"
   https_proxy: "{{ https_proxy| default ('') }}"
-  no_proxy: "{{ no_proxy }}"
+  no_proxy: "{{ no_proxy| default ('') }}"
 
 # Vars for pointing to kubernetes api endpoints
 is_kube_master: "{{ inventory_hostname in groups['kube-master'] }}"
diff --git a/roles/network_plugin/calico/defaults/main.yml b/roles/network_plugin/calico/defaults/main.yml
index 1b0cd0421dfba443cd953848222dd3355d326181..857ebd11aac4400a67ecc5110d067933969ff915 100644
--- a/roles/network_plugin/calico/defaults/main.yml
+++ b/roles/network_plugin/calico/defaults/main.yml
@@ -50,4 +50,4 @@ rbac_resources:
 # * can-reach=DESTINATION
 # * interface=INTERFACE-REGEX
 # see https://docs.projectcalico.org/v3.0/reference/node/configuration#ip-autodetection-methods
-#calico_ip_auto_method: "interface=eth.*"
+# calico_ip_auto_method: "interface=eth.*"
diff --git a/roles/network_plugin/calico/templates/calico-config.yml.j2 b/roles/network_plugin/calico/templates/calico-config.yml.j2
index 92d2f1f0a8192c060048a6506f4b2a79753ca62e..3be65deaa49d35d36f7f7d1c1db396b9bc0642a9 100644
--- a/roles/network_plugin/calico/templates/calico-config.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-config.yml.j2
@@ -2,7 +2,7 @@ kind: ConfigMap
 apiVersion: v1
 metadata:
   name: calico-config
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 data:
   etcd_endpoints: "{{ etcd_access_addresses }}"
   etcd_ca: "/calico-secrets/ca_cert.crt"
diff --git a/roles/network_plugin/calico/templates/calico-cr.yml.j2 b/roles/network_plugin/calico/templates/calico-cr.yml.j2
index 47d6266593b90798a77ce87c7278845a150e83da..cef8331f39dbf6fd2e2d4a5794a63f64bc0d0108 100644
--- a/roles/network_plugin/calico/templates/calico-cr.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-cr.yml.j2
@@ -3,7 +3,7 @@ kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: calico-node
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 rules:
   - apiGroups: [""]
     resources:
diff --git a/roles/network_plugin/calico/templates/calico-crb.yml.j2 b/roles/network_plugin/calico/templates/calico-crb.yml.j2
index 2e132a0dc527da745256b41fbb8a715890336451..1b4e8fe00972f721daf44cf4c699ae373095ec00 100644
--- a/roles/network_plugin/calico/templates/calico-crb.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-crb.yml.j2
@@ -10,4 +10,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: calico-node
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/network_plugin/calico/templates/calico-node-sa.yml.j2 b/roles/network_plugin/calico/templates/calico-node-sa.yml.j2
index 5cce29793786552350911e8550f160ae0fad302e..68b1c286f9ba7ce445418db05a390251d69ff022 100644
--- a/roles/network_plugin/calico/templates/calico-node-sa.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-node-sa.yml.j2
@@ -3,6 +3,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: calico-node
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/network_plugin/calico/templates/calico-node.yml.j2 b/roles/network_plugin/calico/templates/calico-node.yml.j2
index 6ec3cd20b655128c0064a796e4b82157f2675da4..849ea0afb94094b2ae9d0574d7875ca8c882e81d 100644
--- a/roles/network_plugin/calico/templates/calico-node.yml.j2
+++ b/roles/network_plugin/calico/templates/calico-node.yml.j2
@@ -6,7 +6,7 @@ kind: DaemonSet
 apiVersion: extensions/v1beta1
 metadata:
   name: calico-node
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: calico-node
 spec:
diff --git a/roles/network_plugin/canal/templates/canal-cr-calico.yml.j2 b/roles/network_plugin/canal/templates/canal-cr-calico.yml.j2
index e3b048c640fe682e9d549db22ef82a2d5669fc0c..2e92b7b2b9cb2db3e5137acea8fa7f0e0ae2b100 100644
--- a/roles/network_plugin/canal/templates/canal-cr-calico.yml.j2
+++ b/roles/network_plugin/canal/templates/canal-cr-calico.yml.j2
@@ -3,7 +3,7 @@ kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: calico
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 rules:
   - apiGroups: [""]
     resources:
diff --git a/roles/network_plugin/canal/templates/canal-crb-calico.yml.j2 b/roles/network_plugin/canal/templates/canal-crb-calico.yml.j2
index e1c1f5050a5d871ee43de2aa36b51615c325c906..016e5193e2398e1405e48318e1b73964ff1b893e 100644
--- a/roles/network_plugin/canal/templates/canal-crb-calico.yml.j2
+++ b/roles/network_plugin/canal/templates/canal-crb-calico.yml.j2
@@ -11,4 +11,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: canal
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/network_plugin/canal/templates/canal-crb-flannel.yml.j2 b/roles/network_plugin/canal/templates/canal-crb-flannel.yml.j2
index 3b00017b13e02b48f6b89c42f38311d4c46b2383..097b1538e4c5c75ff4d7b297b412ee1dc0d1774b 100644
--- a/roles/network_plugin/canal/templates/canal-crb-flannel.yml.j2
+++ b/roles/network_plugin/canal/templates/canal-crb-flannel.yml.j2
@@ -11,4 +11,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: canal
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/network_plugin/canal/templates/canal-node-sa.yml.j2 b/roles/network_plugin/canal/templates/canal-node-sa.yml.j2
index d5b9a6e971ae3b055d8289f19cef25e5c828acb8..aa168d15c14d43d493493fe23109c5f859cd45d3 100644
--- a/roles/network_plugin/canal/templates/canal-node-sa.yml.j2
+++ b/roles/network_plugin/canal/templates/canal-node-sa.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: canal
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
 
diff --git a/roles/network_plugin/canal/templates/canal-node.yaml.j2 b/roles/network_plugin/canal/templates/canal-node.yaml.j2
index d63bf99b0b5a3663c8868377d498e0fb7f8a8a9b..8535360a101b68010658b72b2beba9e42181763a 100644
--- a/roles/network_plugin/canal/templates/canal-node.yaml.j2
+++ b/roles/network_plugin/canal/templates/canal-node.yaml.j2
@@ -3,7 +3,7 @@ kind: DaemonSet
 apiVersion: extensions/v1beta1
 metadata:
   name: canal-node
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: canal-node
 spec:
diff --git a/roles/network_plugin/cilium/templates/cilium-config.yml.j2 b/roles/network_plugin/cilium/templates/cilium-config.yml.j2
index a96bb8531388c0c1fa6a25a3b5e6320dcbd101b1..c5051e2cae12fada3b9d602a6764f5f77d934a04 100755
--- a/roles/network_plugin/cilium/templates/cilium-config.yml.j2
+++ b/roles/network_plugin/cilium/templates/cilium-config.yml.j2
@@ -2,7 +2,7 @@ kind: ConfigMap
 apiVersion: v1
 metadata:
   name: cilium-config
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 data:
   # This etcd-config contains the etcd endpoints of your cluster. If you use
   # TLS please make sure you uncomment the ca-file line and add the respective
diff --git a/roles/network_plugin/cilium/templates/cilium-crb.yml.j2 b/roles/network_plugin/cilium/templates/cilium-crb.yml.j2
index dcfe4d47122dbbbe69b41969607da4d3a8acdedf..04d603d57a7289ed874ff7fbf127ff68035b1bb2 100755
--- a/roles/network_plugin/cilium/templates/cilium-crb.yml.j2
+++ b/roles/network_plugin/cilium/templates/cilium-crb.yml.j2
@@ -10,6 +10,6 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: cilium
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 - kind: Group
   name: system:nodes
diff --git a/roles/network_plugin/cilium/templates/cilium-ds.yml.j2 b/roles/network_plugin/cilium/templates/cilium-ds.yml.j2
index 3d877a5cbf2df63bf4ec131b16620b2f23ba3401..8eaa24f3212bf6044e43cb263767d75de4df4631 100755
--- a/roles/network_plugin/cilium/templates/cilium-ds.yml.j2
+++ b/roles/network_plugin/cilium/templates/cilium-ds.yml.j2
@@ -3,7 +3,7 @@ apiVersion: extensions/v1beta1
 kind: DaemonSet
 metadata:
   name: cilium
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 spec:
   template:
     metadata:
diff --git a/roles/network_plugin/cilium/templates/cilium-sa.yml.j2 b/roles/network_plugin/cilium/templates/cilium-sa.yml.j2
index d6ef2a4314d57101153b246160cb1b5bdea63f12..c03ac59b49b43b99a9ed99ae8fbd4953404d3c3f 100755
--- a/roles/network_plugin/cilium/templates/cilium-sa.yml.j2
+++ b/roles/network_plugin/cilium/templates/cilium-sa.yml.j2
@@ -3,4 +3,4 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: cilium
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/network_plugin/contiv/templates/contiv-api-proxy.yml.j2 b/roles/network_plugin/contiv/templates/contiv-api-proxy.yml.j2
index 140379b13f4aa2647151703cc64dbae18848eb42..3ccaffaf89538a84a3ec5e5e8e26103f07c91333 100644
--- a/roles/network_plugin/contiv/templates/contiv-api-proxy.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-api-proxy.yml.j2
@@ -3,7 +3,7 @@ apiVersion: extensions/v1beta1
 kind: DaemonSet
 metadata:
   name: contiv-api-proxy
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: contiv-api-proxy
 spec:
@@ -12,7 +12,7 @@ spec:
   template:
     metadata:
       name: contiv-api-proxy
-      namespace: {{ system_namespace }}
+      namespace: kube-system
       labels:
         k8s-app: contiv-api-proxy
       annotations:
diff --git a/roles/network_plugin/contiv/templates/contiv-config.yml.j2 b/roles/network_plugin/contiv/templates/contiv-config.yml.j2
index 0505cd1f1e9533bd9205148e6d2c27cc35bd0711..249d9d88ebbcbfb9478f9b0739fa80c8246ebd27 100644
--- a/roles/network_plugin/contiv/templates/contiv-config.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-config.yml.j2
@@ -5,7 +5,7 @@ kind: ConfigMap
 apiVersion: v1
 metadata:
   name: contiv-config
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 data:
   # The location of your cluster store. This is set to the
   # avdertise-client value below from the contiv-etcd service.
diff --git a/roles/network_plugin/contiv/templates/contiv-etcd-proxy.yml.j2 b/roles/network_plugin/contiv/templates/contiv-etcd-proxy.yml.j2
index a9690cc2fa29cd83a66d5a13a10b679a6e3209a2..75946d82191729ac0a27d14c2407eb1fbe8b1e16 100644
--- a/roles/network_plugin/contiv/templates/contiv-etcd-proxy.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-etcd-proxy.yml.j2
@@ -3,7 +3,7 @@ kind: DaemonSet
 apiVersion: extensions/v1beta1
 metadata:
   name: contiv-etcd-proxy
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: contiv-etcd-proxy
 spec:
diff --git a/roles/network_plugin/contiv/templates/contiv-etcd.yml.j2 b/roles/network_plugin/contiv/templates/contiv-etcd.yml.j2
index 8060f4c01e678aaa6734301546fd8612b87f6888..a6e9121d4ff11f122a7fb37917feaba1aed78e25 100644
--- a/roles/network_plugin/contiv/templates/contiv-etcd.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-etcd.yml.j2
@@ -3,7 +3,7 @@ kind: DaemonSet
 apiVersion: extensions/v1beta1
 metadata:
   name: contiv-etcd
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: contiv-etcd
 spec:
diff --git a/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrole.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrole.yml.j2
index 82ca00437532f6f2565ff5048724e55ee54568b1..6ccd4f9b49479985c31796d731aff975a8ee7ab9 100644
--- a/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrole.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrole.yml.j2
@@ -2,7 +2,7 @@ kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: contiv-netmaster
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 rules:
   - apiGroups:
     - ""
diff --git a/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrolebinding.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrolebinding.yml.j2
index 74c5e3145beddbd94af988ba4c8b8d5583a58cf5..73d636775a10811e1ba0a1a0ceb04d9cb4cfab36 100644
--- a/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrolebinding.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netmaster-clusterrolebinding.yml.j2
@@ -9,4 +9,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: contiv-netmaster
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/network_plugin/contiv/templates/contiv-netmaster-serviceaccount.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netmaster-serviceaccount.yml.j2
index 0c1bfb3e58f206f904122530a5cf1afd0e91424b..758ea449336307555a5cf3cb7e7bdca4f62e2a46 100644
--- a/roles/network_plugin/contiv/templates/contiv-netmaster-serviceaccount.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netmaster-serviceaccount.yml.j2
@@ -2,6 +2,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: contiv-netmaster
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/network_plugin/contiv/templates/contiv-netmaster.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netmaster.yml.j2
index 56be2d93d6a6fcb58a7bf59c2c07c29eb8086a24..d41259ec16b94fdb5bd3f592137b50bfe56cbf08 100644
--- a/roles/network_plugin/contiv/templates/contiv-netmaster.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netmaster.yml.j2
@@ -3,7 +3,7 @@ kind: DaemonSet
 apiVersion: extensions/v1beta1
 metadata:
   name: contiv-netmaster
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: contiv-netmaster
 spec:
@@ -12,7 +12,7 @@ spec:
   template:
     metadata:
       name: contiv-netmaster
-      namespace: {{ system_namespace }}
+      namespace: kube-system
       labels:
         k8s-app: contiv-netmaster
       annotations:
diff --git a/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrole.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrole.yml.j2
index c26e094edb36380cde23d1925ad884359d58f9c7..af4c6e584829459402a44f3e44b71855d5568380 100644
--- a/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrole.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrole.yml.j2
@@ -2,7 +2,7 @@ kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1beta1
 metadata:
   name: contiv-netplugin
-  namespace: {{ system_namespace }}
+  namespace: kube-system
 rules:
   - apiGroups:
     - ""
diff --git a/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrolebinding.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrolebinding.yml.j2
index 0c989008a6548a06ecb885b7c3a4bc44f95a7762..6cac217fc744e88a2f0958754118e1c6ad29577f 100644
--- a/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrolebinding.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netplugin-clusterrolebinding.yml.j2
@@ -9,4 +9,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: contiv-netplugin
-  namespace: {{ system_namespace }}
+  namespace: kube-system
diff --git a/roles/network_plugin/contiv/templates/contiv-netplugin-serviceaccount.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netplugin-serviceaccount.yml.j2
index edfac8bb34a716bbaab20f9e52868444c5e2cc66..8d00ec8cb43f4d2cbba1a6eefbf7658cc04ff283 100644
--- a/roles/network_plugin/contiv/templates/contiv-netplugin-serviceaccount.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netplugin-serviceaccount.yml.j2
@@ -2,6 +2,6 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: contiv-netplugin
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     kubernetes.io/cluster-service: "true"
diff --git a/roles/network_plugin/contiv/templates/contiv-netplugin.yml.j2 b/roles/network_plugin/contiv/templates/contiv-netplugin.yml.j2
index 9c2c0a036ad5fbcaf359f3419a7873dbcfe6a33e..2a7bf71cbb164786b56ebbb558e66c3c78154ea5 100644
--- a/roles/network_plugin/contiv/templates/contiv-netplugin.yml.j2
+++ b/roles/network_plugin/contiv/templates/contiv-netplugin.yml.j2
@@ -5,7 +5,7 @@ kind: DaemonSet
 apiVersion: extensions/v1beta1
 metadata:
   name: contiv-netplugin
-  namespace: {{ system_namespace }}
+  namespace: kube-system
   labels:
     k8s-app: contiv-netplugin
 spec:
diff --git a/roles/network_plugin/flannel/templates/cni-flannel-rbac.yml.j2 b/roles/network_plugin/flannel/templates/cni-flannel-rbac.yml.j2
index aafe2a0f525a28ff8a94755444efe7830cde9813..6f5c9a2114c76c116ad074ac7718ef02241973b9 100644
--- a/roles/network_plugin/flannel/templates/cni-flannel-rbac.yml.j2
+++ b/roles/network_plugin/flannel/templates/cni-flannel-rbac.yml.j2
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: flannel
-  namespace: "{{system_namespace}}"
+  namespace: "kube-system"
 ---
 kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1beta1
@@ -41,4 +41,4 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: flannel
-  namespace: "{{system_namespace}}"
\ No newline at end of file
+  namespace: "kube-system"
\ No newline at end of file
diff --git a/roles/network_plugin/flannel/templates/cni-flannel.yml.j2 b/roles/network_plugin/flannel/templates/cni-flannel.yml.j2
index bb2a6a7f8758df0195152ab2c0361c1446a16bc3..7ecb21ad06848de6e06949c20547845fbd505768 100644
--- a/roles/network_plugin/flannel/templates/cni-flannel.yml.j2
+++ b/roles/network_plugin/flannel/templates/cni-flannel.yml.j2
@@ -3,7 +3,7 @@ kind: ConfigMap
 apiVersion: v1
 metadata:
   name: kube-flannel-cfg
-  namespace: "{{system_namespace}}"
+  namespace: "kube-system"
   labels:
     tier: node
     app: flannel
@@ -41,7 +41,7 @@ apiVersion: extensions/v1beta1
 kind: DaemonSet
 metadata:
   name: kube-flannel
-  namespace: "{{system_namespace}}"
+  namespace: "kube-system"
   labels:
     tier: node
     k8s-app: flannel
diff --git a/roles/network_plugin/weave/templates/weave-net.yml.j2 b/roles/network_plugin/weave/templates/weave-net.yml.j2
index 699ba3128410e862438fea419e68cad9cd2e6c17..9a7da7377e58cabfa9be3334b2d6e7bf12416224 100644
--- a/roles/network_plugin/weave/templates/weave-net.yml.j2
+++ b/roles/network_plugin/weave/templates/weave-net.yml.j2
@@ -8,14 +8,14 @@ items:
       name: weave-net
       labels:
         name: weave-net
-      namespace: {{ system_namespace }}
+      namespace: kube-system
   - apiVersion: rbac.authorization.k8s.io/v1beta1
     kind: ClusterRole
     metadata:
       name: weave-net
       labels:
         name: weave-net
-      namespace: {{ system_namespace }}
+      namespace: kube-system
     rules:
       - apiGroups:
           - ''
@@ -41,7 +41,7 @@ items:
       name: weave-net
       labels:
         name: weave-net
-      namespace: {{ system_namespace }}
+      namespace: kube-system
     roleRef:
       kind: ClusterRole
       name: weave-net
@@ -49,14 +49,14 @@ items:
     subjects:
       - kind: ServiceAccount
         name: weave-net
-        namespace: {{ system_namespace }}
+        namespace: kube-system
   - apiVersion: rbac.authorization.k8s.io/v1beta1
     kind: Role
     metadata:
       name: weave-net
       labels:
         name: weave-net
-      namespace: {{ system_namespace }}
+      namespace: kube-system
     rules:
       - apiGroups:
           - ''
@@ -79,7 +79,7 @@ items:
       name: weave-net
       labels:
         name: weave-net
-      namespace: {{ system_namespace }}
+      namespace: kube-system
     roleRef:
       kind: Role
       name: weave-net
@@ -87,7 +87,7 @@ items:
     subjects:
       - kind: ServiceAccount
         name: weave-net
-        namespace: {{ system_namespace }}
+        namespace: kube-system
   - apiVersion: extensions/v1beta1
     kind: DaemonSet
     metadata:
@@ -95,7 +95,7 @@ items:
       labels:
         name: weave-net
         version: v{{ weave_version }}
-      namespace: {{ system_namespace }}
+      namespace: kube-system
     spec:
       minReadySeconds: 5
       template:
diff --git a/roles/vault/defaults/main.yml b/roles/vault/defaults/main.yml
index 9a3e830354937c06bd32667924f1c2a2e26373e4..8e5ad08a08371de29bd6c7b07d517e86dc628ce5 100644
--- a/roles/vault/defaults/main.yml
+++ b/roles/vault/defaults/main.yml
@@ -86,7 +86,7 @@ vault_ca_options:
     format: pem
     ttl: "{{ vault_max_lease_ttl }}"
     exclude_cn_from_sans: true
-    alt_names: "vault.{{ system_namespace }}.svc.{{ dns_domain }},vault.{{ system_namespace }}.svc,vault.{{ system_namespace }},vault"
+    alt_names: "vault.kube-system.svc.{{ dns_domain }},vault.kube-system.svc,vault.kube-system,vault"
   etcd:
     common_name: etcd
     format: pem
diff --git a/roles/vault/tasks/cluster/systemd.yml b/roles/vault/tasks/cluster/systemd.yml
index 8df52f98255ed0863c1d226ff79eb7b8e463b904..f7139d336bc1159057e6e05b2e7168362f0c42ef 100644
--- a/roles/vault/tasks/cluster/systemd.yml
+++ b/roles/vault/tasks/cluster/systemd.yml
@@ -55,3 +55,4 @@
   register: vault_health_check
   until: vault_health_check|succeeded
   retries: 10
+  delay: "{{ retry_stagger | random + 3 }}"
diff --git a/tests/ansible.cfg b/tests/ansible.cfg
index 9e734403e518ae0b2ed894ea949e17448840cbe5..9c405752924b602cdce2ac921925948b4f7a68d2 100644
--- a/tests/ansible.cfg
+++ b/tests/ansible.cfg
@@ -10,3 +10,4 @@ fact_caching_connection = /tmp
 stdout_callback = skippy
 library = ./library:../library
 callback_whitelist = profile_tasks
+jinja2_extensions = jinja2.ext.do
diff --git a/tests/files/gce_centos7-flannel-addons.yml b/tests/files/gce_centos7-flannel-addons.yml
index 467bee2d0122511ff3ff34d84298040c226c91e7..c120920116551570ca024e345b3aa010ae540f6e 100644
--- a/tests/files/gce_centos7-flannel-addons.yml
+++ b/tests/files/gce_centos7-flannel-addons.yml
@@ -18,3 +18,5 @@ cloud_provider: gce
 kube_encrypt_secret_data: true
 prometheus_operator_enabled: true
 k8s_metrics_enabled: true
+ingress_nginx_enabled: true
+cert_manager_enabled: true