diff --git a/README.md b/README.md
index baa87f90b4c75dd0474c1342c8cc647164f319c9..6709c67b3220b0e608aa537708fb29ce4b60d954 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,6 @@
 - **Continuous integration tests**
 
 For an easy way to use it, check out [**kargo-cli**](https://github.com/kubespray/kargo-cli) </br>
-A complete **documentation** can be found [THERE](https://docs.kubespray.io)
+A complete **documentation** can be found [**here**](https://docs.kubespray.io)
 
 [![Build Status](https://travis-ci.org/kubespray/kargo.svg)](https://travis-ci.org/kubespray/kargo)
diff --git a/roles/kubernetes/secrets/tasks/check-certs.yml b/roles/kubernetes/secrets/tasks/check-certs.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a5ed1af67f0702291b6adc1d3ca12e695ec26547
--- /dev/null
+++ b/roles/kubernetes/secrets/tasks/check-certs.yml
@@ -0,0 +1,36 @@
+---
+- name: "Check certs | check if the certs have already been generated on first master"
+  stat:
+    path: "{{ kube_cert_dir }}/ca.pem"
+  delegate_to: groups['kube-master'][0]
+  register: kubecert_master
+  run_once: true
+
+- name: "Check_certs | Set default value for 'sync_certs' and 'gen_certs' to false"
+  set_fact:
+    sync_certs: false
+    gen_certs: false
+
+- name: "Check_certs | Set 'sync_certs' and 'gen_certs' to true"
+  set_fact:
+    gen_certs: true
+  when: not kubecert_master.stat.exists
+  run_once: true
+
+- name: "Check certs | check if a cert already exists"
+  stat:
+    path: "{{ kube_cert_dir }}/ca.pem"
+  register: kubecert 
+
+- name: "Check_certs | Set 'sync_certs' to true"
+  set_fact:
+    sync_certs: true
+  when: >-
+      {%- set certs = {'sync': False} -%}
+      {%- for server in play_hosts
+         if (not hostvars[server].kubecert.stat.exists) or
+         (hostvars[server].kubecert.stat.checksum != kubecert_master.stat.checksum|default('')) -%}
+         {%- set _ = certs.update({'sync': True}) -%}
+      {%- endfor -%}
+      {{ certs.sync }}
+  run_once: true
diff --git a/roles/kubernetes/secrets/tasks/gen_certs.yml b/roles/kubernetes/secrets/tasks/gen_certs.yml
index 8f5629dd63b5ac8a0b1b57c905ccd61093b77501..138ec868834e14e186383347f840d147d3e85479 100644
--- a/roles/kubernetes/secrets/tasks/gen_certs.yml
+++ b/roles/kubernetes/secrets/tasks/gen_certs.yml
@@ -3,6 +3,7 @@
   become: False
   local_action: template src="openssl.conf.j2" dest="{{ role_path }}/files/openssl.conf"
   run_once: yes
+  when: gen_certs|default(false)
 
 - name: certs | run cert generation script
   become: False
@@ -11,28 +12,47 @@
     -f {{ role_path }}/files/openssl.conf
     -d {{ role_path }}/files/certs/
   run_once: yes
+  when: gen_certs|default(false)
+  notify: set secret_changed
 
-- name: certs | Copy certs on nodes
+- set_fact:
+    master_certs: ['ca-key.pem', 'admin.pem', 'admin-key.pem', 'apiserver-key.pem', 'apiserver.pem']
+    node_certs: ['ca.pem', 'node.pem', 'node-key.pem']
+
+- name: certs | Copy certs on first master
   copy:
     src: "certs/{{ item }}"
     dest: "{{ kube_cert_dir }}"
-  with_items:
-    - ca.pem
-    - node.pem
-    - node-key.pem
-  when: inventory_hostname in "{{ groups['k8s-cluster'] }}"
+  with_items: '{{ master_certs + node_certs }}'
+  when: inventory_hostname == "{{ groups['kube-master'][0] }}" and gen_certs|default(false)
 
-- name: certs | Copy certs on master
+- name: certs | Get the certs from first master
+  slurp:
+    src: "{{ kube_cert_dir }}/{{ item }}"
+  delegate_to: "{{groups['kube-master'][0]}}"
+  register: slurp_certs
+  with_items: '{{ master_certs + node_certs }}'
+  when: sync_certs|default(false)
+  run_once: true
+  notify: set secret_changed
+
+- name: certs | Copy certs on masters
   copy:
-    src: "certs/{{ item }}"
-    dest: "{{ kube_cert_dir }}"
-  with_items:
-    - ca-key.pem
-    - admin.pem
-    - admin-key.pem
-    - apiserver-key.pem
-    - apiserver.pem
-  when: inventory_hostname in "{{ groups['kube-master'] }}"
+    content: "{{ item.content|b64decode }}"
+    dest: "{{ item.source }}"
+  with_items: '{{slurp_certs.results}}'
+  when: item.item in master_certs and
+        inventory_hostname in groups['kube-master'] and sync_certs|default(false) and
+        inventory_hostname != groups['kube-master'][0]
+
+- name: certs | Copy certs on nodes
+  copy:
+    content: "{{ item.content|b64decode }}"
+    dest: "{{ item.source }}"
+  with_items: '{{slurp_certs.results}}'
+  when: item.item in node_certs and
+        inventory_hostname in groups['kube-node'] and sync_certs|default(false) and
+        inventory_hostname != groups['kube-master'][0]
 
 - name: certs | check certificate permissions
   file:
@@ -43,6 +63,7 @@
 
 - shell: ls {{ kube_cert_dir}}/*key.pem
   register: keyfiles
+  changed_when: false
 
 - name: certs | set permissions on keys
   file:
diff --git a/roles/kubernetes/secrets/tasks/main.yml b/roles/kubernetes/secrets/tasks/main.yml
index a2f039cf020eb4d3f2fd302271c37c61fcf3dbe6..027e95a823c79376505bd872d86b1d076405e9a5 100644
--- a/roles/kubernetes/secrets/tasks/main.yml
+++ b/roles/kubernetes/secrets/tasks/main.yml
@@ -1,4 +1,6 @@
 ---
+- include: check-certs.yml
+
 - name: Make sure the certificate directory exits
   file:
     path={{ kube_cert_dir }}
@@ -30,12 +32,6 @@
   when: inventory_hostname in "{{ groups['kube-master'] }}"
   notify: set secret_changed
 
-- name: Check if a certificate already exists
-  stat:
-    path: "{{ kube_cert_dir }}/ca.pem"
-  register: kubecert
-
 - include: gen_certs.yml
-  when: not kubecert.stat.exists
 
 - include: gen_tokens.yml