diff --git a/changelog/2.26.0.md b/changelog/2.26.0.md
new file mode 100644
index 00000000..670f5272
--- /dev/null
+++ b/changelog/2.26.0.md
@@ -0,0 +1,44 @@
+# v2.26.0-ck8s1
+
+Released 2024-11-08
+
+## Changes by kind
+
+### Feature(s)
+
+- [#379](https://github.com/elastisys/compliantkubernetes-kubespray/pull/379) - Upgrade kubespray to include support for upcloud router @Xartos
+
+### Improvement(s)
+
+- [#382](https://github.com/elastisys/compliantkubernetes-kubespray/pull/382) - Pg/config for snapshot controller @Pavan-Gunda
+- [#387](https://github.com/elastisys/compliantkubernetes-kubespray/pull/387) - Only run lb legacy network migration script on upcloud environments @Ajarmar
+- [#398](https://github.com/elastisys/compliantkubernetes-kubespray/pull/398) - ansible: add support for bastion hosts when running authorized_key @davidumea
+
+### Other(s)
+
+- [7e5c199](https://github.com/elastisys/compliantkubernetes-kubespray/commit/7e5c199d2419236ee4ffcf99a3710e02f6638dc8) - Updated Kubespray fork to v2.26.0-ck8s1 @davidumea
+ - Default Kubernetes version upgraded to `v1.30.4`.
+- [c13cc10](https://github.com/elastisys/compliantkubernetes-kubespray/commit/c13cc10528b8b46cf2caf97122a180a647d069ab) - Added migration document for v2.26 @davidumea
+- [#372](https://github.com/elastisys/compliantkubernetes-kubespray/pull/372) - clean-up: Remove some Infra Providers from release template issue @lucianvlad
+- [#373](https://github.com/elastisys/compliantkubernetes-kubespray/pull/373) - clean-up: Lucian/remove some Infra Providers from the release template @lucianvlad
+- [#374](https://github.com/elastisys/compliantkubernetes-kubespray/pull/374) - other: Port 2.25.0 ck8s1 @anders-elastisys
+- [#384](https://github.com/elastisys/compliantkubernetes-kubespray/pull/384) - bug: kubespray: Added LB legacy network fix and added ipsec properties @Xartos
+- [#386](https://github.com/elastisys/compliantkubernetes-kubespray/pull/386) - documentation: docs: Update migration guide with missing export command for variable @lucianvlad
+- [#388](https://github.com/elastisys/compliantkubernetes-kubespray/pull/388) - documentation: Merge v2.25 patch changelogs to main @Xartos
+- [#390](https://github.com/elastisys/compliantkubernetes-kubespray/pull/390) - other: Port 2.25.0 ck8s4 @Ajarmar
+- [#391](https://github.com/elastisys/compliantkubernetes-kubespray/pull/391) - documentation: docs: skip calico config for v2.25.0-ck8s4 @Ajarmar
+- [#393](https://github.com/elastisys/compliantkubernetes-kubespray/pull/393) - bug: rook-ceph: fix alerts @lunkan93
+- [#395](https://github.com/elastisys/compliantkubernetes-kubespray/pull/395) - documentation: docs: updated fork process @Eliastisys
+- [#396](https://github.com/elastisys/compliantkubernetes-kubespray/pull/396) - clean-up: rook-ceph: remove ceph node packet drops alert @lunkan93
+- [#397](https://github.com/elastisys/compliantkubernetes-kubespray/pull/397) - other: all: add codeowners @viktor-f
+
+### Kubespray changes
+
+- [v2.26.0](https://github.com/kubernetes-sigs/kubespray/releases/tag/v2.26.0) - Upstream release notes for Kubespray v2.26.0
+- [fb950e8](https://github.com/elastisys/kubespray/commit/fb950e8a58cfa164e2cbb1000d9af454cd274ace) - Add support for ntpsec @davidumea
+- [9302e36](https://github.com/elastisys/kubespray/commit/9302e36f8548c3ef613e70ba2b36ccf67f41bd90) - Add support to use existing fips with terraform openstack @anders-elastisys
+- [7ee926a](https://github.com/elastisys/kubespray/commit/7ee926a696186a41eb5e2a1bf8ca3cb80011b107) - terraform upcloud: Added possibility to set up nodes with only private IPs @Xartos
+- [9e522af](https://github.com/elastisys/kubespray/commit/9e522affc281fddee740386a2d49724fe7a5d13a) - terraform upcloud: add support for gateway in private zone @davidumea
+- [4ecbee6](https://github.com/elastisys/kubespray/commit/4ecbee6c0f245a6ba0fb33eba36bfd97e5211c14) - terraform upcloud: split LB proxy protocol config per backend @davidumea
+- [d40faef](https://github.com/elastisys/kubespray/commit/d40faef54f47ff26442ff271e6ec01b251d948d9) - terraform upcloud: fix flexible plans @davidumea
+- [4113920](https://github.com/elastisys/kubespray/commit/4113920ad99e7f1853c3c215534375bd43766b45) - upcloud: encrypted at rest volumes @robinAwallace
diff --git a/kubespray b/kubespray
index 4c9a772a..4113920a 160000
--- a/kubespray
+++ b/kubespray
@@ -1 +1 @@
-Subproject commit 4c9a772aa77f82a9b7552abec8be8dcf486f6554
+Subproject commit 4113920ad99e7f1853c3c215534375bd43766b45
diff --git a/migration/v2.26/README.md b/migration/v2.26/README.md
new file mode 100644
index 00000000..a67bc893
--- /dev/null
+++ b/migration/v2.26/README.md
@@ -0,0 +1,125 @@
+# Upgrade v2.25 to v2.26
+
+## Prerequisites
+
+- [ ] Notify the users (if any) before the upgrade starts;
+- [ ] Check if there are any pending changes to the environment;
+- [ ] Check the state of the environment, pods, nodes and backup jobs:
+
+ ```bash
+ ./compliantkubernetes-apps/bin/ck8s test sc|wc
+ ./compliantkubernetes-apps/bin/ck8s ops kubectl sc|wc get pods -A -o custom-columns=NAMESPACE:metadata.namespace,POD:metadata.name,READY-false:status.containerStatuses[*].ready,REASON:status.containerStatuses[*].state.terminated.reason | grep false | grep -v Completed
+ ./compliantkubernetes-apps/bin/ck8s ops kubectl sc|wc get nodes
+ ./compliantkubernetes-apps/bin/ck8s ops kubectl sc|wc get jobs -A
+ velero get backup
+ ```
+
+- [ ] Silence the notifications for the alerts. e.g you can use [alertmanager silences](https://prometheus.io/docs/alerting/latest/alertmanager/#silences);
+
+## Steps that can be done before the upgrade - non-disruptive
+
+1. Checkout the new release: `git switch -d v2.26.x-ck8sx`
+
+1. Switch to the correct remote: `git submodule sync`
+
+1. Update the kubespray submodule: `git submodule update --init --recursive`
+
+1. Run `bin/ck8s-kubespray upgrade both v2.26 prepare` to update your config.
+
+ > [!NOTE]
+ > It is possible to update `wc` and `sc` config separately by replacing `both` when running the `upgrade` command, e.g. the following will only update config for the workload cluster:
+ >
+ > ```bash
+ > bin/ck8s-kubespray upgrade wc v2.26 prepare
+ > ```
+
+1. Download the required files on the nodes
+
+ ```bash
+ ./bin/ck8s-kubespray run-playbook sc upgrade_cluster.yml -b --tags=download
+ ./bin/ck8s-kubespray run-playbook wc upgrade_cluster.yml -b --tags=download
+ ```
+
+## Upgrade steps
+
+These steps will cause disruptions in the environment.
+
+1. Upgrade the cluster to a new kubernetes version:
+
+ ```bash
+ ./bin/ck8s-kubespray run-playbook sc upgrade_cluster.yml -b -e skip_downloads=true
+ ./bin/ck8s-kubespray run-playbook wc upgrade_cluster.yml -b -e skip_downloads=true
+ ```
+
+1. For UpCloud environments, update terraform state
+
+
+ UpCloud environments only
+
+ Clean up old terraform state
+
+ ```bash
+ export CK8S_CLUSTER=
+ ./apply/00-upcloud-clean-tfstate.sh
+ ```
+
+ Configure proxy protocol per LB backend in `cluster.tfvars` (Make sure to keep the same value as was configured before, except for master-api if it was enabled)
+
+ ```diff
+ - loadbalancer_proxy_protocol = true
+ loadbalancers = {
+ "http" : {
+ + "proxy_protocol" : true,
+ "port" : 80,
+ "target_port" : 80,
+ "backend_servers" : [
+ ]
+ },
+ "https" : {
+ + "proxy_protocol" : true,
+ "port" : 443,
+ "target_port" : 443,
+ "backend_servers" : [
+ ]
+ },
+ "master-api" : {
+ + "proxy_protocol" : false,
+ "port" : 6443,
+ "target_port" : 6443,
+ "backend_servers" : [
+ ]
+ ```
+
+ Apply terraform to update state
+
+ ```bash
+ # Source credentials
+ CK8S_KUBESPRAY_PATH=/path/to/compliantkubernetes-kubespray
+ terraform -chdir="${CK8S_KUBESPRAY_PATH}/kubespray/contrib/terraform/upcloud/" plan -var-file="${CK8S_CONFIG_PATH}/sc-config/cluster.tfvars" -state="${CK8S_CONFIG_PATH}/sc-config/terraform.tfstate" -var="inventory_file=${CK8S_CONFIG_PATH}/sc-config/inventory.ini"
+ terraform -chdir="${CK8S_KUBESPRAY_PATH}/kubespray/contrib/terraform/upcloud/" apply -var-file="${CK8S_CONFIG_PATH}/sc-config/cluster.tfvars" -state="${CK8S_CONFIG_PATH}/sc-config/terraform.tfstate" -var="inventory_file=${CK8S_CONFIG_PATH}/sc-config/inventory.ini"
+
+ terraform -chdir="${CK8S_KUBESPRAY_PATH}/kubespray/contrib/terraform/upcloud/" plan -var-file="${CK8S_CONFIG_PATH}/wc-config/cluster.tfvars" -state="${CK8S_CONFIG_PATH}/wc-config/terraform.tfstate" -var="inventory_file=${CK8S_CONFIG_PATH}/wc-config/inventory.ini"
+ terraform -chdir="${CK8S_KUBESPRAY_PATH}/kubespray/contrib/terraform/upcloud/" apply -var-file="${CK8S_CONFIG_PATH}/wc-config/cluster.tfvars" -state="${CK8S_CONFIG_PATH}/wc-config/terraform.tfstate" -var="inventory_file=${CK8S_CONFIG_PATH}/wc-config/inventory.ini"
+ ```
+
+
+
+## Postrequisite
+
+- [ ] Check the state of the environment, pods and nodes:
+
+ ```bash
+ ./compliantkubernetes-apps/bin/ck8s test sc|wc
+ ./compliantkubernetes-apps/bin/ck8s ops kubectl sc|wc get pods -A -o custom-columns=NAMESPACE:metadata.namespace,POD:metadata.name,READY-false:status.containerStatuses[*].ready,REASON:status.containerStatuses[*].state.terminated.reason | grep false | grep -v Completed
+ ./compliantkubernetes-apps/bin/ck8s ops kubectl sc|wc get nodes
+ ```
+
+- [ ] Enable the notifications for the alerts;
+- [ ] Notify the users (if any) when the upgrade is complete;
+
+> [!NOTE]
+> Additionally it is good to check:
+>
+> - if any alerts generated by the upgrade didn't close.
+> - if you can login to Grafana, Opensearch or Harbor.
+> - if you can see fresh metrics and logs.
diff --git a/migration/v2.26/apply/00-upcloud-clean-tfstate.sh b/migration/v2.26/apply/00-upcloud-clean-tfstate.sh
new file mode 100755
index 00000000..71cf5c99
--- /dev/null
+++ b/migration/v2.26/apply/00-upcloud-clean-tfstate.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+HERE="$(dirname "$(readlink -f "${0}")")"
+ROOT="$(readlink -f "${HERE}/../../../")"
+
+# shellcheck source=scripts/migration/lib.sh
+source "${ROOT}/scripts/migration/lib.sh"
+
+if [[ "${CK8S_CLUSTER}" =~ ^(sc|both)$ ]]; then
+ log_info "Removing old tfstate from service cluster"
+ terraform state rm -state="${CK8S_CONFIG_PATH}/sc-config/terraform.tfstate" null_resource.inventories
+ terraform state rm -state="${CK8S_CONFIG_PATH}/sc-config/terraform.tfstate" data.template_file.inventory
+fi
+if [[ "${CK8S_CLUSTER}" =~ ^(wc|both)$ ]]; then
+ log_info "Removing old tfstate from workload cluster"
+ terraform state rm -state="${CK8S_CONFIG_PATH}/wc-config/terraform.tfstate" null_resource.inventories
+ terraform state rm -state="${CK8S_CONFIG_PATH}/wc-config/terraform.tfstate" data.template_file.inventory
+fi
diff --git a/migration/v2.26/prepare/00-template.sh b/migration/v2.26/prepare/00-template.sh
new file mode 100755
index 00000000..350087e6
--- /dev/null
+++ b/migration/v2.26/prepare/00-template.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+HERE="$(dirname "$(readlink -f "${0}")")"
+ROOT="$(readlink -f "${HERE}/../../../")"
+
+# shellcheck source=scripts/migration/lib.sh
+source "${ROOT}/scripts/migration/lib.sh"
+
+# functions currently available in the library:
+# - logging:
+# - log_info(_no_newline)
+# - log_warn(_no_newline)
+# - log_error(_no_newline)
+# - log_fatal # this will call "exit 1"
+#
+# - yq:
+# - yq_null
+# - yq_copy
+# - yq_move
+# - yq_remove
+# - yq_length
+
+# Note: 00-template.sh will be skipped by the upgrade command
+log_info "no operation: this is a template"
+
+if [[ "${CK8S_CLUSTER}" =~ ^(sc|both)$ ]]; then
+ log_info "operation on service cluster"
+fi
+if [[ "${CK8S_CLUSTER}" =~ ^(wc|both)$ ]]; then
+ log_info "operation on workload cluster"
+fi
diff --git a/migration/v2.26/prepare/10-init.sh b/migration/v2.26/prepare/10-init.sh
new file mode 100755
index 00000000..d163259a
--- /dev/null
+++ b/migration/v2.26/prepare/10-init.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+HERE="$(dirname "$(readlink -f "${0}")")"
+ROOT="$(readlink -f "${HERE}/../../../")"
+
+# shellcheck source=scripts/migration/lib.sh
+source "${ROOT}/scripts/migration/lib.sh"
+
+if [[ "${CK8S_CLUSTER}" =~ ^(sc|both)$ ]]; then
+ yq_add sc all/ck8s-kubespray-general .ck8sKubesprayVersion "\"$(git_version)\""
+fi
+if [[ "${CK8S_CLUSTER}" =~ ^(wc|both)$ ]]; then
+ yq_add wc all/ck8s-kubespray-general .ck8sKubesprayVersion "\"$(git_version)\""
+fi