Skip to content

Add support for vpc.controlPlaneOnPrivateSubnets - #8793

Open
guessi wants to merge 1 commit into
eksctl-io:mainfrom
guessi:feat/control-plane-on-private-subnets
Open

Add support for vpc.controlPlaneOnPrivateSubnets#8793
guessi wants to merge 1 commit into
eksctl-io:mainfrom
guessi:feat/control-plane-on-private-subnets

Conversation

@guessi

@guessi guessi commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Description

Closes #8792.

When eksctl creates a VPC, it currently passes both the public and the private subnets to the EKS API, so the control plane's cross-account ENIs are placed in public subnets as well as private ones. Restricting them to private subnets afterwards requires eksctl utils update-cluster-vpc-config, which calls the EKS API directly and leaves the cluster's CloudFormation stack out of sync with the actual configuration.

This PR adds a vpc.controlPlaneOnPrivateSubnets field so that only the private subnets are passed to the EKS API at cluster creation time. Public subnets are still created and used for NAT gateways and internet-facing load balancers — this does not make the cluster fully private, it only changes which subnets the control plane's ENIs land in.

Key implementation points:

  • The field is honoured for eksctl-created VPCs (IPv4 and IPv6, including fully-private clusters) and for pre-existing/imported VPCs.
  • It is rejected when combined with vpc.controlPlaneSubnetIDs, since that field already gives explicit control over control plane subnets.
  • It is rejected when the configured private subnets do not cover at least two availability zones, which EKS requires. This check is best-effort: subnets given only by ID have their AZ resolved from EC2 after validation runs, so those are allowed through validation and rejected by the EKS API instead if insufficient.
  • Outposts clusters are exempt, since the control plane there is already private-only.
  • eksctl utils update-cluster-vpc-config now rejects the field (rather than silently ignoring it) and points users at vpc.controlPlaneSubnetIDs instead, since that command talks to the EKS API directly and can't keep the CloudFormation stack in sync.
  • Control plane subnet selection is now built through a single helper. autoMode is passed into it rather than derived internally, so the new field keeps applying only to VPCs that eksctl creates — the pre-existing VPC path has never restricted the control plane for Auto Mode clusters, and deriving autoMode there would have changed that behaviour for configurations not using the new field.

See examples/49-control-plane-on-private-subnets.yaml for a usage example, and the updated userdocs/src/usage/cluster-subnets-security-groups.md for documentation.

Checklist

  • Added tests that cover your change (if possible)
  • Added/modified documentation as required (such as the README.md, or the userdocs directory)
  • Manually tested
  • Made sure the title of the PR is a good description that can go into the release notes
  • (Core team) Added labels for change area (e.g. area/nodegroup) and kind (e.g. kind/improvement)

BONUS POINTS checklist: complete for good vibes and maybe prizes?! 🤯

  • Backfilled missing tests for code in same general area 🎉
  • Refactored something and made the world a better place 🌟

When eksctl creates a VPC, it passes both the public and the private subnets
to the EKS API, so the control plane's cross-account ENIs are placed in public
subnets as well. Restricting them to private subnets afterwards requires
`eksctl utils update-cluster-vpc-config`, which calls the EKS API directly and
leaves the cluster's CloudFormation stack out of sync.

Add a `vpc.controlPlaneOnPrivateSubnets` field so that only the private subnets
are passed to the EKS API at creation time. Public subnets are still created and
used for NAT gateways and internet-facing load balancers, so this does not make
the cluster fully private.

The field is honoured for eksctl-created VPCs (IPv4 and IPv6, including
fully-private clusters) and for pre-existing VPCs. It is rejected when combined
with `vpc.controlPlaneSubnetIDs`, and when the configured private subnets do not
cover at least two availability zones, which EKS requires. That last check is
best-effort: subnets given only by ID have their zone resolved from EC2 after
validation runs, so they are allowed through and rejected by the EKS API instead.
Outposts are exempt, since the control plane there is already private-only.

`eksctl utils update-cluster-vpc-config` rejects the field rather than silently
ignoring it, and points at `vpc.controlPlaneSubnetIDs` instead.

Control plane subnet selection is now built through a single helper. autoMode is
passed into it rather than derived, so that it keeps applying only to VPCs that
eksctl creates: the pre-existing VPC path has never restricted the control plane
for Auto Mode clusters, and deriving it would have changed that behaviour for
configurations that do not use the new field.

Issue eksctl-io#8792

Signed-off-by: guessi <guessi@gmail.com>
@gustavodiaz7722 gustavodiaz7722 added the kind/feature New feature or request label Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Allow restricting EKS control plane ENIs to private subnets on cluster creation

2 participants