diff --git a/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml b/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml
index e11e8e2d15077d4ecf1a5b88005dbe94346ab93f..01173150300cd13acb832f64bcb932f6f65c4048 100644
--- a/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml
+++ b/roles/kubernetes-apps/csi_driver/upcloud/tasks/main.yml
@@ -18,6 +18,7 @@
   template:
     src: "{{ item.file }}.j2"
     dest: "{{ kube_config_dir }}/{{ item.file }}"
+    mode: 0644
   with_items:
     - {name: upcloud-csi-cred-secret, file: upcloud-csi-cred-secret.yml}
     - {name: upcloud-csi-setup, file: upcloud-csi-setup.yml}
diff --git a/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml b/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml
index f63e49a9b3d72db8d6c9368ddc859b632d7c8b04..26104a092adfe7f624ba9433b708a495ef81ab6c 100644
--- a/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml
+++ b/roles/kubernetes-apps/persistent_volumes/upcloud-csi/tasks/main.yml
@@ -3,6 +3,7 @@
   template:
     src: "upcloud-csi-storage-class.yml.j2"
     dest: "{{ kube_config_dir }}/upcloud-csi-storage-class.yml"
+    mode: 0644
   register: manifests
   when:
     - inventory_hostname == groups['kube_control_plane'][0]
diff --git a/roles/network_plugin/calico/defaults/main.yml b/roles/network_plugin/calico/defaults/main.yml
index 9e947ec703a856662af7daebcd7006611340bc55..e73545c21c314858cf0fc4f4951c4024cb3df439 100644
--- a/roles/network_plugin/calico/defaults/main.yml
+++ b/roles/network_plugin/calico/defaults/main.yml
@@ -133,8 +133,14 @@ calico_felix_log_severity_screen: Info
 # Calico container settings
 calico_allow_ip_forwarding: false
 
-# Calico IPAM strictaffinity
+# Calico IPAM strictAffinity
 calico_ipam_strictaffinity: false
 
+# Calico IPAM autoAllocateBlocks
+calcio_ipam_autoallocateblocks: true
+
+# Calico IPAM maxBlocksPerHost, default 0
+calico_ipam_maxblocksperhost: 0
+
 # Calico apiserver (only with kdd)
 calico_apiserver_enabled: false
diff --git a/roles/network_plugin/calico/tasks/install.yml b/roles/network_plugin/calico/tasks/install.yml
index 164ae0e0ed4c1e4eb50bac636710020befff504f..402aeeeb9eb1eca951de594766f6cf84ae1a8911 100644
--- a/roles/network_plugin/calico/tasks/install.yml
+++ b/roles/network_plugin/calico/tasks/install.yml
@@ -491,13 +491,20 @@
     - peer_with_router|default(false)
     - inventory_hostname == groups['kube_control_plane'][0]
 
-- name: Calico | Configure ipam strictaffinity
-  command:
-    cmd: "{{ bin_dir }}/calicoctl.sh ipam configure --strictaffinity={{ calico_ipam_strictaffinity }}"
-  register: output
-  retries: 4
-  until: output.rc == 0
-  delay: "{{ retry_stagger | random + 3 }}"
+- name: Calico | Create Calico ipam manifests
+  template:
+    src: "{{ item.file }}.j2"
+    dest: "{{ kube_config_dir }}/{{ item.file }}"
+    mode: 0644
+  with_items:
+    - {name: calico, file: calico-ipamconfig.yml, type: ipam}
+  when:
+    - inventory_hostname in groups['kube_control_plane']
+
+- name: Calico | Create ipamconfig resources
+  kube:
+    kubectl: "{{ bin_dir }}/kubectl"
+    filename: "{{ kube_config_dir }}/calico-ipamconfig.yml"
+    state: "latest"
   when:
-    - calico_ipam_strictaffinity is defined
     - inventory_hostname == groups['kube_control_plane'][0]
diff --git a/roles/network_plugin/calico/templates/calico-ipamconfig.yml.j2 b/roles/network_plugin/calico/templates/calico-ipamconfig.yml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..3cb85c1bf70c37d8312472bfeb2c405124762b40
--- /dev/null
+++ b/roles/network_plugin/calico/templates/calico-ipamconfig.yml.j2
@@ -0,0 +1,8 @@
+apiVersion: crd.projectcalico.org/v1
+kind: IPAMConfig
+metadata:
+  name: default
+spec:
+  autoAllocateBlocks: {{ calcio_ipam_autoallocateblocks }}
+  strictAffinity: {{ calico_ipam_strictaffinity }}
+  maxBlocksPerHost: {{ calico_ipam_maxblocksperhost }}