diff --git a/roles/etcd/tasks/main.yml b/roles/etcd/tasks/main.yml
index 6d8388ee873337313432500651ee7f78d5fc4e5f..a210169411f97c99bc8188fe0176df521aee6ebf 100644
--- a/roles/etcd/tasks/main.yml
+++ b/roles/etcd/tasks/main.yml
@@ -13,6 +13,11 @@
 - include: upd_ca_trust.yml
   tags: etcd-secrets
 
+- name: "Gen_certs | Get etcd certificate serials"
+  shell: "openssl x509 -in {{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem -noout -serial | cut -d= -f2"
+  register: "node-{{ inventory_hostname }}_serial"
+  when: inventory_hostname in groups['k8s-cluster']|union(groups['etcd'])|union(groups['calico-rr']|default([]))|unique|sort
+
 - include: "install_{{ etcd_deployment_type }}.yml"
   when: is_etcd_master
   tags: upgrade
diff --git a/roles/etcd/tasks/pre_upgrade.yml b/roles/etcd/tasks/pre_upgrade.yml
index e86a0d947dbe230cb3199c88f5b9165bdd86363b..c08aee6212f1becc024b0dac2d2a9f2962bfe1b3 100644
--- a/roles/etcd/tasks/pre_upgrade.yml
+++ b/roles/etcd/tasks/pre_upgrade.yml
@@ -34,7 +34,7 @@
 
 - name: "Pre-upgrade | remove etcd-proxy if it exists"
   command: "{{ docker_bin_dir }}/docker rm -f {{item}}"
-  with_items: "{{etcd_proxy_container.stdout_lines}}"
+  with_items: "{{etcd_proxy_container.stdout_lines|default()}}"
 
 - name: "Pre-upgrade | see if etcdctl is installed"
   stat:
diff --git a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
index 1032ba482fd07370779be63c469afe6284398f53..f5dec558918cfd12f75094a3891514ac5019d316 100644
--- a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
+++ b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
@@ -6,6 +6,9 @@ metadata:
   labels:
     k8s-app: kube-apiserver
     kubespray: v2
+  annotations:
+    kubespray.etcd-cert/serial: "{{ etcd_node_cert_serial }}"
+    kubespray.apiserver-cert/serial: "{{ apiserver_cert_serial }}"
 spec:
   hostNetwork: true
 {% if kube_version | version_compare('v1.6', '>=')  %}
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 8d08dfeb61459f60397be18783e90c3fc3a91ed0..e0ef08fe487b873b74e931a016501bc3bf9a08ec 100644
--- a/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2
+++ b/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2
@@ -5,6 +5,9 @@ metadata:
   namespace: {{system_namespace}}
   labels:
     k8s-app: kube-controller
+  annotations:
+    kubespray.etcd-cert/serial: "{{ etcd_node_cert_serial }}"
+    kubespray.controller-manager-cert/serial: "{{ controller_manager_cert_serial }}"
 spec:
   hostNetwork: true
 {% if kube_version | version_compare('v1.6', '>=') %}
diff --git a/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2
index e9422d4a15e3d9e04e3673c386332f653d3e06cd..6353ca102b3ab7c95a70f3821136d72061f86cc2 100644
--- a/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2
+++ b/roles/kubernetes/master/templates/manifests/kube-scheduler.manifest.j2
@@ -5,6 +5,8 @@ metadata:
   namespace: {{ system_namespace }}
   labels:
     k8s-app: kube-scheduler
+  annotations:
+    kubespray.scheduler-cert/serial: "{{ scheduler_cert_serial }}"
 spec:
   hostNetwork: true
 {% if kube_version | version_compare('v1.6', '>=') %}
diff --git a/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2 b/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
index 65feeee65c73fe8d7de7f384db70889872cccb51..daf0fcb4f825d56958fbc36cd8016c4820a62fb7 100644
--- a/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
+++ b/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
@@ -5,6 +5,8 @@ metadata:
   namespace: {{system_namespace}}
   labels:
     k8s-app: kube-proxy
+  annotations:
+    kubespray.kube-proxy-cert/serial: "{{ kube_proxy_cert_serial }}"
 spec:
   hostNetwork: true
 {% if kube_version | version_compare('v1.6', '>=') %}
diff --git a/roles/kubernetes/secrets/tasks/main.yml b/roles/kubernetes/secrets/tasks/main.yml
index d2ce2283d537c0fa94e7d707eb95e43e6c012191..2a15591df1466fe719a32dfd962461720a8adaa6 100644
--- a/roles/kubernetes/secrets/tasks/main.yml
+++ b/roles/kubernetes/secrets/tasks/main.yml
@@ -75,5 +75,37 @@
 - include: upd_ca_trust.yml
   tags: k8s-secrets
 
+- name: "Gen_certs | Get certificate serials on kube masters"
+  shell: "openssl x509 -in {{ kube_cert_dir }}/{{ item }} -noout -serial | cut -d= -f2"
+  register: "master_certificate_serials"
+  with_items:
+    - "admin-{{ inventory_hostname }}.pem"
+    - "apiserver.pem"
+    - "kube-controller-manager.pem"
+    - "kube-scheduler.pem"
+  when: inventory_hostname in groups['kube-master']
+
+- name: "Gen_certs | set kube master certificate serial facts"
+  set_fact:
+    etcd_admin_cert_serial: "{{ master_certificate_serials.results[0].stdout|default() }}"
+    apiserver_cert_serial: "{{ master_certificate_serials.results[1].stdout|default() }}"
+    controller_manager_cert_serial: "{{ master_certificate_serials.results[2].stdout|default() }}"
+    scheduler_cert_serial: "{{ master_certificate_serials.results[3].stdout|default() }}"
+  when: inventory_hostname in groups['kube-master']
+
+- name: "Gen_certs | Get certificate serials on kube nodes"
+  shell: "openssl x509 -in {{ kube_cert_dir }}/{{ item }} -noout -serial | cut -d= -f2"
+  register: "node_certificate_serials"
+  with_items:
+    - "node-{{ inventory_hostname }}.pem"
+    - "kube-proxy-{{ inventory_hostname }}.pem"
+  when: inventory_hostname in groups['k8s-cluster']
+
+- name: "Gen_certs | set kube node certificate serial facts"
+  set_fact:
+    etcd_node_cert_serial: "{{ node_certificate_serials.results[0].stdout|default() }}"
+    kube_proxy_cert_serial: "{{ node_certificate_serials.results[1].stdout|default() }}"
+  when: inventory_hostname in groups['k8s-cluster']
+
 - include: gen_tokens.yml
   tags: k8s-secrets
diff --git a/roles/vault/tasks/shared/issue_cert.yml b/roles/vault/tasks/shared/issue_cert.yml
index d3dbbd9e8f54bed5f312cab9db848d2ca253f773..fa09bfd2b236062ba36f0b0b2c2a30d9a89c8299 100644
--- a/roles/vault/tasks/shared/issue_cert.yml
+++ b/roles/vault/tasks/shared/issue_cert.yml
@@ -66,3 +66,11 @@
     mode: "{{ issue_cert_file_mode | d('0644') }}"
     owner: "{{ issue_cert_file_owner | d('root') }}"
   when: issue_cert_copy_ca|default(false)
+
+- name: issue_cert | Copy certificate serial to all hosts
+  copy:
+    content: "{{ hostvars[issue_cert_hosts|first]['issue_cert_result']['json']['data']['serial_number'] }}"
+    dest: "{{ issue_cert_path.rsplit('.', 1)|first }}.serial }}"
+    group: "{{ issue_cert_file_group | d('root' )}}"
+    mode: "{{ issue_cert_file_mode | d('0640') }}"
+    owner: "{{ issue_cert_file_owner | d('root') }}"