diff --git a/playbooks/legacy_groups.yml b/playbooks/boilerplate.yml
similarity index 71%
rename from playbooks/legacy_groups.yml
rename to playbooks/boilerplate.yml
index 643032ff0985c6300dfd84ef56a0a7846c739c3d..137a4c2c5b42ae8403a1930513699a5b274477bb 100644
--- a/playbooks/legacy_groups.yml
+++ b/playbooks/boilerplate.yml
@@ -1,5 +1,8 @@
 ---
-# This is an inventory compatibility playbook to ensure we keep compatibility with old style group names
+- name: Check ansible version
+  import_playbook: ansible_version.yml
+
+# These are inventory compatibility tasks to ensure we keep compatibility with old style group names
 
 - name: Add kube-master nodes to kube_control_plane
   hosts: kube-master
@@ -45,3 +48,11 @@
     - name: Add nodes to no-floating group
       group_by:
         key: 'no_floating'
+
+- name: Install bastion ssh config
+  hosts: bastion[0]
+  gather_facts: False
+  environment: "{{ proxy_disable_env }}"
+  roles:
+    - { role: kubespray-defaults }
+    - { role: bastion-ssh-config, tags: ["localhost", "bastion"] }
diff --git a/playbooks/cluster.yml b/playbooks/cluster.yml
index 85a483a3cf84ab1f51b5dea57a81660a2017b7eb..a6fd770b9573f8355ff25b4071fb7580e0642a49 100644
--- a/playbooks/cluster.yml
+++ b/playbooks/cluster.yml
@@ -1,17 +1,6 @@
 ---
-- name: Check ansible version
-  import_playbook: ansible_version.yml
-
-- name: Ensure compatibility with old groups
-  import_playbook: legacy_groups.yml
-
-- name: Install bastion ssh config
-  hosts: bastion[0]
-  gather_facts: False
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - { role: bastion-ssh-config, tags: ["localhost", "bastion"] }
+- name: Common tasks for every playbooks
+  import_playbook: boilerplate.yml
 
 - name: Gather facts
   import_playbook: facts.yml
@@ -28,35 +17,7 @@
     - { role: download, tags: download, when: "not skip_downloads" }
 
 - name: Install etcd
-  hosts: etcd:kube_control_plane
-  gather_facts: False
-  any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - role: etcd
-      tags: etcd
-      vars:
-        etcd_cluster_setup: true
-        etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}"
-      when: etcd_deployment_type != "kubeadm"
-
-- name: Install etcd certs on nodes if required
-  hosts: k8s_cluster
-  gather_facts: False
-  any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - role: etcd
-      tags: etcd
-      vars:
-        etcd_cluster_setup: false
-        etcd_events_cluster_setup: false
-      when:
-        - etcd_deployment_type != "kubeadm"
-        - kube_network_plugin in ["calico", "flannel", "canal", "cilium"] or cilium_deploy_additionally | default(false) | bool
-        - kube_network_plugin != "calico" or calico_datastore == "etcd"
+  import_playbook: install_etcd.yml
 
 - name: Install Kubernetes nodes
   hosts: k8s_cluster
diff --git a/playbooks/install_etcd.yml b/playbooks/install_etcd.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9bd13dfcd6e46e6ceabde0ddff64a56d134dd380
--- /dev/null
+++ b/playbooks/install_etcd.yml
@@ -0,0 +1,31 @@
+---
+- name: Install etcd
+  hosts: etcd:kube_control_plane
+  gather_facts: False
+  any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
+  environment: "{{ proxy_disable_env }}"
+  roles:
+    - { role: kubespray-defaults }
+    - role: etcd
+      tags: etcd
+      vars:
+        etcd_cluster_setup: true
+        etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}"
+      when: etcd_deployment_type != "kubeadm"
+
+- name: Install etcd certs on nodes if required
+  hosts: k8s_cluster
+  gather_facts: False
+  any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
+  environment: "{{ proxy_disable_env }}"
+  roles:
+    - { role: kubespray-defaults }
+    - role: etcd
+      tags: etcd
+      vars:
+        etcd_cluster_setup: false
+        etcd_events_cluster_setup: false
+      when:
+        - etcd_deployment_type != "kubeadm"
+        - kube_network_plugin in ["calico", "flannel", "canal", "cilium"] or cilium_deploy_additionally | default(false) | bool
+        - kube_network_plugin != "calico" or calico_datastore == "etcd"
diff --git a/playbooks/recover_control_plane.yml b/playbooks/recover_control_plane.yml
index d2bb574274518ed07fb56746959ee6eef79c046c..35ed2c276727774fdeeb0dcff24dcfebe1d59dce 100644
--- a/playbooks/recover_control_plane.yml
+++ b/playbooks/recover_control_plane.yml
@@ -1,17 +1,6 @@
 ---
-- name: Check ansible version
-  import_playbook: ansible_version.yml
-
-- name: Ensure compatibility with old groups
-  import_playbook: legacy_groups.yml
-
-- name: Install bastion ssh config
-  hosts: bastion[0]
-  gather_facts: False
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults}
-    - { role: bastion-ssh-config, tags: ["localhost", "bastion"]}
+- name: Common tasks for every playbooks
+  import_playbook: boilerplate.yml
 
 - name: Recover etcd
   hosts: etcd[0]
diff --git a/playbooks/remove_node.yml b/playbooks/remove_node.yml
index 63df859385afd22f56f0166664f6efbd7a29820b..e01338965e14022bbdd66c6dcc2e062169cea3a3 100644
--- a/playbooks/remove_node.yml
+++ b/playbooks/remove_node.yml
@@ -1,17 +1,6 @@
 ---
-- name: Check ansible version
-  import_playbook: ansible_version.yml
-
-- name: Ensure compatibility with old groups
-  import_playbook: legacy_groups.yml
-
-- name: Install bastion ssh config
-  hosts: bastion[0]
-  gather_facts: False
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - { role: bastion-ssh-config, tags: ["localhost", "bastion"] }
+- name: Common tasks for every playbooks
+  import_playbook: boilerplate.yml
 
 - name: Confirm node removal
   hosts: "{{ node | default('etcd:k8s_cluster:calico_rr') }}"
diff --git a/playbooks/reset.yml b/playbooks/reset.yml
index 0b4312fbd7ac033708ead0bb0a04f8643328af15..5742bd844e49fca23f29995a88302f38df7ecc9d 100644
--- a/playbooks/reset.yml
+++ b/playbooks/reset.yml
@@ -1,17 +1,6 @@
 ---
-- name: Check ansible version
-  import_playbook: ansible_version.yml
-
-- name: Ensure compatibility with old groups
-  import_playbook: legacy_groups.yml
-
-- name: Install bastion ssh config
-  hosts: bastion[0]
-  gather_facts: False
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults}
-    - { role: bastion-ssh-config, tags: ["localhost", "bastion"]}
+- name: Common tasks for every playbooks
+  import_playbook: boilerplate.yml
 
 - name: Gather facts
   import_playbook: facts.yml
diff --git a/playbooks/scale.yml b/playbooks/scale.yml
index aaa1bf5841bb4a359f990dd464c5ce11251b0112..b8f87f484e82ff1c4c8f4186a7f9a163e21188fd 100644
--- a/playbooks/scale.yml
+++ b/playbooks/scale.yml
@@ -1,17 +1,6 @@
 ---
-- name: Check ansible version
-  import_playbook: ansible_version.yml
-
-- name: Ensure compatibility with old groups
-  import_playbook: legacy_groups.yml
-
-- name: Install bastion ssh config
-  hosts: bastion[0]
-  gather_facts: False
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - { role: bastion-ssh-config, tags: ["localhost", "bastion"] }
+- name: Common tasks for every playbooks
+  import_playbook: boilerplate.yml
 
 - name: Gather facts
   import_playbook: facts.yml
diff --git a/playbooks/upgrade_cluster.yml b/playbooks/upgrade_cluster.yml
index 3e2125c83d2635767a2851845b20a7fc27f69428..a79cf0aa76364f821f613a53fb7fb72cb6726a79 100644
--- a/playbooks/upgrade_cluster.yml
+++ b/playbooks/upgrade_cluster.yml
@@ -1,17 +1,6 @@
 ---
-- name: Check ansible version
-  import_playbook: ansible_version.yml
-
-- name: Ensure compatibility with old groups
-  import_playbook: legacy_groups.yml
-
-- name: Install bastion ssh config
-  hosts: bastion[0]
-  gather_facts: False
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - { role: bastion-ssh-config, tags: ["localhost", "bastion"] }
+- name: Common tasks for every playbooks
+  import_playbook: boilerplate.yml
 
 - name: Gather facts
   import_playbook: facts.yml
@@ -47,35 +36,7 @@
     - { role: container-engine, tags: "container-engine", when: deploy_container_engine }
 
 - name: Install etcd
-  hosts: etcd:kube_control_plane
-  gather_facts: False
-  any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - role: etcd
-      tags: etcd
-      vars:
-        etcd_cluster_setup: true
-        etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}"
-      when: etcd_deployment_type != "kubeadm"
-
-- name: Install etcd certs on nodes if required
-  hosts: k8s_cluster
-  gather_facts: False
-  any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
-  environment: "{{ proxy_disable_env }}"
-  roles:
-    - { role: kubespray-defaults }
-    - role: etcd
-      tags: etcd
-      vars:
-        etcd_cluster_setup: false
-        etcd_events_cluster_setup: false
-      when:
-        - etcd_deployment_type != "kubeadm"
-        - kube_network_plugin in ["calico", "flannel", "canal", "cilium"] or cilium_deploy_additionally | default(false) | bool
-        - kube_network_plugin != "calico" or calico_datastore == "etcd"
+  import_playbook: install_etcd.yml
 
 - name: Handle upgrades to master components first to maintain backwards compat.
   gather_facts: False