diff --git a/roles/create_infrastructure/tasks/lb_members.yml b/roles/create_infrastructure/tasks/lb_members.yml
index 35b6d60559c919c6c5eac74a08a5e72db9c051c8..595ffccd997b5e651b1c65cd46e2fd84a6369624 100644
--- a/roles/create_infrastructure/tasks/lb_members.yml
+++ b/roles/create_infrastructure/tasks/lb_members.yml
@@ -62,8 +62,8 @@
     pool_members:
       - { pool: 6443, port: 6443, vm: "{{ servers + [ master ] }}" }
       - { pool: 9345, port: 9345, vm: "{{ servers + [ master ] }}" }
-      - { pool: 80, port: 32080, vm: "{{ servers + [ master ] + agents }}" }
-      - { pool: 443, port: 32443, vm: "{{ servers + [ master ] + agents }}" }
+      - { pool: 80, port: 80, vm: "{{ agents }}" }
+      - { pool: 443, port: 443, vm: "{{ agents }}" }
 
 - name: add members
   openstack.cloud.lb_member:
diff --git a/roles/create_infrastructure/tasks/security_groups.yml b/roles/create_infrastructure/tasks/security_groups.yml
index de43f1f9cf464edd981c94f01ca4f9b13e956851..de51a9b238521ef1aa481fcf462890d4a2c586d2 100644
--- a/roles/create_infrastructure/tasks/security_groups.yml
+++ b/roles/create_infrastructure/tasks/security_groups.yml
@@ -17,6 +17,9 @@
   loop:
     - { protocol: TCP, min: 2379, max: 2380, cidr: "{{ cidr }}" } # etcd
     - { protocol: TCP, min: 6443, max: 6443, cidr: "{{ cidr }}" } # Kubernetes API
+    - { protocol: TCP, min: 80, max: 80, cidr: "{{ cidr }}" } # Ingress HTTP
+    - { protocol: TCP, min: 443, max: 80, cidr: "{{ cidr }}" } # Ingress HTTPS
+    - { protocol: TCP, min: 8443, max: 8443, cidr: "{{ cidr }}" } # Ingress Webhook
     - { protocol: TCP, min: 9345, max: 9345, cidr: "{{ cidr }}" } # RKE2 API
     - { protocol: TCP, min: 10250, max: 10250, cidr: "{{ cidr }}" } # kubelet metrics
     - { protocol: TCP, min: 30000, max: 32767, cidr: "{{ cidr }}" } # NodePort port range
diff --git a/roles/rke2/defaults/main.yml b/roles/rke2/defaults/main.yml
index 80a359ea776c55abf265f3f66240bc954ee1b02c..518b274b32d1d58665a880c00c266b1e6ad671df 100644
--- a/roles/rke2/defaults/main.yml
+++ b/roles/rke2/defaults/main.yml
@@ -9,4 +9,7 @@ node_labels: []
 
 rke2_channel: stable
 
-state: present
\ No newline at end of file
+state: present
+upgrade: no
+dist_upgrade: no
+reboot: no
\ No newline at end of file
diff --git a/roles/rke2/tasks/install_rke2.yml b/roles/rke2/tasks/install_rke2.yml
index 5cab01d94a1d4423d490757dbd448d911d66a215..a96d4b6310d0640c9203b575b14d853d01eae65b 100644
--- a/roles/rke2/tasks/install_rke2.yml
+++ b/roles/rke2/tasks/install_rke2.yml
@@ -3,7 +3,7 @@
     url: https://get.rke2.io
     dest: /tmp/rke2.sh
     mode: '0755'
-  when: not rke2_installed.stat.exists
+  when: not rke2_installed.stat.exists or upgrade
 
 - name: Install RKE2
   command: "/tmp/rke2.sh"
@@ -13,6 +13,14 @@
     INSTALL_RKE2_CHANNEL: "{{ rke2_channel }}"
     INSTALL_RKE2_TYPE: "{{ node_type }}"
 
+- name: Upgrade RKE2
+  command: "/tmp/rke2.sh"
+  environment:
+    INSTALL_RKE2_CHANNEL: "{{ rke2_channel }}"
+    INSTALL_RKE2_TYPE: "{{ node_type }}"
+  when: upgrade
+  notify: restart rke2
+
 - name: remove RKE2 install script
   file:
     path: /tmp/rke2.sh
diff --git a/roles/rke2/tasks/main.yml b/roles/rke2/tasks/main.yml
index d65d0db0143fba04652bc4d9edea5435de2cbb63..cc6f6b67380885480ca0e0186029fb6e04bb6840 100644
--- a/roles/rke2/tasks/main.yml
+++ b/roles/rke2/tasks/main.yml
@@ -5,7 +5,7 @@
 - block:
   - include_tasks: setup_host.yml
   - include_tasks: install_rke2.yml
-  when: not rke2_installed.stat.exists and state != 'absent'
+  when: ( not rke2_installed.stat.exists and state != 'absent' ) or (upgrade and state != 'absent' )
 
 - include_tasks: helm.yml
   when: "state != 'absent' and 'master' in group_names"
diff --git a/roles/rke2/tasks/setup_host.yml b/roles/rke2/tasks/setup_host.yml
index 221922ba5aa56fbde9ebd27374b20d9937afbec8..843aaf9d83be27ba3089b6e60f30e1a95704a02c 100644
--- a/roles/rke2/tasks/setup_host.yml
+++ b/roles/rke2/tasks/setup_host.yml
@@ -42,15 +42,17 @@
 - name: update package cache
   apt:
     update_cache: yes
+  when: dist_upgrade
 
 - name: upgrade packages
   apt: 
     name: "*"
     state: latest
   register: update_packages
+  when: dist_upgrade
 
 - name: reboot vm
   throttle: 1
   reboot:
     reboot_timeout: 300
-  when: update_packages.changed
\ No newline at end of file
+  when: update_packages.changed and reboot
\ No newline at end of file
diff --git a/roles/rke2/templates/helm/config-nginx-ingress.j2 b/roles/rke2/templates/helm/config-nginx-ingress.j2
index a730ded72442ac1ce3549db7ad985173b0a178c0..b3db1604110f5cf5353c77dab134fc822808b023 100644
--- a/roles/rke2/templates/helm/config-nginx-ingress.j2
+++ b/roles/rke2/templates/helm/config-nginx-ingress.j2
@@ -3,22 +3,8 @@ kind: HelmChartConfig
 metadata:
   name: rke2-ingress-nginx
   namespace: kube-system
-
 spec:
-  set:
-    controller:
-      config:
-        entries: |
-          upstream-keepalive-timeout: 3600
   valuesContent: |-
     controller:
-      image:
-        repository: k8s.gcr.io/ingress-nginx/controller
-        tag: "v0.48.1"
       config: 
-        use-forwarded-headers: "true"
-      service:
-        type: NodePort
-        nodePorts:
-          http: 32080
-          https: 32443
\ No newline at end of file
+        use-forwarded-headers: "true"
\ No newline at end of file