AKS cluster nodes do not have public IP addresses
AKS agent pools use only private addressing, with node public IP assignment disabled (enableNodePublicIP=false). Clusters where any pool assigns a public IP to nodes are identified.
Risk
Public node IPs expose worker VMs to Internet scanning and exploit attempts against OS or kubelet services. Successful compromise can lead to stolen secrets and images (confidentiality), workload tampering (integrity), and node/resource exhaustion via DDoS or cryptomining (availability).
Run this check with Prowler
Run in Prowler Cloudprowler azure --checks aks_clusters_created_with_private_nodesRecommendation
Disable public node IPs on all agent pools (enableNodePublicIP=false) and route egress via a NAT gateway or Azure Firewall. Apply least privilege with NSGs blocking Internet ingress, use private endpoints and bastion/VPN for admin access, and adopt defense in depth with continuous hardening and monitoring.
Remediation
Terraform
# AKS cluster with node public IPs disabled
resource "azurerm_kubernetes_cluster" "<example_resource_name>" {
name = "<example_resource_name>"
location = "<location>"
resource_group_name = "<example_resource_name>"
dns_prefix = "<example_resource_name>"
default_node_pool {
name = "default"
node_count = 1
vm_size = "Standard_DS2_v2"
enable_node_public_ip = false # CRITICAL: ensures nodes have no public IPs
}
identity {
type = "SystemAssigned"
}
}NativeIaC
// AKS cluster with nodes not assigned public IPs
resource mc '<example_resource_name>@Microsoft.ContainerService/managedClusters@2024-05-01' = {
name: '<example_resource_name>'
location: '<location>'
identity: {
type: 'SystemAssigned'
}
properties: {
dnsPrefix: '<example_resource_name>'
agentPoolProfiles: [
{
name: 'nodepool1'
count: 1
vmSize: 'Standard_DS2_v2'
enableNodePublicIP: false // CRITICAL: ensures nodes have no public IPs
}
]
}
}Other
Check Code
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.aks.aks_client import aks_client
class aks_clusters_created_with_private_nodes(Check):
def execute(self) -> Check_Report_Azure:
findings = []
for subscription_id, clusters in aks_client.clusters.items():
subscription_name = aks_client.subscriptions.get(
subscription_id, subscription_id
)
for cluster in clusters.values():
report = Check_Report_Azure(metadata=self.metadata(), resource=cluster)
report.subscription = subscription_id
report.status = "PASS"
report.status_extended = f"Cluster '{cluster.name}' was created with private nodes in subscription '{subscription_name} ({subscription_id})'"
for agent_pool in cluster.agent_pool_profiles:
if getattr(agent_pool, "enable_node_public_ip", True):
report.status = "FAIL"
report.status_extended = f"Cluster '{cluster.name}' was not created with private nodes in subscription '{subscription_name} ({subscription_id})'"
break
findings.append(report)
return findings