Skip to content

VPC endpoint association resources have external name oscillation due to ID format mismatch #2116

Description

@aditmeno

What happened?

VPCEndpointSubnetAssociation (and VPCEndpointRouteTableAssociation) managed resources flip their crossplane.io/external-name annotation between two formats on every reconciliation, causing perpetual updates (and, on affected setups, delete/recreate churn and AWS 429 throttling).

Observed live across reconciles for a single subnet association MR:

ext=vpce-079f2245bf1ec40be/subnet-012d3109ebb773a1c    <-- import format
ext=a-vpce-079f2245bf1ec40be1284373945                 <-- internal-id format

The resource's resourceVersion increments continuously while it sits in the vpce/subnet state; a sibling association that happens to settle on the a-<hash> form is stable.

Root cause

aws_vpc_endpoint_subnet_association and aws_vpc_endpoint_route_table_association are configured with FormattedIdentifierFromProvider("/", ...) in config/externalname.go. That helper leaves GetExternalNameFn as the IdentifierFromProvider default (reads tfstate["id"]) while GetIDFn joins the parameters with /.

But the Terraform AWS provider sets the id to a prefixed, hashcode-based value, not the slash-joined import id (internal/service/ec2/id.go):

func vpcEndpointSubnetAssociationCreateID(vpcEndpointID, subnetID string) string {
    return fmt.Sprintf("a-%s%d", vpcEndpointID, create.StringHashcode(subnetID))
}

So GetExternalNameFn yields a-<vpc_endpoint_id><hashcode(subnet_id)> while GetIDFn yields vpc_endpoint_id/subnet_id — the two disagree and the external name oscillates. This is the same class of bug fixed for the API Gateway v1 resources in #1974 / #1975.

(aws_vpc_endpoint_security_group_association uses config.IdentifierFromProvider — both sides are the a-<hash> id, so it is consistent and unaffected.)

How can we reproduce it?

Create a VPCEndpointSubnetAssociation and watch kubectl get vpcendpointsubnetassociations -o yaml — the crossplane.io/external-name annotation alternates between <vpc_endpoint_id>/<subnet_id> and a-<vpc_endpoint_id><number>, and resourceVersion climbs continuously.

Fix

Make GetExternalNameFn and GetIDFn both deterministic from the named fields (same approach as #1975): external name = vpc_endpoint_id/child_id, Terraform id = a-<vpc_endpoint_id><hashcode(child_id)>. PR to follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions