diff --git a/.ansible-lint b/.ansible-lint
index 048a89787a90c035ba05fec2a282d828aff94ae8..5848a6034cf5d943ce483c06feabf5a85a06b436 100644
--- a/.ansible-lint
+++ b/.ansible-lint
@@ -24,7 +24,14 @@ skip_list:
   # (Disabled in June 2021)
   - 'role-name'
 
+  - 'experimental'
   # [var-naming] "defaults/main.yml" File defines variable 'apiVersion' that violates variable naming standards
   # In Kubespray we use variables that use camelCase to match their k8s counterparts
   # (Disabled in June 2021)
   - 'var-naming'
+  - 'var-spacing'
+
+  # [fqcn-builtins]
+  # Roles in kubespray don't need fully qualified collection names
+  # (Disabled in Feb 2023)
+  - 'fqcn-builtins'
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 28cf7a907343ff89bd018a3cbef0696f5374ce6f..3f4f0918c9d3b04d833c1f7706a067513e0b1151 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,5 +1,20 @@
 ---
 repos:
+
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v3.4.0
+    hooks:
+      - id: check-added-large-files
+      - id: check-case-conflict
+      - id: check-executables-have-shebangs
+      - id: check-xml
+      - id: check-merge-conflict
+      - id: detect-private-key
+      - id: end-of-file-fixer
+      - id: forbid-new-submodules
+      - id: requirements-txt-fixer
+      - id: trailing-whitespace
+
   - repo: https://github.com/adrienverge/yamllint.git
     rev: v1.27.1
     hooks:
diff --git a/CNAME b/CNAME
index 4d47144bc21a0ef2c42264179cc78cb54500cac1..e5bd1ffa1bbc5a51428f22c27f562a680b725ea5 100644
--- a/CNAME
+++ b/CNAME
@@ -1 +1 @@
-kubespray.io
\ No newline at end of file
+kubespray.io
diff --git a/LICENSE b/LICENSE
index 51004adce48a22dce25168631ae3ada2e4ae83b5..0b540e19a344c8db9cfa0088993feb6584b8fafd 100644
--- a/LICENSE
+++ b/LICENSE
@@ -187,7 +187,7 @@
       identification within third-party archives.
 
    Copyright 2016 Kubespray
-   
+
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
diff --git a/OWNERS b/OWNERS
index a52158cbd1fffbbdcbddc1c0c030ece8b59e2986..e4ac17f4556f0e0373a5c276e360344dffe27476 100644
--- a/OWNERS
+++ b/OWNERS
@@ -5,4 +5,4 @@ approvers:
 reviewers:
   - kubespray-reviewers
 emeritus_approvers:
-  - kubespray-emeritus_approvers
\ No newline at end of file
+  - kubespray-emeritus_approvers
diff --git a/contrib/aws_inventory/requirements.txt b/contrib/aws_inventory/requirements.txt
index 4989ce660e87bebaba76a450dd0e1a581cda319c..179d5de54c6bcf63954190e40018514ed5a77ae6 100644
--- a/contrib/aws_inventory/requirements.txt
+++ b/contrib/aws_inventory/requirements.txt
@@ -1 +1 @@
-boto3  # Apache-2.0
\ No newline at end of file
+boto3  # Apache-2.0
diff --git a/contrib/azurerm/.gitignore b/contrib/azurerm/.gitignore
index 3a04fb27660d35448bf7a95ab598fb3376933874..3ef07f874604855abd992b494295ebe80a387225 100644
--- a/contrib/azurerm/.gitignore
+++ b/contrib/azurerm/.gitignore
@@ -1,2 +1,2 @@
 .generated
-/inventory
\ No newline at end of file
+/inventory
diff --git a/contrib/azurerm/roles/generate-inventory_2/templates/inventory.j2 b/contrib/azurerm/roles/generate-inventory_2/templates/inventory.j2
index 6ab59df1ba28b8f9a74024a5868affc5a937fa58..2f6ac5c431526327b172dd411cc33fd8ba8ab5a2 100644
--- a/contrib/azurerm/roles/generate-inventory_2/templates/inventory.j2
+++ b/contrib/azurerm/roles/generate-inventory_2/templates/inventory.j2
@@ -31,4 +31,3 @@
 [k8s_cluster:children]
 kube_node
 kube_control_plane
-
diff --git a/contrib/azurerm/roles/generate-templates/templates/availability-sets.json b/contrib/azurerm/roles/generate-templates/templates/availability-sets.json
index 4f458cd66d7ff6350031ed9ebef34cc6b5b52d35..78c1547a9c377c1012fc10b01d57dee12b5f4065 100644
--- a/contrib/azurerm/roles/generate-templates/templates/availability-sets.json
+++ b/contrib/azurerm/roles/generate-templates/templates/availability-sets.json
@@ -27,4 +27,4 @@
       }
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/contrib/azurerm/roles/generate-templates/templates/bastion.json b/contrib/azurerm/roles/generate-templates/templates/bastion.json
index d7fd9c8f6ca48cac04a5d4bc2fb5795700fd542c..4cf8fc7a64b1cf927237ad1582d56f16846029c2 100644
--- a/contrib/azurerm/roles/generate-templates/templates/bastion.json
+++ b/contrib/azurerm/roles/generate-templates/templates/bastion.json
@@ -103,4 +103,4 @@
     }
     {% endif %}
   ]
-}
\ No newline at end of file
+}
diff --git a/contrib/azurerm/roles/generate-templates/templates/clear-rg.json b/contrib/azurerm/roles/generate-templates/templates/clear-rg.json
index 5facf5e67ab5c206f2138a5894da4cd582f5d691..faf31e8cca95dcc76374557428f90d00ca5c7c45 100644
--- a/contrib/azurerm/roles/generate-templates/templates/clear-rg.json
+++ b/contrib/azurerm/roles/generate-templates/templates/clear-rg.json
@@ -5,4 +5,4 @@
   "variables": {},
   "resources": [],
   "outputs": {}
-}
\ No newline at end of file
+}
diff --git a/contrib/azurerm/roles/generate-templates/templates/storage.json b/contrib/azurerm/roles/generate-templates/templates/storage.json
index 2632aba2cf5e7a3eed3f214b95442c78aa9cb980..1ed08669784a9383b678a1478be3fe899cc32e6c 100644
--- a/contrib/azurerm/roles/generate-templates/templates/storage.json
+++ b/contrib/azurerm/roles/generate-templates/templates/storage.json
@@ -16,4 +16,4 @@
       }
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/contrib/inventory_builder/requirements.txt b/contrib/inventory_builder/requirements.txt
index 3d833f66ec3d4bb6397cfd19fdb784a4a11fdc16..c54501a4bd39c6dff8511573107e53240b1a8aa1 100644
--- a/contrib/inventory_builder/requirements.txt
+++ b/contrib/inventory_builder/requirements.txt
@@ -1,3 +1,3 @@
 configparser>=3.3.0
-ruamel.yaml>=0.15.88
 ipaddress
+ruamel.yaml>=0.15.88
diff --git a/contrib/inventory_builder/test-requirements.txt b/contrib/inventory_builder/test-requirements.txt
index 4e334a09405c3478c69f6aed8ac0f7c93a15edc4..98a662a4dde66e413991d8edbb9ba8a7a08f33ba 100644
--- a/contrib/inventory_builder/test-requirements.txt
+++ b/contrib/inventory_builder/test-requirements.txt
@@ -1,3 +1,3 @@
 hacking>=0.10.2
-pytest>=2.8.0
 mock>=1.3.0
+pytest>=2.8.0
diff --git a/contrib/kvm-setup/group_vars/all b/contrib/kvm-setup/group_vars/all
index 6edfd8fd146115ad74ff107cc1d1d0938f3c10a6..d497c5888bb301fe4333860aed7c26b59d30bda2 100644
--- a/contrib/kvm-setup/group_vars/all
+++ b/contrib/kvm-setup/group_vars/all
@@ -1,3 +1,2 @@
 #k8s_deployment_user: kubespray
 #k8s_deployment_user_pkey_path: /tmp/ssh_rsa
-
diff --git a/contrib/network-storage/glusterfs/inventory.example b/contrib/network-storage/glusterfs/inventory.example
index 84dd022e9e0038c3bcc65e79cf5c55e5a1d65a26..985647e8cd07e0da02f852b99557227c07cfa1f1 100644
--- a/contrib/network-storage/glusterfs/inventory.example
+++ b/contrib/network-storage/glusterfs/inventory.example
@@ -41,4 +41,3 @@
 
 # [network-storage:children]
 # gfs-cluster
-
diff --git a/contrib/network-storage/glusterfs/roles/kubernetes-pv/ansible/templates/glusterfs-kubernetes-endpoint.json.j2 b/contrib/network-storage/glusterfs/roles/kubernetes-pv/ansible/templates/glusterfs-kubernetes-endpoint.json.j2
index 866c09f3ea2c108ae092a02552640815ed4d4cc0..36cc1cccab04a2229c5c88fa8f04642480aa72cf 100644
--- a/contrib/network-storage/glusterfs/roles/kubernetes-pv/ansible/templates/glusterfs-kubernetes-endpoint.json.j2
+++ b/contrib/network-storage/glusterfs/roles/kubernetes-pv/ansible/templates/glusterfs-kubernetes-endpoint.json.j2
@@ -21,4 +21,3 @@
     {% endfor %}
   ]
 }
-
diff --git a/contrib/terraform/equinix/output.tf b/contrib/terraform/equinix/output.tf
index 299bced95ad815467f202d0dd44eb65908932760..f4ab63a94d3bb837010e39af7a8fd7581ad35cc6 100644
--- a/contrib/terraform/equinix/output.tf
+++ b/contrib/terraform/equinix/output.tf
@@ -13,4 +13,3 @@ output "k8s_etcds" {
 output "k8s_nodes" {
   value = equinix_metal_device.k8s_node.*.access_public_ipv4
 }
-
diff --git a/contrib/terraform/equinix/variables.tf b/contrib/terraform/equinix/variables.tf
index d8e2d3da12dbe0523c5f9a9bb9abf77d0232e4ea..82c7015080ef5346106652e33dd1d7ba99219b95 100644
--- a/contrib/terraform/equinix/variables.tf
+++ b/contrib/terraform/equinix/variables.tf
@@ -54,4 +54,3 @@ variable "number_of_etcd" {
 variable "number_of_k8s_nodes" {
   default = 1
 }
-
diff --git a/contrib/terraform/hetzner/main.tf b/contrib/terraform/hetzner/main.tf
index fc2f27108dea71e45e723c59b0e75fa692eca4b2..d02a06484b46e239bf0c48c50b65def7d35813f1 100644
--- a/contrib/terraform/hetzner/main.tf
+++ b/contrib/terraform/hetzner/main.tf
@@ -53,4 +53,4 @@ resource "null_resource" "inventories" {
   triggers = {
     template = data.template_file.inventory.rendered
   }
-}
\ No newline at end of file
+}
diff --git a/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/outputs.tf b/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/outputs.tf
index c6bb276da16f987ecdba0422cd3c335795a459da..5c31aaa003cd0ab26a932e2e08287299e125761f 100644
--- a/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/outputs.tf
+++ b/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/outputs.tf
@@ -24,4 +24,4 @@ output "cluster_private_network_cidr" {
 
 output "network_id" {
   value = hcloud_network.kubernetes.id
-}
\ No newline at end of file
+}
diff --git a/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/templates/machine.yaml.tmpl b/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/templates/machine.yaml.tmpl
index 26e05f867b2d84f49ca5ee0e26742adcc32902d6..426cb09ae0fc85e4ddbae3da69e5baec926aa0d5 100644
--- a/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/templates/machine.yaml.tmpl
+++ b/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/templates/machine.yaml.tmpl
@@ -13,4 +13,4 @@ storage:
           #!/bin/bash
           set -euo pipefail
           hostname="$(hostname)"
-          echo My name is ${name} and the hostname is $${hostname}
\ No newline at end of file
+          echo My name is ${name} and the hostname is $${hostname}
diff --git a/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/versions.tf b/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/versions.tf
index 4291f8a6180302c13f6e72f735bc31ed9556df1a..5fa23ff851ac013d1fa47f516481dcfec8661048 100644
--- a/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/versions.tf
+++ b/contrib/terraform/hetzner/modules/kubernetes-cluster-flatcar/versions.tf
@@ -10,4 +10,4 @@ terraform {
       source  = "hashicorp/null"
     }
   }
-}
\ No newline at end of file
+}
diff --git a/contrib/terraform/hetzner/modules/kubernetes-cluster/output.tf b/contrib/terraform/hetzner/modules/kubernetes-cluster/output.tf
index c6bb276da16f987ecdba0422cd3c335795a459da..5c31aaa003cd0ab26a932e2e08287299e125761f 100644
--- a/contrib/terraform/hetzner/modules/kubernetes-cluster/output.tf
+++ b/contrib/terraform/hetzner/modules/kubernetes-cluster/output.tf
@@ -24,4 +24,4 @@ output "cluster_private_network_cidr" {
 
 output "network_id" {
   value = hcloud_network.kubernetes.id
-}
\ No newline at end of file
+}
diff --git a/contrib/terraform/hetzner/modules/kubernetes-cluster/templates/cloud-init.tmpl b/contrib/terraform/hetzner/modules/kubernetes-cluster/templates/cloud-init.tmpl
index c81aef5dd4c2a2ce16be2e49073a3238de7bc5f1..02a4e2dd08470bbf0ebf13402c56b3c117a05b89 100644
--- a/contrib/terraform/hetzner/modules/kubernetes-cluster/templates/cloud-init.tmpl
+++ b/contrib/terraform/hetzner/modules/kubernetes-cluster/templates/cloud-init.tmpl
@@ -14,4 +14,3 @@ ssh_authorized_keys:
 %{ for ssh_public_key in ssh_public_keys ~}
   - ${ssh_public_key}
 %{ endfor ~}
-
diff --git a/contrib/terraform/openstack/modules/ips/main.tf b/contrib/terraform/openstack/modules/ips/main.tf
index 3f962fdfc97c9444ea140575ffe315c1e699902b..b0989dcc2242f9348363b42d166b54ebba6b6761 100644
--- a/contrib/terraform/openstack/modules/ips/main.tf
+++ b/contrib/terraform/openstack/modules/ips/main.tf
@@ -44,4 +44,3 @@ resource "openstack_networking_floatingip_v2" "k8s_nodes" {
   pool       = var.floatingip_pool
   depends_on = [null_resource.dummy_dependency]
 }
-
diff --git a/contrib/terraform/openstack/sample-inventory/cluster.tfvars b/contrib/terraform/openstack/sample-inventory/cluster.tfvars
index 3c2576775fd2c99d18ee8dec569cabe479546ce4..8ab7c6d38e46bad1e454366e593187404ebc4f16 100644
--- a/contrib/terraform/openstack/sample-inventory/cluster.tfvars
+++ b/contrib/terraform/openstack/sample-inventory/cluster.tfvars
@@ -86,4 +86,4 @@ floatingip_pool = "<pool>"
 bastion_allowed_remote_ips = ["0.0.0.0/0"]
 
 # Force port security to be null. Some cloud providers do not allow to set port security.
-# force_null_port_security = false
\ No newline at end of file
+# force_null_port_security = false
diff --git a/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf b/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
index afa801948de081ca7f0bc826b2a18257e2ee42e7..d638c3e74d504def110daee2f3b1bfb87d2eca63 100644
--- a/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
+++ b/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
@@ -80,7 +80,7 @@ resource "upcloud_server" "master" {
   lifecycle {
     ignore_changes = [storage_devices]
   }
-  
+
   firewall  = var.firewall_enabled
 
   dynamic "storage_devices" {
@@ -525,7 +525,7 @@ resource "upcloud_loadbalancer_backend" "lb_backend" {
 
 resource "upcloud_loadbalancer_frontend" "lb_frontend" {
   for_each = var.loadbalancer_enabled ? var.loadbalancers : {}
-  
+
   loadbalancer         = upcloud_loadbalancer.lb[0].id
   name                 = "lb-frontend-${each.key}"
   mode                 = "tcp"
@@ -535,7 +535,7 @@ resource "upcloud_loadbalancer_frontend" "lb_frontend" {
 
 resource "upcloud_loadbalancer_static_backend_member" "lb_backend_member" {
   for_each = {
-    for be_server in local.lb_backend_servers: 
+    for be_server in local.lb_backend_servers:
       "${be_server.server_name}-lb-backend-${be_server.lb_name}" => be_server
       if var.loadbalancer_enabled
   }
diff --git a/docs/vars.md b/docs/vars.md
index 877c78f7e2762d49b6839a1cf20dff5985bb68a6..2fa8ea02938784e12500a42a3609b42cd4f5e911 100644
--- a/docs/vars.md
+++ b/docs/vars.md
@@ -189,7 +189,7 @@ Stack](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/dns-stack.m
 * *http_proxy/https_proxy/no_proxy/no_proxy_exclude_workers/additional_no_proxy* - Proxy variables for deploying behind a
   proxy. Note that no_proxy defaults to all internal cluster IPs and hostnames
   that correspond to each node.
-  
+
 * *kubelet_cgroup_driver* - Allows manual override of the cgroup-driver option for Kubelet.
   By default autodetection is used to match container manager configuration.
   `systemd` is the preferred driver for `containerd` though it can have issues with `cgroups v1` and `kata-containers` in which case you may want to change to `cgroupfs`.
@@ -213,9 +213,9 @@ Stack](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/dns-stack.m
 
   * *kubelet_secure_addresses* - By default *kubelet_systemd_hardening* set the **control plane** `ansible_host` IPs as the `kubelet_secure_addresses`. In case you have multiple interfaces in your control plane nodes and the `kube-apiserver` is not bound to the default interface, you can override them with this variable.
     Example:
-  
+
     The **control plane** node may have 2 interfaces with the following IP addresses: `eth0:10.0.0.110`, `eth1:192.168.1.110`.
-  
+
     By default the `kubelet_secure_addresses` is set with the `10.0.0.110` the ansible control host uses `eth0` to  connect to the machine. In case you want to use `eth1` as the outgoing interface on which `kube-apiserver` connects to the `kubelet`s, you should override the variable in this way: `kubelet_secure_addresses: "192.168.1.110"`.
 
 * *node_labels* - Labels applied to nodes via `kubectl label node`.
diff --git a/inventory/sample/group_vars/all/etcd.yml b/inventory/sample/group_vars/all/etcd.yml
index 7206a06b51377411e311c998ff3a17cea612ba1c..39600c35fbe447bbd9826aeba8d73ac054ffc953 100644
--- a/inventory/sample/group_vars/all/etcd.yml
+++ b/inventory/sample/group_vars/all/etcd.yml
@@ -13,4 +13,4 @@ etcd_data_dir: /var/lib/etcd
 
 ## Settings for etcd deployment type
 # Set this to docker if you are using container_manager: docker
-etcd_deployment_type: host
\ No newline at end of file
+etcd_deployment_type: host
diff --git a/inventory/sample/group_vars/all/upcloud.yml b/inventory/sample/group_vars/all/upcloud.yml
index c2d7f5df8c280d46ec42896cd601b5763b80bc3f..f05435daa07ebbc5b03bf97ad0320c4f6d79de6f 100644
--- a/inventory/sample/group_vars/all/upcloud.yml
+++ b/inventory/sample/group_vars/all/upcloud.yml
@@ -21,4 +21,4 @@
 #     is_default: false
 #     expand_persistent_volumes: true
 #     parameters:
-#       tier: hdd
\ No newline at end of file
+#       tier: hdd
diff --git a/inventory/sample/patches/kube-controller-manager+merge.yaml b/inventory/sample/patches/kube-controller-manager+merge.yaml
index a8aa5a7856b710c10139ae9c3824c7c341e24e09..3f0fbbcd5e8e35092de6eafe69bae6fe54f88a09 100644
--- a/inventory/sample/patches/kube-controller-manager+merge.yaml
+++ b/inventory/sample/patches/kube-controller-manager+merge.yaml
@@ -5,4 +5,4 @@ metadata:
   name: kube-controller-manager
   annotations:
     prometheus.io/scrape: 'true'
-    prometheus.io/port: '10257'
\ No newline at end of file
+    prometheus.io/port: '10257'
diff --git a/inventory/sample/patches/kube-scheduler+merge.yaml b/inventory/sample/patches/kube-scheduler+merge.yaml
index 0bb39509d51f4e50030ff032586ce614090f90ee..00f457237cf4d8545b267e0e85a0df5294b5ebe2 100644
--- a/inventory/sample/patches/kube-scheduler+merge.yaml
+++ b/inventory/sample/patches/kube-scheduler+merge.yaml
@@ -5,4 +5,4 @@ metadata:
   name: kube-scheduler
   annotations:
     prometheus.io/scrape: 'true'
-    prometheus.io/port: '10259'
\ No newline at end of file
+    prometheus.io/port: '10259'
diff --git a/logo/logo-clear.svg b/logo/logo-clear.svg
index 00798d6d87941324ebd5edf41f971e45e257cb28..7d60232126e38e39727e4d6d8bf05764275da97e 100644
--- a/logo/logo-clear.svg
+++ b/logo/logo-clear.svg
@@ -77,4 +77,4 @@
    </g>
   </g>
  </g>
-</svg>
\ No newline at end of file
+</svg>
diff --git a/logo/logo-dark.svg b/logo/logo-dark.svg
index d9d8cb56b774aec196acc67619f1a13a5ebc3eee..3f6f0a66f463ea2817ee3d780060b294176e72b1 100644
--- a/logo/logo-dark.svg
+++ b/logo/logo-dark.svg
@@ -80,4 +80,4 @@
    </g>
   </g>
  </g>
-</svg>
\ No newline at end of file
+</svg>
diff --git a/logo/logo-text-clear.svg b/logo/logo-text-clear.svg
index c24f788196e869e02b82d4aa5233f51c717e0e55..b1029ded911159eea67fe6518f6182fbf451b492 100644
--- a/logo/logo-text-clear.svg
+++ b/logo/logo-text-clear.svg
@@ -104,4 +104,4 @@
    </g>
   </g>
  </g>
-</svg>
\ No newline at end of file
+</svg>
diff --git a/logo/logo-text-dark.svg b/logo/logo-text-dark.svg
index 171df353d69ce5b487247d9932ec2c79b89afa30..52bdb4e1e12079be3782fc9e54887733fbafb4c1 100644
--- a/logo/logo-text-dark.svg
+++ b/logo/logo-text-dark.svg
@@ -107,4 +107,4 @@
    </g>
   </g>
  </g>
-</svg>
\ No newline at end of file
+</svg>
diff --git a/logo/logo-text-mixed.svg b/logo/logo-text-mixed.svg
index ed058c07c30798aaaacbf774b762c4dd51b89ebe..44ea1feb6ac176452ded4e5da16c0ae5c2b766e5 100644
--- a/logo/logo-text-mixed.svg
+++ b/logo/logo-text-mixed.svg
@@ -107,4 +107,4 @@
    </g>
   </g>
  </g>
-</svg>
\ No newline at end of file
+</svg>
diff --git a/pipeline.Dockerfile b/pipeline.Dockerfile
index 10fe1d845bc422f7606b92111c3f9f6dcc0055d9..7e1667db1e3f322dbea8c6e6f5e3886b386cdcb0 100644
--- a/pipeline.Dockerfile
+++ b/pipeline.Dockerfile
@@ -48,4 +48,4 @@ RUN wget https://releases.hashicorp.com/vagrant/${VAGRANT_VERSION}/vagrant_${VAG
 
 # Install Kubernetes collections
 RUN pip3 install kubernetes \
-    && ansible-galaxy collection install kubernetes.core
\ No newline at end of file
+    && ansible-galaxy collection install kubernetes.core
diff --git a/requirements-2.11.txt b/requirements-2.11.txt
index ef2e02315c3b611cc41ba4413e6986e9e5b1553a..b381159154895409600c53ad8fab76032e83b562 100644
--- a/requirements-2.11.txt
+++ b/requirements-2.11.txt
@@ -2,9 +2,9 @@ ansible==4.10.0
 ansible-core==2.11.11
 cryptography==3.4.8
 jinja2==2.11.3
+jmespath==0.9.5
+MarkupSafe==1.1.1
 netaddr==0.7.19
 pbr==5.4.4
-jmespath==0.9.5
 ruamel.yaml==0.16.10
 ruamel.yaml.clib==0.2.7
-MarkupSafe==1.1.1
diff --git a/requirements-2.12.txt b/requirements-2.12.txt
index 722cc99e3900eaf7658fd311e59ff85596fba50c..14779e2a987a05753a3a0f810d45314c6fc4d086 100644
--- a/requirements-2.12.txt
+++ b/requirements-2.12.txt
@@ -2,9 +2,9 @@ ansible==5.7.1
 ansible-core==2.12.5
 cryptography==3.4.8
 jinja2==2.11.3
+jmespath==0.9.5
+MarkupSafe==1.1.1
 netaddr==0.7.19
 pbr==5.4.4
-jmespath==0.9.5
 ruamel.yaml==0.16.10
 ruamel.yaml.clib==0.2.7
-MarkupSafe==1.1.1
diff --git a/roles/bastion-ssh-config/defaults/main.yml b/roles/bastion-ssh-config/defaults/main.yml
index d322814e9ce490dee04585a6bac1b7f5ea03f377..83aafedefb41ce198686ff5ca5e7e8bcf1caeeeb 100644
--- a/roles/bastion-ssh-config/defaults/main.yml
+++ b/roles/bastion-ssh-config/defaults/main.yml
@@ -1,2 +1,2 @@
 ---
-ssh_bastion_confing__name: ssh-bastion.conf
\ No newline at end of file
+ssh_bastion_confing__name: ssh-bastion.conf
diff --git a/roles/container-engine/containerd-common/meta/main.yml b/roles/container-engine/containerd-common/meta/main.yml
index a4159c5bfb548a514bb6a2f03a9826f5c2bee722..61d3ffe4f9416869d4fff5118f784dd567977025 100644
--- a/roles/container-engine/containerd-common/meta/main.yml
+++ b/roles/container-engine/containerd-common/meta/main.yml
@@ -1,2 +1,2 @@
 ---
-allow_duplicates: true
\ No newline at end of file
+allow_duplicates: true
diff --git a/roles/container-engine/cri-o/templates/config.json.j2 b/roles/container-engine/cri-o/templates/config.json.j2
index 522ade7a4fe677d45b47aa035d26298860131e2f..4afd49f6b2d2407bff2c6713fe5eb7d76bcc2d90 100644
--- a/roles/container-engine/cri-o/templates/config.json.j2
+++ b/roles/container-engine/cri-o/templates/config.json.j2
@@ -1,5 +1,5 @@
 {% if crio_registry_auth is defined and crio_registry_auth|length %}
-{ 
+{
 {% for reg in crio_registry_auth %}
   "auths": {
     "{{ reg.registry }}": {
diff --git a/roles/container-engine/docker/templates/docker-dns.conf.j2 b/roles/container-engine/docker/templates/docker-dns.conf.j2
index d501a19c07e17854accc9b2312d7d455bd79a4b8..01dbd3b20b973782c46cf1b2e674921f86acfabb 100644
--- a/roles/container-engine/docker/templates/docker-dns.conf.j2
+++ b/roles/container-engine/docker/templates/docker-dns.conf.j2
@@ -3,4 +3,4 @@ Environment="DOCKER_DNS_OPTIONS=\
     {% for d in docker_dns_servers %}--dns {{ d }} {% endfor %} \
     {% for d in docker_dns_search_domains %}--dns-search {{ d }} {% endfor %} \
     {% for o in docker_dns_options %}--dns-opt {{ o }} {% endfor %} \
-"
\ No newline at end of file
+"
diff --git a/roles/container-engine/docker/templates/docker-orphan-cleanup.conf.j2 b/roles/container-engine/docker/templates/docker-orphan-cleanup.conf.j2
index 787a941ed77576f58ee2fe4299ac8a9672e92ef6..370f1e71ae360fa0bc7130802ebd4998d7f86a97 100644
--- a/roles/container-engine/docker/templates/docker-orphan-cleanup.conf.j2
+++ b/roles/container-engine/docker/templates/docker-orphan-cleanup.conf.j2
@@ -1,2 +1,2 @@
 [Service]
-ExecStartPost=-{{ bin_dir }}/cleanup-docker-orphans.sh
\ No newline at end of file
+ExecStartPost=-{{ bin_dir }}/cleanup-docker-orphans.sh
diff --git a/roles/container-engine/kata-containers/templates/configuration-qemu.toml.j2 b/roles/container-engine/kata-containers/templates/configuration-qemu.toml.j2
index 40382423d3e0c45a5e22e4ff539cda02fcd32fa7..9e89deedabe8956de3d2dfa6cc35caf76b8cf009 100644
--- a/roles/container-engine/kata-containers/templates/configuration-qemu.toml.j2
+++ b/roles/container-engine/kata-containers/templates/configuration-qemu.toml.j2
@@ -375,7 +375,7 @@ valid_entropy_sources = ["/dev/urandom","/dev/random",""]
 # When enable_guest_swap is enabled, insert a raw file to the guest as the swap device
 # if the swappiness of a container (set by annotation "io.katacontainers.container.resource.swappiness")
 # is bigger than 0.
-# The size of the swap device should be 
+# The size of the swap device should be
 # swap_in_bytes (set by annotation "io.katacontainers.container.resource.swap_in_bytes") - memory_limit_in_bytes.
 # If swap_in_bytes is not set, the size should be memory_limit_in_bytes.
 # If swap_in_bytes and memory_limit_in_bytes is not set, the size should
diff --git a/roles/etcd/templates/etcd.env.j2 b/roles/etcd/templates/etcd.env.j2
index 18395c9b6cb9b84fcff1377cc22f33bd1eb28b54..c3013f679323ae732230db122a9bff78c30f8e78 100644
--- a/roles/etcd/templates/etcd.env.j2
+++ b/roles/etcd/templates/etcd.env.j2
@@ -65,4 +65,4 @@ ETCDCTL_CERT={{ etcd_cert_dir }}/admin-{{ inventory_hostname }}.pem
 
 # ETCD 3.5.x issue
 # https://groups.google.com/a/kubernetes.io/g/dev/c/B7gJs88XtQc/m/rSgNOzV2BwAJ?utm_medium=email&utm_source=footer
-ETCD_EXPERIMENTAL_INITIAL_CORRUPT_CHECK={{ etcd_experimental_initial_corrupt_check }}
\ No newline at end of file
+ETCD_EXPERIMENTAL_INITIAL_CORRUPT_CHECK={{ etcd_experimental_initial_corrupt_check }}
diff --git a/roles/kubernetes-apps/cloud_controller/oci/templates/controller-manager-config.yml.j2 b/roles/kubernetes-apps/cloud_controller/oci/templates/controller-manager-config.yml.j2
index b8dcc60fa5b6fdfcc09162a4c82c02a92cf477fe..de7709354aa9c1689adeb14f63d38c93c8a617ae 100644
--- a/roles/kubernetes-apps/cloud_controller/oci/templates/controller-manager-config.yml.j2
+++ b/roles/kubernetes-apps/cloud_controller/oci/templates/controller-manager-config.yml.j2
@@ -87,4 +87,3 @@ rateLimiter:
   rateLimitBucketWrite: {{ oci_rate_limit.rate_limit_bucket_write }}
 {% endif %}
 {% endif %}
-
diff --git a/roles/kubernetes-apps/cloud_controller/oci/templates/oci-cloud-provider.yml.j2 b/roles/kubernetes-apps/cloud_controller/oci/templates/oci-cloud-provider.yml.j2
index bacd1e95c6c760efbc9c9c13ce277c019722ed20..d50f1393faf31881bb045d3a4df312efeb30b055 100644
--- a/roles/kubernetes-apps/cloud_controller/oci/templates/oci-cloud-provider.yml.j2
+++ b/roles/kubernetes-apps/cloud_controller/oci/templates/oci-cloud-provider.yml.j2
@@ -70,4 +70,3 @@ spec:
             - name: kubernetes
               mountPath: /etc/kubernetes
               readOnly: true
-
diff --git a/roles/kubernetes-apps/csi_driver/aws_ebs/templates/aws-ebs-csi-controllerservice.yml.j2 b/roles/kubernetes-apps/csi_driver/aws_ebs/templates/aws-ebs-csi-controllerservice.yml.j2
index ffce40bd84b89b5c1685177795d65aecdabeeb6c..d58490aebad0166bd5079ef46561de3b360ba6fc 100644
--- a/roles/kubernetes-apps/csi_driver/aws_ebs/templates/aws-ebs-csi-controllerservice.yml.j2
+++ b/roles/kubernetes-apps/csi_driver/aws_ebs/templates/aws-ebs-csi-controllerservice.yml.j2
@@ -129,4 +129,3 @@ spec:
       volumes:
         - name: socket-dir
           emptyDir: {}
-
diff --git a/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-cloud-config.j2 b/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-cloud-config.j2
index 1a83f7dbd95114faa54af5f558c89bf31d3d5b40..04d0c68abf4d644b4299e6fe378f0428160058a0 100644
--- a/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-cloud-config.j2
+++ b/roles/kubernetes-apps/csi_driver/cinder/templates/cinder-csi-cloud-config.j2
@@ -41,4 +41,4 @@ node-volume-attach-limit="{{ node_volume_attach_limit }}"
 {% endif %}
 {% if cinder_csi_rescan_on_resize is defined %}
 rescan-on-resize={{ cinder_csi_rescan_on_resize | bool }}
-{% endif %}
\ No newline at end of file
+{% endif %}
diff --git a/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml b/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml
index 657b3006dfb8cb2bf5a6efad0b2c7eca419bb465..0f9eac4713435f4b7020249d076277292062863a 100644
--- a/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml
+++ b/roles/kubernetes-apps/csi_driver/upcloud/defaults/main.yml
@@ -13,4 +13,4 @@ upcloud_csi_snapshot_controller_replicas: 2
 upcloud_csi_snapshotter_image_tag: "v4.2.1"
 upcloud_csi_snapshot_controller_image_tag: "v4.2.1"
 upcloud_csi_snapshot_validation_webhook_image_tag: "v4.2.1"
-upcloud_cacert: "{{ lookup('env','OS_CACERT') }}"
\ No newline at end of file
+upcloud_cacert: "{{ lookup('env','OS_CACERT') }}"
diff --git a/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml b/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml
index f37daba92f3dbc02e33173d835b21b534d840d40..63e37bcf5f0cedc24525440310a20fb7a684bce2 100644
--- a/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml
+++ b/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml
@@ -37,4 +37,4 @@
     - inventory_hostname == groups['kube_control_plane'][0]
     - not item is skipped
   loop_control:
-    label: "{{ item.item.file }}"
\ No newline at end of file
+    label: "{{ item.item.file }}"
diff --git a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2 b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2
index 0d52837a968e708b2c7eb39674e28a0737a9b9e3..1b8519dfa5e89b4d6d37b6dc55600c02d2b3e2de 100644
--- a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2
+++ b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-controller.yml.j2
@@ -90,4 +90,4 @@ spec:
         - name: regcred
       volumes:
         - name: socket-dir
-          emptyDir: {}
\ No newline at end of file
+          emptyDir: {}
diff --git a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-driver.yml.j2 b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-driver.yml.j2
index 363394a21945fd7a5d0e0508b344b170bd01ef75..8f4c61224f01f0ca7cce7eb0445b78632d90c8ea 100644
--- a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-driver.yml.j2
+++ b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-driver.yml.j2
@@ -5,4 +5,4 @@ metadata:
 spec:
   attachRequired: true
   podInfoOnMount: true
-  fsGroupPolicy: File
\ No newline at end of file
+  fsGroupPolicy: File
diff --git a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2 b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2
index 7173c6baf8eb2a6a4fa557102fe06af8a86a0c4e..7ed39be4705d46daa24c645cabe46957c95f1212 100644
--- a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2
+++ b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-node.yml.j2
@@ -98,4 +98,4 @@ spec:
 {% if upcloud_tolerations %}
       tolerations:
         {{ upcloud_tolerations | to_nice_yaml(indent=2) | indent(width=8) }}
-{% endif %}
\ No newline at end of file
+{% endif %}
diff --git a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2 b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2
index 3bc0bd580644ed3fd33704987ad4dce191a9ac9b..5af71d2fba14844150daf97e3a7128bfec80ce7f 100644
--- a/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2
+++ b/roles/kubernetes-apps/csi_driver/upcloud/templates/upcloud-csi-setup.yml.j2
@@ -182,4 +182,4 @@ subjects:
 roleRef:
   kind: ClusterRole
   name: csi-upcloud-resizer-role
-  apiGroup: rbac.authorization.k8s.io
\ No newline at end of file
+  apiGroup: rbac.authorization.k8s.io
diff --git a/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-namespace.yml.j2 b/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-namespace.yml.j2
index 0a28bda12c5ea09ff358977f9f774246aebc9336..6cf31509ae37ca6643871cb5e1b196dbfd9b685f 100644
--- a/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-namespace.yml.j2
+++ b/roles/kubernetes-apps/csi_driver/vsphere/templates/vsphere-csi-namespace.yml.j2
@@ -1,4 +1,4 @@
 apiVersion: v1
 kind: Namespace
 metadata:
-  name: "{{ vsphere_csi_namespace }}"
\ No newline at end of file
+  name: "{{ vsphere_csi_namespace }}"
diff --git a/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/OWNERS b/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/OWNERS
index e8c0fcc26a507c6e0bca2820d6fda4c88d54ca24..a80e724274aaf21198cb7bd3056cf102cd700954 100644
--- a/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/OWNERS
+++ b/roles/kubernetes-apps/ingress_controller/alb_ingress_controller/OWNERS
@@ -3,4 +3,4 @@
 approvers:
   - kubespray-approvers
 reviewers:
-  - kubespray-reviewers
\ No newline at end of file
+  - kubespray-reviewers
diff --git a/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml b/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml
index 10cf1a7fca2614f99862bab5b586e7056d054a9a..16dfe9a46037bfe9f33c25a85ee4a73c59ede713 100644
--- a/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml
+++ b/roles/kubernetes-apps/ingress_controller/ingress_nginx/defaults/main.yml
@@ -17,4 +17,4 @@ ingress_nginx_termination_grace_period_seconds: 300
 ingress_nginx_webhook_enabled: false
 ingress_nginx_webhook_job_ttl: 1800
 
-ingress_nginx_probe_initial_delay_seconds: 10
\ No newline at end of file
+ingress_nginx_probe_initial_delay_seconds: 10
diff --git a/roles/kubernetes-apps/metrics_server/defaults/main.yml b/roles/kubernetes-apps/metrics_server/defaults/main.yml
index 4e247a166b9ac0dc08abaa9c452054eac1c421f2..548cf0ee826d120396ada509420e52e2b1443c50 100644
--- a/roles/kubernetes-apps/metrics_server/defaults/main.yml
+++ b/roles/kubernetes-apps/metrics_server/defaults/main.yml
@@ -8,4 +8,4 @@ metrics_server_limits_memory: 200Mi
 metrics_server_requests_cpu: 100m
 metrics_server_requests_memory: 200Mi
 metrics_server_host_network: false
-metrics_server_replicas: 1
\ No newline at end of file
+metrics_server_replicas: 1
diff --git a/roles/kubernetes-apps/metrics_server/templates/metrics-server-deployment.yaml.j2 b/roles/kubernetes-apps/metrics_server/templates/metrics-server-deployment.yaml.j2
index 86247b9e144313d7c31dfc8193a2c7c1be283baa..d44dc8f5e43c6d813042c18e3062705e80f30c29 100644
--- a/roles/kubernetes-apps/metrics_server/templates/metrics-server-deployment.yaml.j2
+++ b/roles/kubernetes-apps/metrics_server/templates/metrics-server-deployment.yaml.j2
@@ -104,4 +104,4 @@ spec:
                   - metrics-server
               topologyKey: kubernetes.io/hostname
               namespaces:
-              - kube-system
\ No newline at end of file
+              - kube-system
diff --git a/roles/kubernetes-apps/network_plugin/kube-router/OWNERS b/roles/kubernetes-apps/network_plugin/kube-router/OWNERS
index c95aad2e35d9309a67612553a5fdc4c9a9359b9f..c40af3c30cea7ab163b94eb4c7dec362c88e8174 100644
--- a/roles/kubernetes-apps/network_plugin/kube-router/OWNERS
+++ b/roles/kubernetes-apps/network_plugin/kube-router/OWNERS
@@ -3,4 +3,4 @@
 approvers:
   - bozzo
 reviewers:
-  - bozzo
\ No newline at end of file
+  - bozzo
diff --git a/roles/kubernetes-apps/persistent_volumes/meta/main.yml b/roles/kubernetes-apps/persistent_volumes/meta/main.yml
index fdfd80778bdd6d5f180807e364e56f635e78ff6a..e3066bb62a971e6893bed91582a0f988e8fe0222 100644
--- a/roles/kubernetes-apps/persistent_volumes/meta/main.yml
+++ b/roles/kubernetes-apps/persistent_volumes/meta/main.yml
@@ -40,4 +40,4 @@ dependencies:
       - upcloud_csi_enabled
     tags:
       - persistent_volumes_upcloud_csi
-      - upcloud-csi-driver
\ No newline at end of file
+      - upcloud-csi-driver
diff --git a/roles/kubernetes/control-plane/tasks/psp-install.yml b/roles/kubernetes/control-plane/tasks/psp-install.yml
index 581d1286df25500c29b148e1520be9678899f2c9..4a990f82a62272e79cf3724e59d293fdbf379a75 100644
--- a/roles/kubernetes/control-plane/tasks/psp-install.yml
+++ b/roles/kubernetes/control-plane/tasks/psp-install.yml
@@ -35,4 +35,4 @@
   environment:
     KUBECONFIG: "{{ kube_config_dir }}/admin.conf"
   loop_control:
-    label: "{{ item.item.file }}"
\ No newline at end of file
+    label: "{{ item.item.file }}"
diff --git a/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2 b/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2
index b4b3c5ecc04762e53d1724e9e58c21c9e80d6a4f..78e399d5f9af946779b87650b0444e709b8cb9d5 100644
--- a/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2
+++ b/roles/kubernetes/control-plane/templates/kubeadm-controlplane.v1beta3.yaml.j2
@@ -31,4 +31,4 @@ nodeRegistration:
 {% if kubeadm_patches is defined and kubeadm_patches.enabled %}
 patches:
   directory: {{ kubeadm_patches.dest_dir }}
-{% endif %}
\ No newline at end of file
+{% endif %}
diff --git a/roles/kubernetes/node/templates/cloud-configs/gce-cloud-config.j2 b/roles/kubernetes/node/templates/cloud-configs/gce-cloud-config.j2
index f4cac50f314826b2f001bbc8185a876f71115891..399512677951497b9ca56db1c87c3202daa1a06b 100644
--- a/roles/kubernetes/node/templates/cloud-configs/gce-cloud-config.j2
+++ b/roles/kubernetes/node/templates/cloud-configs/gce-cloud-config.j2
@@ -1,3 +1,2 @@
 [global]
-node-tags = {{ gce_node_tags }} 
-
+node-tags = {{ gce_node_tags }}
diff --git a/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2 b/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2
index 3de8b8aec5b4cba8fb894cd4ad78a57f36d81e0b..1ed5f492a9f2e8ed9c269a6c3b5bfe1aa5e56f57 100644
--- a/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2
+++ b/roles/kubernetes/node/templates/manifests/kube-vip.manifest.j2
@@ -94,4 +94,3 @@ spec:
       path: /etc/kubernetes/admin.conf
     name: kubeconfig
 status: {}
-
diff --git a/roles/network_plugin/canal/templates/canal-config.yaml.j2 b/roles/network_plugin/canal/templates/canal-config.yaml.j2
index 8aab6fb75664437fc71c7be6f34f4d81884ad244..81f7f5de8ae00b5173448229465ebe2a5d60cf0e 100644
--- a/roles/network_plugin/canal/templates/canal-config.yaml.j2
+++ b/roles/network_plugin/canal/templates/canal-config.yaml.j2
@@ -77,4 +77,3 @@ data:
         "Type": "vxlan"
       }
     }
-
diff --git a/roles/network_plugin/cilium/templates/cilium/secret.yml.j2 b/roles/network_plugin/cilium/templates/cilium/secret.yml.j2
index a5fcc56eba38a83f90733c6b217ee735f094851b..776c6893800d44183b200e52c5c05214c5fc0ca0 100644
--- a/roles/network_plugin/cilium/templates/cilium/secret.yml.j2
+++ b/roles/network_plugin/cilium/templates/cilium/secret.yml.j2
@@ -6,4 +6,4 @@ kind: Secret
 metadata:
   name: cilium-ipsec-keys
   namespace: kube-system
-type: Opaque
\ No newline at end of file
+type: Opaque
diff --git a/roles/network_plugin/kube-router/OWNERS b/roles/network_plugin/kube-router/OWNERS
index c95aad2e35d9309a67612553a5fdc4c9a9359b9f..c40af3c30cea7ab163b94eb4c7dec362c88e8174 100644
--- a/roles/network_plugin/kube-router/OWNERS
+++ b/roles/network_plugin/kube-router/OWNERS
@@ -3,4 +3,4 @@
 approvers:
   - bozzo
 reviewers:
-  - bozzo
\ No newline at end of file
+  - bozzo
diff --git a/roles/network_plugin/macvlan/files/ifdown-macvlan b/roles/network_plugin/macvlan/files/ifdown-macvlan
index 4d26db5af6683515070748c3cf98776430d0772b..b79b9c11ec8d32889a0b2ab8f1633c89f836018f 100755
--- a/roles/network_plugin/macvlan/files/ifdown-macvlan
+++ b/roles/network_plugin/macvlan/files/ifdown-macvlan
@@ -38,4 +38,3 @@ fi
 ${OTHERSCRIPT} ${CONFIG}
 
 ip link del ${DEVICE} type ${TYPE:-macvlan}
-
diff --git a/roles/network_plugin/macvlan/files/ifup-macvlan b/roles/network_plugin/macvlan/files/ifup-macvlan
index 8dc61aad23a69876a5d17f89aef3d67159ce1a05..97daec0c4d3f48baf2eef34316e4d5f2be8ff5b3 100755
--- a/roles/network_plugin/macvlan/files/ifup-macvlan
+++ b/roles/network_plugin/macvlan/files/ifup-macvlan
@@ -41,4 +41,3 @@ ip link add \
 	type ${TYPE:-macvlan} mode ${MACVLAN_MODE:-private}
 
 ${OTHERSCRIPT} ${CONFIG}
-
diff --git a/roles/network_plugin/macvlan/templates/centos-network-macvlan.cfg.j2 b/roles/network_plugin/macvlan/templates/centos-network-macvlan.cfg.j2
index e7bad788e6a9c149e274e789ca38c6b491bad948..a7431c8b400503aac7c56e036400b4a073314c9c 100644
--- a/roles/network_plugin/macvlan/templates/centos-network-macvlan.cfg.j2
+++ b/roles/network_plugin/macvlan/templates/centos-network-macvlan.cfg.j2
@@ -11,4 +11,3 @@ MACVLAN_MODE=bridge
 IPADDR={{ node_pod_cidr|ipaddr('net')|ipaddr(1)|ipaddr('address') }}
 NETMASK={{ node_pod_cidr|ipaddr('netmask') }}
 NETWORK={{ node_pod_cidr|ipaddr('network') }}
-
diff --git a/roles/network_plugin/macvlan/templates/centos-postdown-macvlan.cfg.j2 b/roles/network_plugin/macvlan/templates/centos-postdown-macvlan.cfg.j2
index f3edd99b96007c9b55dc35caa0e5072089064161..d62ac2e7dc5e32785cfd3ef4405b502b251e678f 100644
--- a/roles/network_plugin/macvlan/templates/centos-postdown-macvlan.cfg.j2
+++ b/roles/network_plugin/macvlan/templates/centos-postdown-macvlan.cfg.j2
@@ -1,4 +1,3 @@
 {% if enable_nat_default_gateway %}
 iptables -t nat -D POSTROUTING -s {{ node_pod_cidr|ipaddr('net') }} -o {{ node_default_gateway_interface }} -j MASQUERADE
 {% endif %}
-
diff --git a/roles/network_plugin/macvlan/templates/centos-postup-macvlan.cfg.j2 b/roles/network_plugin/macvlan/templates/centos-postup-macvlan.cfg.j2
index 35cd5b5426bb81ef98f96c1b293ba7d4a1637c05..340bf7257378cab467ebefd88bbc36aa75316c44 100644
--- a/roles/network_plugin/macvlan/templates/centos-postup-macvlan.cfg.j2
+++ b/roles/network_plugin/macvlan/templates/centos-postup-macvlan.cfg.j2
@@ -1,4 +1,3 @@
 {% if enable_nat_default_gateway %}
 iptables -t nat -I POSTROUTING -s {{ node_pod_cidr|ipaddr('net') }} -o {{ node_default_gateway_interface }} -j MASQUERADE
 {% endif %}
-
diff --git a/roles/network_plugin/macvlan/templates/coreos-network-macvlan.cfg.j2 b/roles/network_plugin/macvlan/templates/coreos-network-macvlan.cfg.j2
index 696eba50110769e8629818c3e9be1589a86db048..ac67389892127a4dbbfd4d545f7d9c048576d291 100644
--- a/roles/network_plugin/macvlan/templates/coreos-network-macvlan.cfg.j2
+++ b/roles/network_plugin/macvlan/templates/coreos-network-macvlan.cfg.j2
@@ -15,4 +15,3 @@ GatewayOnlink=yes
 {% endif %}
 {% endif %}
 {% endfor %}
-
diff --git a/roles/network_plugin/macvlan/templates/debian-network-macvlan.cfg.j2 b/roles/network_plugin/macvlan/templates/debian-network-macvlan.cfg.j2
index 9edd6d1577d4548bf966f64f83b0a03edceedbda..3b3e2e4ca2ccf0e9f4f32260d827e8d2e1ad2dfe 100644
--- a/roles/network_plugin/macvlan/templates/debian-network-macvlan.cfg.j2
+++ b/roles/network_plugin/macvlan/templates/debian-network-macvlan.cfg.j2
@@ -24,4 +24,3 @@ iface mac0 inet static
 {% endfor %}
     post-down iptables -t nat -D POSTROUTING -s {{ node_pod_cidr|ipaddr('net') }} -o {{ node_default_gateway_interface }} -j MASQUERADE
     post-down ip link delete mac0
-
diff --git a/roles/network_plugin/weave/templates/weave-net.yml.j2 b/roles/network_plugin/weave/templates/weave-net.yml.j2
index 84c4fa0dad81a8e961bccf7d165248b96164a561..3a3886510aca8b1f08bef8e9cd539823ec5c5c91 100644
--- a/roles/network_plugin/weave/templates/weave-net.yml.j2
+++ b/roles/network_plugin/weave/templates/weave-net.yml.j2
@@ -233,7 +233,7 @@ items:
 {% if weave_npc_extra_args %}
                 - name: EXTRA_ARGS
                   value: "{{ weave_npc_extra_args }}"
-{% endif %}                       
+{% endif %}
               image: {{ weave_npc_image_repo }}:{{ weave_npc_image_tag }}
               imagePullPolicy: {{ k8s_image_pull_policy }}
               resources:
diff --git a/run.rc b/run.rc
new file mode 100644
index 0000000000000000000000000000000000000000..f87ad4e0d8167bc38869d7f766dba344fd7908d0
--- /dev/null
+++ b/run.rc
@@ -0,0 +1,45 @@
+# use virtualenv to install all python requirements
+VENVDIR=venv
+python3 -m venv $VENVDIR
+source $VENVDIR/bin/activate
+pip install --upgrade pip
+pip install wheel
+pip install --upgrade setuptools
+pip install -r requirements.txt
+pip install -r tests/requirements.txt
+pre-commit install
+# prepare an inventory to test with
+INV=inventory/lab
+rm -rf ${INV}.bak &> /dev/null
+mv ${INV} ${INV}.bak &> /dev/null
+cp -a inventory/sample ${INV}
+rm -f ${INV}/hosts.ini
+
+# customize the vagrant environment
+mkdir vagrant
+cat << EOF > vagrant/config.rb
+\$instance_name_prefix = kub"
+\$vm_cpus = 2
+\$num_instances = 3
+\$os = "almalinux8"
+\$subnet = "192.168.56"
+\$network_plugin = "calico"
+\$inventory = "$INV"
+\$shared_folders = { 'temp/docker_rpms' => "/var/cache/yum/x86_64/7/docker-ce/packages" }
+EOF
+
+# make the rpm cache
+mkdir -p temp/docker_rpms
+
+vagrant up
+
+# make a copy of the downloaded docker rpm, to speed up the next provisioning run
+scp kub-1:/var/cache/yum/x86_64/7/docker-ce/packages/* temp/docker_rpms/
+
+# copy kubectl access configuration in place
+mkdir $HOME/.kube/ &> /dev/null
+ln -s $PWD/$INV/artifacts/admin.conf $HOME/.kube/config
+# make the kubectl binary available
+sudo ln -s $PWD/$INV/artifacts/kubectl /usr/local/bin/kubectl
+#or
+export PATH=$PATH:$PWD/$INV/artifacts
diff --git a/tests/files/vagrant_ubuntu18-flannel.rb b/tests/files/vagrant_ubuntu18-flannel.rb
index 25b86904c31e6696b16347935265fd016c559cc9..ce942edbb014f3632073d37ee08493a539a5144d 100644
--- a/tests/files/vagrant_ubuntu18-flannel.rb
+++ b/tests/files/vagrant_ubuntu18-flannel.rb
@@ -4,4 +4,4 @@ $libvirt_volume_cache = "unsafe"
 # Checking for box update can trigger API rate limiting
 # https://www.vagrantup.com/docs/vagrant-cloud/request-limits.html
 $box_check_update = false
-$vm_cpus = 2
\ No newline at end of file
+$vm_cpus = 2
diff --git a/tests/files/vagrant_ubuntu20-flannel.rb b/tests/files/vagrant_ubuntu20-flannel.rb
index c739f58a2aba8ee87a89a2d481b5ec6630a07cfd..55daa19e3eb084297a46df3edf63e01c89631b96 100644
--- a/tests/files/vagrant_ubuntu20-flannel.rb
+++ b/tests/files/vagrant_ubuntu20-flannel.rb
@@ -6,4 +6,4 @@ $libvirt_volume_cache = "unsafe"
 # Checking for box update can trigger API rate limiting
 # https://www.vagrantup.com/docs/vagrant-cloud/request-limits.html
 $box_check_update = false
-$vm_cpus = 2
\ No newline at end of file
+$vm_cpus = 2
diff --git a/tests/requirements-2.11.txt b/tests/requirements-2.11.txt
index d3241516be8eec43b5dfa82e3f614f60886b9b9a..4b2c06004aa887809190a644aa4122c2dbd5558b 100644
--- a/tests/requirements-2.11.txt
+++ b/tests/requirements-2.11.txt
@@ -1,11 +1,11 @@
 -r ../requirements-2.11.txt
-yamllint==1.19.0
+ansible-lint==5.4.0
 apache-libcloud==2.2.1
-tox==3.11.1
+ara[server]==1.6.1
 dopy==0.3.7
-ansible-lint==5.4.0
 molecule==3.0.6
 molecule-vagrant==0.3
-testinfra==5.2.2
 python-vagrant==0.5.15
-ara[server]==1.6.1
+testinfra==5.2.2
+tox==3.11.1
+yamllint==1.19.0
diff --git a/tests/requirements-2.12.txt b/tests/requirements-2.12.txt
index 2fb47e1abcf28a376b70c1c93a11857c1a182241..6b0d6220bf964aa63b91064d1778293f57e4201c 100644
--- a/tests/requirements-2.12.txt
+++ b/tests/requirements-2.12.txt
@@ -1,11 +1,11 @@
 -r ../requirements-2.12.txt
-yamllint==1.19.0
+ansible-lint==5.4.0
 apache-libcloud==2.2.1
-tox==3.11.1
+ara[server]==1.6.1
 dopy==0.3.7
-ansible-lint==5.4.0
 molecule==3.0.6
 molecule-vagrant==0.3
-testinfra==5.2.2
 python-vagrant==0.5.15
-ara[server]==1.6.1
+testinfra==5.2.2
+tox==3.11.1
+yamllint==1.19.0
diff --git a/tests/scripts/md-table/requirements.txt b/tests/scripts/md-table/requirements.txt
index ecf5aac53a7c9dcf993bda6de344fc303936b126..6d4aca36aa541c9dd7154be2e0c6fb09e7437c59 100644
--- a/tests/scripts/md-table/requirements.txt
+++ b/tests/scripts/md-table/requirements.txt
@@ -1,4 +1,4 @@
-pyaml
 jinja2
 pathlib ; python_version < '3.10'
+pyaml
 pydblite
diff --git a/tests/scripts/md-table/table.md.j2 b/tests/scripts/md-table/table.md.j2
index 7e8f4cae14dc5dcbbc75230883a9ae4680eeaacb..c5cf37d017503fb5849fc18bbef360df7e43ce6c 100644
--- a/tests/scripts/md-table/table.md.j2
+++ b/tests/scripts/md-table/table.md.j2
@@ -1,6 +1,6 @@
 # CI test coverage
 
-To generate this Matrix run `./tests/scripts/md-table/main.py` 
+To generate this Matrix run `./tests/scripts/md-table/main.py`
 
 {%- for container_engine in container_engines %}
 
@@ -12,4 +12,4 @@ To generate this Matrix run `./tests/scripts/md-table/main.py`
 {{ os }} | {% for cni in network_plugins %} {{ ':white_check_mark:' if exists(container_engine, cni, os) else ':x:' }} |{% endfor %}
 {%- endfor %}
 
-{%- endfor %}
\ No newline at end of file
+{%- endfor %}
diff --git a/tests/scripts/md-table/test.sh b/tests/scripts/md-table/test.sh
index 3c2e5817424aed0fe66daf8420348df6e2b4af83..46daa6384696fedaedb9e1c2ce35f67b60e810d3 100755
--- a/tests/scripts/md-table/test.sh
+++ b/tests/scripts/md-table/test.sh
@@ -8,4 +8,4 @@ echo "Generate current file..."
 ./tests/scripts/md-table/main.py > tmp.md
 
 echo "Compare docs/ci.md with actual tests in tests/files/*.yml ..."
-cmp docs/ci.md tmp.md
\ No newline at end of file
+cmp docs/ci.md tmp.md
diff --git a/tests/scripts/vagrant_clean.sh b/tests/scripts/vagrant_clean.sh
index b0488183640d6e5f53396e052d0eb9a18403d8e0..5a44956e2473243256e4af77cecc13043853b174 100755
--- a/tests/scripts/vagrant_clean.sh
+++ b/tests/scripts/vagrant_clean.sh
@@ -16,4 +16,4 @@ done
 for i in $(virsh vol-list default|grep \.img |grep -v VAGRANTSLASH | cut -f 2 -d ' ')
 do
     virsh vol-delete "$i" --pool default
-done
\ No newline at end of file
+done