diff --git a/contrib/terraform/upcloud/README.md b/contrib/terraform/upcloud/README.md
index 0962f83542237b1631b645331bb18e584d12773f..5689831ff49356116b44530b36569e00cf5784f8 100644
--- a/contrib/terraform/upcloud/README.md
+++ b/contrib/terraform/upcloud/README.md
@@ -112,12 +112,26 @@ terraform destroy --var-file cluster-settings.tfvars \
     * `size`: The size of the additional disk in GB
     * `tier`: The tier of disk to use (`maxiops` is the only one you can choose atm)
 * `firewall_enabled`: Enable firewall rules
+* `firewall_default_deny_in`: Set the firewall to deny inbound traffic by default. Automatically adds UpCloud DNS server and NTP port allowlisting.
+* `firewall_default_deny_out`: Set the firewall to deny outbound traffic by default.
 * `master_allowed_remote_ips`: List of IP ranges that should be allowed to access API of masters
   * `start_address`: Start of address range to allow
   * `end_address`: End of address range to allow
 * `k8s_allowed_remote_ips`: List of IP ranges that should be allowed SSH access to all nodes
   * `start_address`: Start of address range to allow
   * `end_address`: End of address range to allow
+* `master_allowed_ports`: List of port ranges that should be allowed to access the masters
+  * `protocol`: Protocol *(tcp|udp|icmp)*
+  * `port_range_min`: Start of port range to allow
+  * `port_range_max`: End of port range to allow
+  * `start_address`: Start of address range to allow
+  * `end_address`: End of address range to allow
+* `worker_allowed_ports`: List of port ranges that should be allowed to access the workers
+  * `protocol`: Protocol *(tcp|udp|icmp)*
+  * `port_range_min`: Start of port range to allow
+  * `port_range_max`: End of port range to allow
+  * `start_address`: Start of address range to allow
+  * `end_address`: End of address range to allow
 * `loadbalancer_enabled`: Enable managed load balancer
 * `loadbalancer_plan`: Plan to use for load balancer *(development|production-small)*
 * `loadbalancers`: Ports to load balance and which machines to forward to. Key of this object will be used as the name of the load balancer frontends/backends
diff --git a/contrib/terraform/upcloud/cluster-settings.tfvars b/contrib/terraform/upcloud/cluster-settings.tfvars
index b7bdb2302f636ef0e0c081c4252d0a5f9c6194b0..873150b31d49b5e9fb4c646072b66fc17c65ae2f 100644
--- a/contrib/terraform/upcloud/cluster-settings.tfvars
+++ b/contrib/terraform/upcloud/cluster-settings.tfvars
@@ -95,7 +95,9 @@ machines = {
   }
 }
 
-firewall_enabled = false
+firewall_enabled          = false
+firewall_default_deny_in  = false
+firewall_default_deny_out = false
 
 master_allowed_remote_ips = [
   {
@@ -111,6 +113,9 @@ k8s_allowed_remote_ips = [
   }
 ]
 
+master_allowed_ports = []
+worker_allowed_ports = []
+
 loadbalancer_enabled = false
 loadbalancer_plan    = "development"
 loadbalancers = {
diff --git a/contrib/terraform/upcloud/main.tf b/contrib/terraform/upcloud/main.tf
index 1acc260fa1cd6916bf9938134c2d3b440f9bee91..9904ce291e913279a59dbc5245fe1441c30a5a79 100644
--- a/contrib/terraform/upcloud/main.tf
+++ b/contrib/terraform/upcloud/main.tf
@@ -24,8 +24,12 @@ module "kubernetes" {
   ssh_public_keys = var.ssh_public_keys
 
   firewall_enabled          = var.firewall_enabled
+  firewall_default_deny_in  = var.firewall_default_deny_in
+  firewall_default_deny_out = var.firewall_default_deny_out
   master_allowed_remote_ips = var.master_allowed_remote_ips
   k8s_allowed_remote_ips    = var.k8s_allowed_remote_ips
+  master_allowed_ports      = var.master_allowed_ports
+  worker_allowed_ports      = var.worker_allowed_ports
 
   loadbalancer_enabled = var.loadbalancer_enabled
   loadbalancer_plan    = var.loadbalancer_plan
diff --git a/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf b/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
index ed9de9dd6c6f0548ba6eeebd3f9033751e5be2e9..c6d27ae827d624ef2627d9b9abbe8614172fdb3c 100644
--- a/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
+++ b/contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
@@ -228,6 +228,112 @@ resource "upcloud_firewall_rules" "master" {
       source_address_start   = "0.0.0.0"
     }
   }
+
+  dynamic firewall_rule {
+    for_each = var.master_allowed_ports
+
+    content {
+      action                 = "accept"
+      comment                = "Allow access on this port"
+      destination_port_end   = firewall_rule.value.port_range_max
+      destination_port_start = firewall_rule.value.port_range_min
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value.protocol
+      source_address_end     = firewall_rule.value.end_address
+      source_address_start   = firewall_rule.value.start_address
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value
+      source_address_end     = "94.237.40.9"
+      source_address_start   = "94.237.40.9"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value
+      source_address_end     = "94.237.127.9"
+      source_address_start   = "94.237.127.9"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv6"
+      protocol               = firewall_rule.value
+      source_address_end     = "2a04:3540:53::1"
+      source_address_start   = "2a04:3540:53::1"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv6"
+      protocol               = firewall_rule.value
+      source_address_end     = "2a04:3544:53::1"
+      source_address_start   = "2a04:3544:53::1"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "NTP Port"
+      destination_port_end   = "123"
+      destination_port_start = "123"
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value
+      source_address_end     = "255.255.255.255"
+      source_address_start   = "0.0.0.0"
+    }
+  }
+
+  firewall_rule {
+    action    = var.firewall_default_deny_in ? "drop" : "accept"
+    direction = "in"
+  }
+
+  firewall_rule {
+    action    = var.firewall_default_deny_out ? "drop" : "accept"
+    direction = "out"
+  }
 }
 
 resource "upcloud_firewall_rules" "k8s" {
@@ -265,6 +371,112 @@ resource "upcloud_firewall_rules" "k8s" {
       source_address_start   = "0.0.0.0"
     }
   }
+
+  dynamic firewall_rule {
+    for_each = var.worker_allowed_ports
+
+    content {
+      action                 = "accept"
+      comment                = "Allow access on this port"
+      destination_port_end   = firewall_rule.value.port_range_max
+      destination_port_start = firewall_rule.value.port_range_min
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value.protocol
+      source_address_end     = firewall_rule.value.end_address
+      source_address_start   = firewall_rule.value.start_address
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value
+      source_address_end     = "94.237.40.9"
+      source_address_start   = "94.237.40.9"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value
+      source_address_end     = "94.237.127.9"
+      source_address_start   = "94.237.127.9"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv6"
+      protocol               = firewall_rule.value
+      source_address_end     = "2a04:3540:53::1"
+      source_address_start   = "2a04:3540:53::1"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["tcp", "udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "UpCloud DNS"
+      destination_port_end   = "53"
+      destination_port_start = "53"
+      direction              = "in"
+      family                 = "IPv6"
+      protocol               = firewall_rule.value
+      source_address_end     = "2a04:3544:53::1"
+      source_address_start   = "2a04:3544:53::1"
+    }
+  }
+
+  dynamic firewall_rule {
+    for_each = var.firewall_default_deny_in ? ["udp"] : []
+
+    content {
+      action                 = "accept"
+      comment                = "NTP Port"
+      destination_port_end   = "123"
+      destination_port_start = "123"
+      direction              = "in"
+      family                 = "IPv4"
+      protocol               = firewall_rule.value
+      source_address_end     = "255.255.255.255"
+      source_address_start   = "0.0.0.0"
+    }
+  }
+
+  firewall_rule {
+    action    = var.firewall_default_deny_in ? "drop" : "accept"
+    direction = "in"
+  }
+
+  firewall_rule {
+    action    = var.firewall_default_deny_out ? "drop" : "accept"
+    direction = "out"
+  }
 }
 
 resource "upcloud_loadbalancer" "lb" {
diff --git a/contrib/terraform/upcloud/modules/kubernetes-cluster/variables.tf b/contrib/terraform/upcloud/modules/kubernetes-cluster/variables.tf
index 1fc411b27adc0b205d4ec00596d08a21e46c87a0..1b334440d7705110fb8ae9d08a5ae65bd64b4278 100644
--- a/contrib/terraform/upcloud/modules/kubernetes-cluster/variables.tf
+++ b/contrib/terraform/upcloud/modules/kubernetes-cluster/variables.tf
@@ -49,6 +49,34 @@ variable "k8s_allowed_remote_ips" {
   }))
 }
 
+variable "master_allowed_ports" {
+  type = list(object({
+    protocol       = string
+    port_range_min = number
+    port_range_max = number
+    start_address  = string
+    end_address    = string
+  }))
+}
+
+variable "worker_allowed_ports" {
+  type = list(object({
+    protocol       = string
+    port_range_min = number
+    port_range_max = number
+    start_address  = string
+    end_address    = string
+  }))
+}
+
+variable "firewall_default_deny_in" {
+  type = bool
+}
+
+variable "firewall_default_deny_out" {
+  type = bool
+}
+
 variable "loadbalancer_enabled" {
   type = bool
 }
diff --git a/contrib/terraform/upcloud/modules/kubernetes-cluster/versions.tf b/contrib/terraform/upcloud/modules/kubernetes-cluster/versions.tf
index 8d87504df1722f18a4a32b351b23918272191f50..447ba84da235c13085ba96e93e4e42363adf41b9 100644
--- a/contrib/terraform/upcloud/modules/kubernetes-cluster/versions.tf
+++ b/contrib/terraform/upcloud/modules/kubernetes-cluster/versions.tf
@@ -3,7 +3,7 @@ terraform {
   required_providers {
     upcloud = {
       source = "UpCloudLtd/upcloud"
-      version = "~>2.4.0"
+      version = "~>2.5.0"
     }
   }
   required_version = ">= 0.13"
diff --git a/contrib/terraform/upcloud/sample-inventory/cluster.tfvars b/contrib/terraform/upcloud/sample-inventory/cluster.tfvars
index 787fb702c3aaec9cd863d3b4c8b9890e9c3e44bb..b98a853974d41c027fc44183779f70c70fdfb27f 100644
--- a/contrib/terraform/upcloud/sample-inventory/cluster.tfvars
+++ b/contrib/terraform/upcloud/sample-inventory/cluster.tfvars
@@ -95,7 +95,10 @@ machines = {
   }
 }
 
-firewall_enabled = false
+firewall_enabled          = false
+firewall_default_deny_in  = false
+firewall_default_deny_out = false
+
 
 master_allowed_remote_ips = [
   {
@@ -111,6 +114,9 @@ k8s_allowed_remote_ips = [
   }
 ]
 
+master_allowed_ports = []
+worker_allowed_ports = []
+
 loadbalancer_enabled = false
 loadbalancer_plan = "development"
 loadbalancers = {
diff --git a/contrib/terraform/upcloud/variables.tf b/contrib/terraform/upcloud/variables.tf
index 60d07c1bfe053cd468b909c8a3b2c5c54fe1228c..5a360487849c60a2fda0ebc3804b6c603251961d 100644
--- a/contrib/terraform/upcloud/variables.tf
+++ b/contrib/terraform/upcloud/variables.tf
@@ -79,6 +79,38 @@ variable "k8s_allowed_remote_ips" {
   default = []
 }
 
+variable "master_allowed_ports" {
+  description = "List of ports to allow on masters"
+  type = list(object({
+    protocol       = string
+    port_range_min = number
+    port_range_max = number
+    start_address  = string
+    end_address    = string
+  }))
+}
+
+variable "worker_allowed_ports" {
+  description = "List of ports to allow on workers"
+  type = list(object({
+    protocol       = string
+    port_range_min = number
+    port_range_max = number
+    start_address  = string
+    end_address    = string
+  }))
+}
+
+variable "firewall_default_deny_in" {
+  description = "Add firewall policies that deny all inbound traffic by default"
+  default     = false
+}
+
+variable "firewall_default_deny_out" {
+  description = "Add firewall policies that deny all outbound traffic by default"
+  default     = false
+}
+
 variable "loadbalancer_enabled" {
   description = "Enable load balancer"
   default     = false
diff --git a/contrib/terraform/upcloud/versions.tf b/contrib/terraform/upcloud/versions.tf
index 5250626c39e7919e767d9d51d522a948134374f9..48e6820eea78cd846bc071e2de0e9844f9ab0189 100644
--- a/contrib/terraform/upcloud/versions.tf
+++ b/contrib/terraform/upcloud/versions.tf
@@ -3,7 +3,7 @@ terraform {
   required_providers {
     upcloud = {
       source  = "UpCloudLtd/upcloud"
-      version = "~>2.4.0"
+      version = "~>2.5.0"
     }
   }
   required_version = ">= 0.13"