diff --git a/roles/upgrade/post-upgrade/defaults/main.yml b/roles/upgrade/post-upgrade/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c3574aed450d74f3ce1b0b24a4d531e2e11617b8
--- /dev/null
+++ b/roles/upgrade/post-upgrade/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+# how long to wait for cilium after upgrade before uncordoning
+upgrade_post_cilium_wait_timeout: 120s
diff --git a/roles/upgrade/post-upgrade/tasks/main.yml b/roles/upgrade/post-upgrade/tasks/main.yml
index e56c1a1b2fd2feff436199778a43a603e4e79833..f19ecafb1d4b86632eee53bdc17b3c21aad053d0 100644
--- a/roles/upgrade/post-upgrade/tasks/main.yml
+++ b/roles/upgrade/post-upgrade/tasks/main.yml
@@ -1,4 +1,16 @@
 ---
+- name: wait for cilium
+  when:
+    - needs_cordoning|default(false)
+    - kube_network_plugin == 'cilium'
+  command: >
+    {{ bin_dir }}/kubectl --kubeconfig {{ kube_config_dir }}/admin.conf
+    wait pod -n kube-system -l k8s-app=cilium
+    --field-selector 'spec.nodeName=={{ kube_override_hostname|default(inventory_hostname) }}'
+    --for=condition=Ready
+    --timeout={{ upgrade_post_cilium_wait_timeout }}
+  delegate_to: "{{ groups['kube_control_plane'][0] }}"
+
 - name: Uncordon node
   command: "{{ bin_dir }}/kubectl --kubeconfig {{ kube_config_dir }}/admin.conf uncordon {{ kube_override_hostname|default(inventory_hostname) }}"
   delegate_to: "{{ groups['kube_control_plane'][0] }}"