Private/aks/checks/BestPracticesChecks.ps1
$bestPracticesChecks = @( @{ ID = "BP001"; Category = "Best Practices"; Name = "Allowed Container Images Policy Enforcement"; Value = { ($ClusterInfo.kubeData.Constraints.items | Where-Object { $_.kind -eq "K8sAzureV2ContainerAllowedImages"}).spec.enforcementAction -contains "deny" }; Expected = $true; FailMessage = "The 'Only Allowed Images' policy is either missing or not enforcing deny mode, increasing the risk of running untrusted images."; Severity = "High"; Recommendation = "Deploy and enforce the 'Only Allowed Images' policy with deny mode to restrict unapproved images."; URL = "https://learn.microsoft.com/en-us/azure/aks/azure-policy"; }, @{ ID = "BP002"; Category = "Best Practices"; Name = "No Privileged Containers Policy Enforcement"; Value = { ($ClusterInfo.kubeData.Constraints.items | Where-Object { $_.kind -eq "K8sAzureV2NoPrivilege"}).spec.enforcementAction -contains "deny" }; Expected = $true; FailMessage = "The 'No Privileged Containers' policy is either missing or not enforcing deny mode, allowing potentially insecure workloads."; Severity = "High"; Recommendation = "Deploy and enforce the 'No Privileged Containers' policy in deny mode to block privileged containers and enhance security."; URL = "https://learn.microsoft.com/en-us/azure/aks/azure-policy"; }, @{ ID = "BP003"; Category = "Best Practices"; Name = "Multiple Node Pools"; Value = { $clusterInfo.agentPoolProfiles.Count -gt 1 }; Expected = $true; FailMessage = "Only a single node pool is in use, reducing flexibility and workload separation."; Severity = "Medium"; Recommendation = "Use multiple node pools to optimize workload performance, security, and resource utilization."; URL = "https://learn.microsoft.com/en-us/azure/aks/use-multiple-node-pools"; }, @{ ID = "BP004"; Category = "Best Practices"; Name = "Azure Linux as Host OS"; Value = { ($clusterInfo.agentPoolProfiles | Where-Object { $_.osType -eq "Linux" -and $_.osSKU -ne "AzureLinux" }).Count }; Expected = 0; FailMessage = "One or more Linux node pools are not using Azure Linux as the host OS, which may impact compatibility and support."; Severity = "High"; Recommendation = "Migrate Linux node pools to Azure Linux to ensure better performance and compatibility."; URL = "https://learn.microsoft.com/en-us/azure/aks/use-azure-linux"; }, @{ ID = "BP005"; Category = "Best Practices"; Name = "Ephemeral OS Disks Enabled"; Value = { ($clusterInfo.agentPoolProfiles | Where-Object { $_.osDiskType -ne "Ephemeral" }).Count }; Expected = 0; FailMessage = "One or more agent pools are not using ephemeral OS disks, leading to slower disk performance and increased costs."; Severity = "Medium"; Recommendation = "Configure all agent pools to use ephemeral OS disks for faster disk performance and lower costs."; URL = "https://learn.microsoft.com/en-us/azure/aks/ephemeral-os-disks"; }, @{ ID = "BP006"; Category = "Best Practices"; Name = "Non-Ephemeral Disks with Adequate Size"; Value = { ($clusterInfo.agentPoolProfiles | Where-Object { $_.osDiskType -ne "Ephemeral" -and $_.osDiskSizeGb -lt 128 }).Count }; Expected = 0; FailMessage = "One or more node pools have OS disks smaller than 128GB, which may impact performance under high workloads."; Severity = "Medium"; Recommendation = "Increase OS disk size to 128GB or more for non-ephemeral disks to optimize workload performance."; URL = "https://learn.microsoft.com/en-us/azure/aks/availability-zone-support"; }, @{ ID = "BP007"; Category = "Best Practices"; Name = "System Node Pool Taint"; Value = { ($clusterInfo.agentPoolProfiles | Where-Object { $_.mode -eq "System" }).nodeTaints -contains "CriticalAddonsOnly=true:NoSchedule" }; Expected = $true; FailMessage = "The system node pool does not have the required taint 'CriticalAddonsOnly=true:NoSchedule', potentially affecting system pod placement."; Severity = "High"; Recommendation = "Apply the 'CriticalAddonsOnly=true:NoSchedule' taint to the system node pool to ensure only critical system pods run on it."; URL = "https://learn.microsoft.com/en-us/azure/aks/use-system-node-pools"; }, @{ ID = "BP008"; Category = "Best Practices"; Name = "Auto Upgrade Channel Configured"; Value = { $clusterInfo.autoUpgradeProfile.upgradeChannel -ne "none" }; Expected = $true; FailMessage = "Auto upgrade channel is not configured, meaning the cluster will not automatically receive security patches and updates."; Severity = "Medium"; Recommendation = "Set the auto upgrade channel to an appropriate option (e.g., 'patch' or 'stable') to keep your AKS cluster updated."; URL = "https://learn.microsoft.com/en-us/azure/aks/auto-upgrade"; }, @{ ID = "BP009"; Category = "Best Practices"; Name = "Node OS Upgrade Channel Configured"; Value = { ($clusterInfo.autoUpgradeProfile.nodeOSUpgradeChannel -ne "None") }; Expected = $true; FailMessage = "Node OS upgrade channel is not configured, which may leave your node OS outdated and vulnerable."; Severity = "Medium"; Recommendation = "Configure the node OS upgrade channel to ensure timely updates and security patches."; URL = "https://learn.microsoft.com/en-us/azure/aks/auto-upgrade"; }, @{ ID = "BP010"; Category = "Best Practices"; Name = "Customized MC_ Resource Group Name"; Value = { -not ($clusterInfo.nodeResourceGroup -like "MC_*") }; Expected = $true; FailMessage = "The node resource group is using the default 'MC_' prefix, which makes management less intuitive."; Severity = "Medium"; Recommendation = "Specify a custom node resource group name during AKS cluster creation for better organization and clarity."; URL = "https://learn.microsoft.com/en-us/azure/aks/concepts-clusters-resource-group"; } ) |