Virtual Private Clouds (VPC)
Using VPC Endpoints to Access Cloud Services Privately
Discover how to leverage VPC Endpoints and PrivateLink to connect to managed services like S3 or RDS without your traffic ever leaving the provider's internal backbone.
In this article
The Evolution of Cloud Perimeter Security
Traditional cloud networking models often rely on a centralized gateway to facilitate communication between private resources and public cloud services. While effective for basic connectivity, this approach forces sensitive internal traffic to traverse the public internet or at least cross the boundary into public IP space. This exposure creates a wider attack surface and introduces dependencies on external routing tables that are outside your direct control.
When an application running on a private instance needs to communicate with a managed database or storage service, it typically uses a NAT Gateway. The NAT Gateway translates private addresses to public ones and forwards packets through an internet gateway. This hop adds latency and creates a potential bottleneck for high-throughput applications that move large volumes of data.
Virtual Private Cloud endpoints represent a fundamental shift in this architecture by providing a private bridge between your network and the service provider. Instead of routing traffic out to the internet, these endpoints keep data within the provider's internal fiber backbone. This effectively extends your private network perimeter to include the managed services your application depends on.
Architectural security is not merely about blocking inbound traffic, but about ensuring that every outbound request follows the shortest and most secure path possible without touching the public internet.
Architectural Patterns: Gateway vs Interface Endpoints
Not all cloud endpoints are created equal, and understanding the distinction between Gateway and Interface types is critical for proper network design. Gateway endpoints are a specialized type that modify your VPC routing table to direct traffic toward specific services. Currently, this model is primarily used for high-volume storage and NoSQL services like S3 and DynamoDB.
Interface endpoints are powered by PrivateLink technology and function quite differently. They manifest as Elastic Network Interfaces with private IP addresses directly within your subnets. This makes them appear as local resources within your network, allowing for more granular security group control and simpler cross-region connectivity.
- Gateway Endpoints: Free of charge, use prefix lists in route tables, and support only specific regional services.
- Interface Endpoints: Hourly fee per ENI, charged per GB processed, and support a wide range of first-party and third-party services.
- Network Reachability: Gateway endpoints are not reachable from on-premises via VPN or Direct Connect without complex proxy setups, whereas Interface endpoints are natively reachable.
1resource "aws_vpc_endpoint" "s3_gateway" {
2 vpc_id = var.vpc_id
3 service_name = "com.amazonaws.us-east-1.s3"
4 # Gateway endpoints do not use security groups
5 vpc_endpoint_type = "Gateway"
6
7 # Associate with private route tables
8 route_table_ids = var.private_route_table_ids
9
10 tags = {
11 Environment = "production"
12 Service = "storage"
13 }
14}The Mechanics of Traffic Redirection
When you deploy a Gateway endpoint, the cloud provider adds a prefix list entry to your designated route tables. When an instance attempts to reach the service, the routing logic identifies the prefix list and directs the packet to the endpoint instead of the default gateway. This process is transparent to the application and requires no code changes.
Interface endpoints rely on DNS resolution to function effectively. When you enable private DNS for an Interface endpoint, the provider creates a private hosted zone that overrides the public DNS record for the service. Your application continues to call the standard service URL, but the local DNS resolver returns the private IP address of the endpoint interface instead of a public IP.
Securing the Wire with Endpoint Policies
Establishing a private connection is only the first step in a defense-in-depth strategy. While security groups control which instances can reach the endpoint, VPC Endpoint Policies control what actions can be performed through that endpoint. This allows you to implement fine-grained authorization at the network layer, independent of the identity-based policies attached to your users or roles.
An endpoint policy can prevent your internal users from accidentally or intentionally uploading data to buckets outside of your organization. By defining a policy that only allows access to specific resource ARNs, you create a logical sandbox. Even if an attacker steals credentials, they would be unable to use your network to move data to an external account they control.
1{
2 "Statement": [
3 {
4 "Action": "s3:GetObject",
5 "Effect": "Allow",
6 "Resource": "arn:aws:s3:::company-confidential-data/*",
7 "Principal": "*"
8 },
9 {
10 "Action": "s3:*",
11 "Effect": "Deny",
12 "Resource": "*",
13 "Principal": "*",
14 "Condition": {
15 "StringNotEquals": {
16 "s3:ResourceAccount": "123456789012"
17 }
18 }
19 }
20 ]
21}Policy Evaluation Logic
It is important to remember that endpoint policies do not replace IAM policies; they act as an additional filter. For a request to succeed, it must be allowed by the user policy, the resource policy, and the endpoint policy. If any of these layers explicitly denies the request, the entire operation is blocked.
When designing these policies, start with a restrictive posture and gradually add permissions as needed. Use conditions like StringEquals or Null to ensure that requests originate from expected VPCs or use specific encryption keys. This multi-layered approach ensures that even a compromise in one area does not lead to a total system breach.
Implementing PrivateLink for Custom Services
The power of PrivateLink extends beyond just cloud-native services. You can use this technology to share your own internal services across different VPCs or even different accounts without peering them together. This is particularly useful in microservices architectures where different teams own different network boundaries but need to consume each other's APIs safely.
Creating a service provider involves setting up a Network Load Balancer that sits in front of your application instances. Once the load balancer is configured, you create an Endpoint Service configuration and share the service name with your consumers. The consumer then creates an Interface endpoint pointing to your service, establishing a one-way private link.
This pattern solves the common problem of overlapping IP CIDR blocks. Since PrivateLink maps the service to an IP in the consumer's local subnet, it does not matter if the provider and consumer VPCs use the same internal IP ranges. This makes it an ideal solution for SaaS providers who need to connect to diverse customer environments with unpredictable network configurations.
Handling Scalability and High Availability
To ensure high availability for your Interface endpoints, you should deploy them across multiple availability zones. Each availability zone will have its own network interface and unique IP address. The provider's DNS system will automatically handle load balancing across these interfaces to ensure traffic is distributed evenly.
If an availability zone experiences an outage, the DNS health checks will detect the failure and stop returning the IP address for the affected interface. This ensures that your application remains resilient even during localized infrastructure issues. Always verify that your application's client libraries support DNS caching durations that respect these rapid changes.
Monitoring, Troubleshooting, and Best Practices
Visibility into endpoint traffic is essential for maintaining a healthy infrastructure. You should enable VPC Flow Logs to monitor the traffic passing through your endpoints. These logs provide detailed information about source IPs, destination IPs, and whether packets were accepted or rejected by your security groups.
Another common pitfall involves the Maximum Transmission Unit or MTU settings. Interface endpoints support a specific MTU size, and if your application sends larger packets, they may be dropped or fragmented, leading to performance degradation. Ensure that your network configurations and application layers are tuned to handle the standard 1500-byte MTU usually found in these environments.
When troubleshooting connectivity issues, always start at the DNS layer. Use tools like dig or nslookup from within your instance to confirm that the service name resolves to a private IP rather than a public one. If it resolves correctly but the connection times out, verify that your security groups allow outbound traffic on the required ports to the endpoint interfaces.
Continuous monitoring of endpoint metrics, such as bytes processed and connection errors, is the only way to proactively manage capacity and prevent silent failures in complex distributed systems.
Optimizing for Cost and Performance
For services like S3, always prefer Gateway endpoints over Interface endpoints to save on data processing costs. Use Interface endpoints only when you need to access S3 from an on-premises network or a different region. This hybrid approach allows you to balance the need for connectivity with the goal of minimizing unnecessary expenditures.
Consider the throughput requirements of your application when selecting the subnets for your Interface endpoints. Distributing endpoints across all active subnets ensures that you do not saturate the bandwidth of a single network interface. Regularly audit your endpoints to remove those that are no longer in use, as the hourly ENI fees can accumulate over time in large environments.
