From f5320d26045050fc11d94864e1aa81c0b6991da1 Mon Sep 17 00:00:00 2001 From: Vedant Madane <6527493+VedantMadane@users.noreply.github.com> Date: Mon, 2 Mar 2026 14:07:24 +0530 Subject: [PATCH] fix: allow AWS subnet ID without zone in cluster manifest This PR relaxes the requirement that all subnets must have a zone specified. If a subnet ID is provided, kops can resolve the zone from AWS during the build process. This fixes an issue where kops would fail validation if spec.subnets[*].zone was omitted even when spec.subnets[*].id was present. --- upup/pkg/fi/cloudup/awsup/aws_utils.go | 5 +++++ upup/pkg/fi/cloudup/awsup/aws_utils_test.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/upup/pkg/fi/cloudup/awsup/aws_utils.go b/upup/pkg/fi/cloudup/awsup/aws_utils.go index 4ecd738cd7991..5937f6fe52b32 100644 --- a/upup/pkg/fi/cloudup/awsup/aws_utils.go +++ b/upup/pkg/fi/cloudup/awsup/aws_utils.go @@ -94,6 +94,11 @@ func FindRegion(cluster *kops.Cluster) (string, error) { nodeZones := make(map[string]bool) for _, subnet := range cluster.Spec.Networking.Subnets { + if subnet.Zone == "" && subnet.ID != "" { + // Subnet ID is provided, so we can skip zone check here. + // The zone will be resolved from AWS later. + continue + } if len(subnet.Zone) <= 2 { return "", fmt.Errorf("invalid AWS zone: %q in subnet %q", subnet.Zone, subnet.Name) } diff --git a/upup/pkg/fi/cloudup/awsup/aws_utils_test.go b/upup/pkg/fi/cloudup/awsup/aws_utils_test.go index cba8ba7267a29..21d4c5caee184 100644 --- a/upup/pkg/fi/cloudup/awsup/aws_utils_test.go +++ b/upup/pkg/fi/cloudup/awsup/aws_utils_test.go @@ -68,6 +68,24 @@ func TestFindRegion(t *testing.T) { } } +func TestFindRegion_SubnetIDWithoutZone(t *testing.T) { + c := &kops.Cluster{} + c.Spec.Networking.Subnets = []kops.ClusterSubnetSpec{ + {Name: "subnet-1", Zone: "us-east-1a"}, + {Name: "subnet-2", ID: "subnet-12345678"}, // No zone, but has ID + } + + region, err := FindRegion(c) + if err != nil { + t.Fatalf("unexpected error finding region: %v", err) + } + + expected := "us-east-1" + if region != expected { + t.Fatalf("expected region %q, got %q", expected, region) + } +} + func TestEC2TagSpecification(t *testing.T) { cases := []struct { Name string