Skip to content

EC2 Instance in Dual-Stack VPC Cannot Reach S3 via Gateway Endpoint

0

Hello,

I am encountering a persistent networking issue where an EC2 instance, launched via CloudFormation in a public subnet of a dual-stack VPC, with Private IPv4 and public-routable IPv6 but no Public IPv4, is unable to establish connectivity to Amazon S3 via a configured S3 VPC Gateway Endpoint.

A ping test to s3.us-west-2.amazonaws.com from the EC2 instance consistently shows 100% packet loss. This prevents aws s3 cli from working.

Configuration Details:

  • VPC Type: Dual-stack.
  • EC2 Instance: Launched in a public subnet (IPv4 and IPv6 enabled without a public IPv4).
  • S3 VPC Gateway Endpoint: Configured within the same VPC and associated with the public subnet's route table.
  • IAM Role for EC2: Has necessary s3:GetObject and s3:ListBucket permissions for the target S3 bucket.
  • S3 Bucket Policy: No explicit denying policies are present on the target S3 bucket.
  • EC2 Security Group: Egress rules allow all outbound IPv6 traffic (::/0).
  • UserData Script: Includes a ping test to s3.<us-west-2>.amazonaws.com which fails.

Relevant CloudFormation Template Snippets:

(NOTE: template has been de-identified and summarized by AI and may contain errors not present in the actual attempted deployment)

  RendezvousEc2Instance:
    Type: AWS::EC2::Instance
    Properties:
      # ... other properties ...
      NetworkInterfaces:
        - DeviceIndex: 0
          GroupSet:
            - !GetAtt RendezvousEc2SecurityGroup.GroupId
          SubnetId: !ImportValue
            Fn::Sub: "CorePublicSubnet1Id-${EnvironmentName}" # Using a public subnet for IPv6 internet access
          Ipv6AddressCount: 1
          AssociatePublicIpAddress: false # Explicitly set to false for IPv6-only instance.
      # ... other properties ...

  S3VpcEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !ImportValue
        Fn::Sub: "CoreVpcId-${EnvironmentName}"
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"
      RouteTableIds:
        - !ImportValue
          Fn::Sub: "CorePublicSubnet1RouteTableId-${EnvironmentName}"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal: "*"
            Action:
              - "s3:GetObject"
              - "s3:ListBucket"
            Resource:
              - !Sub 'arn:aws:s3:::${ArtifactS3Bucket}'
              - !Sub 'arn:aws:s3:::${ArtifactS3Bucket}/*'

  RendezvousEc2LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      # ... other properties ...
      UserData: !Base64
          Fn::Sub:
            - |
              #!/bin/bash -xe
              set -e
              exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
              echo "Starting UserData script at $(date)"
              # ... Docker installation ...
              echo "Testing connectivity to S3 endpoint..."
              if ! ping -c 3 s3.us-west-2.amazonaws.com; then
                echo "ERROR: Failed to ping S3 endpoint. Network connectivity issue. Exiting UserData."
                exit 1
              fi
              echo "Connectivity to S3 endpoint successful."
              echo "Syncing Docker registry data from S3..."
              if ! aws s3 sync s3://${ArtifactS3Bucket}/registry-data /opt/registry-data; then
                echo "ERROR: Failed to sync Docker registry data from S3. Exiting UserData."
                exit 1
              fi
              echo "Registry data synced."
              # ... rest of script ...
            - LambdaFunctionUrl: !GetAtt RendezvousCfnSignalLambdaFunctionUrl.FunctionUrl

Observed Behavior:

  • EC2 instance fails to ping s3.us-west-2.amazonaws.com with 100% packet loss.
  • A critical aws s3 sync command within the UserData script hangs, leading to script termination.
  • CloudFormation stack deployments consistently fail due to the UserData script exiting prematurely.

Expected Behavior: The EC2 instance should be able to successfully communicate with Amazon S3 via the S3 VPC Gateway Endpoint, allowing the aws s3 sync command to complete.

Troubleshooting Steps Taken:

  1. IAM Permissions: Verified that the EC2 instance's IAM role has s3:GetObject and s3:ListBucket permissions.
  2. S3 Bucket Policy: Confirmed that the target S3 bucket has no explicit denying policies.
  3. EC2 Security Group: Verified that the EC2 instance's security group has an egress rule allowing all IPv6 outbound traffic.
  4. S3 VPC Endpoint Configuration:
    • The S3 VPC Endpoint resource is defined in the CloudFormation template.
    • It is configured to associate with the public subnet's route table.
    • AWS CLI commands confirm the S3 VPC Endpoint is in CREATE_COMPLETE state.
    • However, inspecting the associated route table shows no automatically injected route for the S3 Prefix List pointing to the VPC Endpoint.
  5. Manual Route Creation Attempt: Attempted to manually create the missing route using aws ec2 create-route, but it failed with InvalidParameterValue: Cannot create or replace a prefix list route targeting a VPC Endpoint., indicating that the endpoint is expected to manage its own routes.
  6. UserData Script Enhancements: Added a ping test and explicit error handling to the UserData script, confirming the network issue.

The core issue appears to be that the S3 VPC Gateway Endpoint is not correctly injecting its routes into the associated route table, despite being configured to do so within the CloudFormation template. This prevents any traffic from the EC2 instance from reaching S3 privately.

The end-goal is to be able to access S3 from this EC2 instance without the addition of a NAT, Public IPv4, or any other cost-additive components.

Is there a solution?

3 Answers
1
Accepted Answer

After reviewing your post here are the key issues I have identified:

  1. The EC2 instance is IPv6-only (no public IPv4)
  2. S3 VPC Gateway Endpoints currently only support IPv4 (this is a fundamental limitation)
  3. The ping test to s3.us-west-2.amazonaws.com is failing
  4. The route table isn't showing the expected S3 prefix list routes

Proposed Solution:

  1. First, verify that your VPC endpoint is properly configured: aws ec2 describe-vpc-endpoints --filters Name=vpc-id,Values=<your-vpc-id>

  2. Modify your CloudFormation template to ensure proper routing. The S3 endpoint needs:

S3VpcEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcId: !ImportValue Fn::Sub: "CoreVpcId-${EnvironmentName}" ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" VpcEndpointType: Gateway RouteTableIds: - !ImportValue Fn::Sub: "CorePublicSubnet1RouteTableId-${EnvironmentName}"

  1. For the EC2 instance, confirm the network interface configuration:

RendezvousEc2Instance: Type: AWS::EC2::Instance Properties: NetworkInterfaces: - DeviceIndex: 0 SubnetId: !ImportValue Fn::Sub: "CorePublicSubnet1Id-${EnvironmentName}" Ipv6AddressCount: 1 AssociatePublicIpAddress: false

  1. Modify your UserData script to use the AWS CLI endpoint-url parameter: aws s3 sync
    --endpoint-url https://s3.${AWS::Region}.amazonaws.com
    s3://${ArtifactS3Bucket}/registry-data /opt/registry-data

  2. Remove the ping test since it's not a reliable indicator of S3 connectivity. Instead, use: aws s3 ls --endpoint-url https://s3.${AWS::Region}.amazonaws.com

Important Notes:

  1. Even with IPv6-only external connectivity, your EC2 instance still needs a private IPv4 address for internal VPC communication and VPC endpoint functionality.
  2. The S3 VPC Gateway Endpoint operates over IPv4 internally, even if your instance doesn't have public IPv4 connectivity.
  3. Make sure your security group allows outbound traffic on port 443 to the VPC endpoint.

Additional Verification Steps:

  1. Check route tables: aws ec2 describe-route-tables --route-table-ids <your-route-table-id>

  2. Verify endpoint policy: aws ec2 describe-vpc-endpoints --vpc-endpoint-ids <endpoint-id> --query 'VpcEndpoints[].PolicyDocument'

If you're still experiencing issues after implementing these changes, you can further debug by:

  1. Checking VPC Flow Logs
  2. Verifying DNS resolution for the S3 endpoint
  3. Testing with a simple AWS CLI command like aws s3 ls with debug logging: aws s3 ls --debug --endpoint-url https://s3.${AWS::Region}.amazonaws.com

The above solution maintains your goal of avoiding NAT Gateways or public IPv4 addresses while enabling S3 access through the VPC endpoint.

AWS
answered 8 months ago
  • The route tables was the problem, I did not have them on the subnet that was associated to the instance.

0

hi AlexR,

I wonder first checking the basics by SSH into your EC2 and run the command for connectivity and Verify S3 Gateway Endpoints with Traceroute and VPC Flow Logs ?

Verify S3 Gateway Enpoint for IPv4:-

traceroute -T -p 443 s3.us-west-2.amazonaws.com

traceroute will reveal, EC2's S3 traffic is routed privately through the Gateway Endpoint using the private IPv4 network inside AWS or if it reveals multiple network hops or public IP addresses, this means the traffic is routed over the internet instead and not through the Gateway Endpoint.

If you have enabled VPC Flow Logs, you can monitor and query the flow logs to verify S3 traffic routing through the Gateway Endpoint.

Happy Troubleshooting,

answered 8 months ago
-1

The issue you're experiencing is related to a fundamental limitation of gateway endpoints: they only support IPv4 traffic, not IPv6. Since your EC2 instance is configured with only IPv6 connectivity (no public IPv4 and no NAT gateway), it cannot use the S3 gateway endpoint.

When you create a gateway endpoint, it adds routes to your route tables that direct IPv4 traffic destined for the service (S3 in this case) to the endpoint. However, since gateway endpoints don't support IPv6 traffic, there's no route being added for IPv6 traffic to S3, which explains why you're not seeing the expected route in your route table.

Your ping test to s3.us-west-2.amazonaws.com is failing because:

  1. The gateway endpoint only works with IPv4 traffic
  2. Your instance doesn't have public IPv4 connectivity
  3. The ping is attempting to use IPv6, which can't route through the gateway endpoint

To resolve this issue, you have a few options:

  1. Assign a public IPv4 address to your EC2 instance (AssociatePublicIpAddress: true)
  2. Use a NAT gateway to allow your instance to access S3 via IPv4
  3. Consider using an S3 interface endpoint instead of a gateway endpoint, as interface endpoints can support IPv6 traffic (though they have additional costs)

The simplest solution would be to enable a public IPv4 address on your instance if your architecture allows for it. This would allow the instance to use the gateway endpoint via IPv4 while still maintaining its IPv6 connectivity for other purposes.
Sources
Gateway endpoints for Amazon S3 - Amazon Virtual Private Cloud
Gateway endpoints - Amazon Virtual Private Cloud

answered 8 months ago
  • This response doesn't quite make sense, considering the instance does have a Private IPv4 interface on the VPC.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.