Skip to main content

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

  1. Open the Amazon EKS console at https://console.aws.amazon.com/eks
  2. Select Clusters from the left navigation
  3. Click on your cluster name
  4. Go to the Networking tab
  5. Find Cluster endpoint access and click Manage
  6. Under Private access, select Enabled
  7. (Recommended) Under Public access, select Disabled to fully restrict external access
  8. 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:

  1. In the AWS Console, navigate to your EKS cluster
  2. Check the Networking tab
  3. 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

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 publicAccessCidrs setting.
  • kubectl access: After disabling public access, you must run kubectl commands from within the VPC or through a connected network.