amazon-web-servicesamazon-vpcaws-fargateaws-vpc-peering

AWS: connect to VPC endpoint in Accepter VPC from fargate task in Requester VPC


I have two VPCs within the same account and region, VPC-A and VPC-B. I have created a VPC peering connection between the two, where VPC-A is the accepter and VPC-B is the requester.

VPC-A contains a few Interface endpoints to be able to access AWS services (ECR, SSM, Logs) w/o a public IP (which works fine).

Now I'd like to start a Fargate task in VPC-B that also doesn't have a public IP, hoping I could use the peering connection to access the required endpoints in VPC-A, but I can't make it work.

When I start the fargate task in VPC-B, I get a CannotPullContainerError with the message:

request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

indicating that the endpoint can not be reached.

However, when I run a reachability analysis using the elastic network interface of the same task as source, and the desired VPC endpoint as destination, it returns a Reachable result with the expected path (IDs redacted):

enter image description here

I think I might be missing some configuration somewhere, but where? Or is this even possible?


Solution

  • Thinks DNS.

    Your fargate service needs to route com.amazonaws.eu-west-1.ecr.dkr etc to an IP address in vpc-b rather than over an internet gateway.

    I think when you create the endpoint and enable dns for it in vpc-a, it creates a private hosted zone with a record like:

    com.amazonaws.eu-west-1.ecr.dkr = [ip.address.1, ip.address.2]

    Each of the records in the array is an IP for the interface endpoint you have created. The private hosted zone is attached to VPC-A but hidden from you so you can't just attach it to VPC-B.

    I don't think there is any direct configuration you are missing, i.e the intent is for the interface endpoint to work within a single vpc.

    However there are ways you might make it work from vpc-b. These are untested, a bit hacky, maybe not worth the effort but could, maybe work.

    Option1:

    Create a private hosted for example for domain com.amazonaws.eu-west-1.ecr.dkr and attach it to vpc-b. Create an A record at the zone apex with multiple values for each of the IP addresses in vpc-a for your interface.

    You would need to repeat this for all the required interfaces so could be a bit tedious. Theoretically dns would resolve this record first and route it over the peering connection to the interface IP.

    Option2.

    https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions-hostentry.html

    You could try adding an entry for example for:

    com.amazonaws.eu-west-1.ecr.dkr=ip.address.1

    You could only add one IP address for a given domain this but in theory the task should route that traffic over the peering connection to the interface.

    Assumes your interface endpoint policy and security group would not block the network traffic.

    Again this may not work but might point you in the direction of where your issues are, hopefully anyway