Ensure Clusters are created with Private Nodes
Overview
This check verifies that your Amazon EKS clusters have private endpoint access enabled for the Kubernetes API server. When enabled, traffic to your cluster's control plane routes through a private VPC endpoint instead of the public internet.
Risk
Without private endpoint access, your Kubernetes API server is publicly exposed. This creates significant security vulnerabilities:
- Unauthorized access: Compromised credentials could allow attackers to make API calls, access secrets, or deploy malicious pods
- Increased attack surface: Public endpoints are discoverable and can be targeted by automated attacks
- Availability concerns: Internet-dependent connections introduce additional failure points
Remediation Steps
Prerequisites
You need access to the AWS Console or AWS CLI with permissions to modify EKS cluster configurations (eks:UpdateClusterConfig).
AWS Console Method
- Open the Amazon EKS console at https://console.aws.amazon.com/eks
- Select Clusters from the left navigation
- Click on your cluster name
- Go to the Networking tab
- Find Cluster endpoint access and click Manage
- Under Private access, select Enabled
- (Recommended) Under Public access, select Disabled to fully restrict external access
- Click Save changes
Note: The update may take several minutes to complete. Your cluster remains functional during this time.
AWS CLI (optional)
Enable private endpoint access for an existing cluster:
aws eks update-cluster-config \
--region us-east-1 \
--name <your-cluster-name> \
--resources-vpc-config endpointPrivateAccess=true,endpointPublicAccess=false
To enable private access while keeping public access (with CIDR restrictions):
aws eks update-cluster-config \
--region us-east-1 \
--name <your-cluster-name> \
--resources-vpc-config endpointPrivateAccess=true,endpointPublicAccess=true,publicAccessCidrs="10.0.0.0/8"
Check the status of your update:
aws eks describe-update \
--region us-east-1 \
--name <your-cluster-name> \
--update-id <update-id-from-previous-command>
CloudFormation (optional)
Use this template to create an EKS cluster with private endpoint access enabled:
AWSTemplateFormatVersion: '2010-09-09'
Description: EKS Cluster with Private Endpoint Access Enabled
Parameters:
ClusterName:
Type: String
Description: Name of the EKS cluster
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: List of subnet IDs for the EKS cluster
SecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
Description: Security group IDs for cluster communication
ClusterRoleArn:
Type: String
Description: ARN of the IAM role for the EKS cluster
Resources:
EKSCluster:
Type: AWS::EKS::Cluster
Properties:
Name: !Ref ClusterName
RoleArn: !Ref ClusterRoleArn
ResourcesVpcConfig:
SubnetIds: !Ref SubnetIds
SecurityGroupIds: !Ref SecurityGroupIds
EndpointPrivateAccess: true
EndpointPublicAccess: false
Outputs:
ClusterEndpoint:
Description: EKS Cluster Endpoint
Value: !GetAtt EKSCluster.Endpoint
ClusterArn:
Description: EKS Cluster ARN
Value: !GetAtt EKSCluster.Arn
Terraform (optional)
variable "cluster_name" {
description = "Name of the EKS cluster"
type = string
}
variable "subnet_ids" {
description = "List of subnet IDs for the EKS cluster"
type = list(string)
}
variable "cluster_role_arn" {
description = "ARN of the IAM role for the EKS cluster"
type = string
}
resource "aws_eks_cluster" "main" {
name = var.cluster_name
role_arn = var.cluster_role_arn
vpc_config {
subnet_ids = var.subnet_ids
endpoint_private_access = true
endpoint_public_access = false
}
}
output "cluster_endpoint" {
description = "EKS cluster endpoint"
value = aws_eks_cluster.main.endpoint
}
output "cluster_certificate_authority" {
description = "EKS cluster certificate authority data"
value = aws_eks_cluster.main.certificate_authority[0].data
}
Verification
After making changes, verify the configuration:
- In the AWS Console, navigate to your EKS cluster
- Check the Networking tab
- Confirm that Private access shows Enabled
CLI Verification
aws eks describe-cluster \
--region us-east-1 \
--name <your-cluster-name> \
--query 'cluster.resourcesVpcConfig.{PrivateAccess:endpointPrivateAccess,PublicAccess:endpointPublicAccess}'
Expected output:
{
"PrivateAccess": true,
"PublicAccess": false
}
Additional Resources
- Amazon EKS Cluster Endpoint Access Control
- Amazon EKS Private Clusters
- Amazon EKS Security Best Practices
Notes
- Connectivity requirement: When disabling public access, ensure you have network connectivity to the private endpoint (via VPN, Direct Connect, or a bastion host within the VPC).
- Update duration: Cluster endpoint changes typically complete within 10-15 minutes. The cluster remains operational during updates.
- Hybrid access: If external access is required, you can keep public access enabled but restrict it to specific CIDR blocks using the
publicAccessCidrssetting. - kubectl access: After disabling public access, you must run
kubectlcommands from within the VPC or through a connected network.