diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fb1e8787260a529e51bd70e6e813f8fd6ade201a..4daad30a6c18edd9050131ddd63e8fefc334c98b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -33,7 +33,7 @@ variables:
   MITOGEN_ENABLE: "false"
   ANSIBLE_LOG_LEVEL: "-vv"
   RECOVER_CONTROL_PLANE_TEST: "false"
-  RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[2:],kube_control_plane[1:]"
+  RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[2:]:kube_control_plane[1:]"
   TERRAFORM_VERSION: 1.3.7
   PIPELINE_IMAGE: "$CI_REGISTRY_IMAGE/pipeline:${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA}"
 
diff --git a/.gitlab-ci/packet.yml b/.gitlab-ci/packet.yml
index 1cb52782343d99d40be1c1882c10a18460df6ac1..c6f9f2f7163e5121fa68cd389879e5911c2f08aa 100644
--- a/.gitlab-ci/packet.yml
+++ b/.gitlab-ci/packet.yml
@@ -122,6 +122,11 @@ packet_debian12-docker:
   extends: .packet_pr
   when: on_success
 
+packet_debian12-cilium:
+  stage: deploy-part2
+  extends: .packet_periodic
+  when: on_success
+
 packet_centos7-calico-ha-once-localhost:
   stage: deploy-part2
   extends: .packet_pr
@@ -311,7 +316,7 @@ packet_ubuntu20-calico-ha-recover:
   when: on_success
   variables:
     RECOVER_CONTROL_PLANE_TEST: "true"
-    RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[2:],kube_control_plane[1:]"
+    RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[2:]:kube_control_plane[1:]"
 
 packet_ubuntu20-calico-ha-recover-noquorum:
   stage: deploy-part3
@@ -319,4 +324,4 @@ packet_ubuntu20-calico-ha-recover-noquorum:
   when: on_success
   variables:
     RECOVER_CONTROL_PLANE_TEST: "true"
-    RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[1:],kube_control_plane[1:]"
+    RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[1:]:kube_control_plane[1:]"
diff --git a/docs/ci.md b/docs/ci.md
index c690b576c487e7543efc289f4c938a98b6d2f349..466072edc45360018ed8ab454053fa9c5d0ecdda 100644
--- a/docs/ci.md
+++ b/docs/ci.md
@@ -11,7 +11,7 @@ amazon |  :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
 centos7 |  :white_check_mark: | :x: | :x: | :white_check_mark: | :x: | :white_check_mark: | :x: | :white_check_mark: |
 debian10 |  :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :white_check_mark: | :x: |
 debian11 |  :white_check_mark: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
-debian12 |  :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
+debian12 |  :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: |
 fedora37 |  :white_check_mark: | :x: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: |
 fedora38 |  :x: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: |
 opensuse |  :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
diff --git a/roles/recover_control_plane/etcd/tasks/main.yml b/roles/recover_control_plane/etcd/tasks/main.yml
index 3c30344926adbbbaf4c32fb1e2ac21661e2d6a90..66dbc8b6deca2a76502880b93cd3afbad03ca291 100644
--- a/roles/recover_control_plane/etcd/tasks/main.yml
+++ b/roles/recover_control_plane/etcd/tasks/main.yml
@@ -12,19 +12,19 @@
     ETCDCTL_KEY: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
     ETCDCTL_CACERT: "{{ etcd_cert_dir }}/ca.pem"
   when:
-    - inventory_hostname in groups['broken_etcd']
+    - groups['broken_etcd']
 
 - name: Set healthy fact
   set_fact:
     healthy: "{{ etcd_endpoint_health.stderr is match('Error: unhealthy cluster') }}"
   when:
-    - inventory_hostname in groups['broken_etcd']
+    - groups['broken_etcd']
 
 - name: Set has_quorum fact
   set_fact:
     has_quorum: "{{ etcd_endpoint_health.stdout_lines | select('match', '.*is healthy.*') | list | length >= etcd_endpoint_health.stderr_lines | select('match', '.*is unhealthy.*') | list | length }}"
   when:
-    - inventory_hostname in groups['broken_etcd']
+    - groups['broken_etcd']
 
 - name: Recover lost etcd quorum
   include_tasks: recover_lost_quorum.yml
@@ -40,7 +40,7 @@
   with_items: "{{ groups['broken_etcd'] }}"
   ignore_errors: true  # noqa ignore-errors
   when:
-    - inventory_hostname in groups['broken_etcd']
+    - groups['broken_etcd']
     - has_quorum
 
 - name: Delete old certificates
@@ -56,7 +56,7 @@
   loop: "{{ delete_old_cerificates.results }}"
   changed_when: false
   when:
-    - inventory_hostname in groups['broken_etcd']
+    - groups['broken_etcd']
     - "item.rc != 0 and not 'No such file or directory' in item.stderr"
 
 - name: Get etcd cluster members
@@ -71,7 +71,7 @@
     ETCDCTL_KEY: "{{ etcd_cert_dir }}/admin-{{ inventory_hostname }}-key.pem"
     ETCDCTL_CACERT: "{{ etcd_cert_dir }}/ca.pem"
   when:
-    - inventory_hostname in groups['broken_etcd']
+    - groups['broken_etcd']
     - not healthy
     - has_quorum
 
@@ -87,7 +87,7 @@
     - "{{ groups['broken_etcd'] }}"
     - "{{ member_list.stdout_lines }}"
   when:
-    - inventory_hostname in groups['broken_etcd']
+    - groups['broken_etcd']
     - not healthy
     - has_quorum
     - hostvars[item[0]]['etcd_member_name'] == item[1].replace(' ', '').split(',')[2]
diff --git a/tests/files/packet_debian12-cilium.yml b/tests/files/packet_debian12-cilium.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c77bcf33c8ec72112835e6a299d1ff804af837c1
--- /dev/null
+++ b/tests/files/packet_debian12-cilium.yml
@@ -0,0 +1,7 @@
+---
+# Instance settings
+cloud_image: debian-12
+mode: default
+
+# Kubespray settings
+kube_network_plugin: cilium
diff --git a/tests/scripts/testcases_run.sh b/tests/scripts/testcases_run.sh
index 4155427fff2074c1b2b29cfeeb4aaf34fe0f0bff..7cd4671a76db9a6a21909c32582cdaaaff3b73a4 100755
--- a/tests/scripts/testcases_run.sh
+++ b/tests/scripts/testcases_run.sh
@@ -83,7 +83,7 @@ fi
 # Test control plane recovery
 if [ "${RECOVER_CONTROL_PLANE_TEST}" != "false" ]; then
   ansible-playbook ${ANSIBLE_LOG_LEVEL} -e @${CI_TEST_SETTING} -e @${CI_TEST_REGISTRY_MIRROR} -e @${CI_TEST_VARS} -e local_release_dir=${PWD}/downloads --limit "${RECOVER_CONTROL_PLANE_TEST_GROUPS}:!fake_hosts" -e reset_confirmation=yes reset.yml
-  ansible-playbook ${ANSIBLE_LOG_LEVEL} -e @${CI_TEST_SETTING} -e @${CI_TEST_REGISTRY_MIRROR} -e @${CI_TEST_VARS} -e local_release_dir=${PWD}/downloads -e etcd_retries=10 --limit etcd,kube_control_plane:!fake_hosts recover-control-plane.yml
+  ansible-playbook ${ANSIBLE_LOG_LEVEL} -e @${CI_TEST_SETTING} -e @${CI_TEST_REGISTRY_MIRROR} -e @${CI_TEST_VARS} -e local_release_dir=${PWD}/downloads -e etcd_retries=10 --limit "etcd:kube_control_plane:!fake_hosts" recover-control-plane.yml
 fi
 
 # Test collection build and install by installing our collection, emptying our repository, adding