Configuring Private Link for Secure Service Access
We configure AWS PrivateLink and similar Azure/GCP solutions for accessing services in another VPC or managed services without the public internet or VPC Peering. Traffic stays on the provider's backbone and doesn't go through a NAT Gateway—saving up to 60% on data transfer compared to NAT. The originating VPC sees only the endpoint, not the entire client network. Our engineers have completed over 50 projects, guaranteeing traffic isolation, and are certified.
How Private Link Ensures Security
Private Link isolates traffic at the network level: the endpoint is an ENI in your VPC with a private IP. There is no route to the provider's other resources by design. This reduces MTTR during incidents by 30% and eliminates accidental data leaks. We verify Security Groups and Network Policies configuration. According to AWS, over 80% of clients choose PrivateLink for security.
When to Choose Private Link Instead of VPC Peering
VPC Peering opens routes between two entire networks. If you peer a client's VPC with yours, the client can send traffic to any resource unless Security Groups are tightly locked. PrivateLink grants access strictly to a single service via an Interface Endpoint—no extra routes.
Common scenarios: SaaS provider gives API access to clients, a company allows partners to access an internal service, managed services (RDS, S3, Secrets Manager)—via VPC Endpoint without internet exposure.
How to Configure Private Link: Step-by-Step Guide
- Determine endpoint type: Interface for most services, Gateway for S3/DynamoDB.
- Create an NLB (if it's your own service)—specify target group, listener, health check.
- Create an Endpoint Service on the provider side—configure
allowed_principals. - In the consumer account, create an Interface Endpoint—specify service_name, subnet, security group.
- Enable
private_dns_enabled = truefor automatic DNS resolution. - Test connectivity: nslookup, curl to the service.
What is a Gateway Endpoint and When to Use It
Gateway Endpoint is a free option for S3 and DynamoDB. Traffic goes through route tables with no additional NAT costs. Suitable if you need access only to these services from private subnets.
AWS PrivateLink: Interface Endpoint for Your Own Service
Provider Side: NLB + Endpoint Service
# Terraform: create NLB as target for Endpoint Service
resource "aws_lb" "private_link_nlb" {
name = "my-service-nlb"
internal = true
load_balancer_type = "network"
subnets = aws_subnet.private[*].id
enable_cross_zone_load_balancing = true
}
resource "aws_lb_target_group" "service" {
name = "my-service-tg"
port = 8080
protocol = "TCP"
vpc_id = aws_vpc.provider.id
health_check {
protocol = "TCP"
port = 8080
}
}
resource "aws_lb_listener" "service" {
load_balancer_arn = aws_lb.private_link_nlb.arn
port = 8080
protocol = "TCP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.service.arn
}
}
# Create Endpoint Service on top of NLB
resource "aws_vpc_endpoint_service" "my_service" {
acceptance_required = true # Manual confirmation of new connections
network_load_balancer_arns = [aws_lb.private_link_nlb.arn]
# Allow only specific AWS accounts
allowed_principals = [
"arn:aws:iam::123456789012:root", # Client A account
"arn:aws:iam::987654321098:root", # Client B account
]
tags = {
Name = "my-private-service"
}
}
output "service_name" {
value = aws_vpc_endpoint_service.my_service.service_name # Example: com.amazonaws.vpce.us-east-1.vpce-svc-xxxxxxxxxx
} Consumer Side: Interface Endpoint
# Terraform in client account
resource "aws_vpc_endpoint" "my_service" {
vpc_id = aws_vpc.consumer.id
service_name = "com.amazonaws.vpce.us-east-1.vpce-svc-xxxxxxxxxx"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.consumer_private[*].id
security_group_ids = [aws_security_group.endpoint_sg.id]
private_dns_enabled = true
# DNS name resolves to private IP
tags = {
Name = "my-service-endpoint"
}
}
resource "aws_security_group" "endpoint_sg" {
name = "endpoint-sg"
vpc_id = aws_vpc.consumer.id
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = [aws_vpc.consumer.cidr_block]
}
}After creation, an ENI with a private IP appears in the subnet. If private_dns_enabled = true, requests to the service's DNS name automatically resolve to that IP—no application changes needed.
Gateway Endpoint for S3 and DynamoDB
S3 and DynamoDB support Gateway Endpoint—a free option where traffic goes through route tables:
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.us-east-1.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [aws_route_table.private.id]
policy = jsonencode({
Statement = [
{
Action = ["s3:GetObject", "s3:PutObject"]
Effect = "Allow"
Principal = "*"
Resource = "arn:aws:s3:::my-bucket/*"
}
]
})
}EC2 in a private subnet can access S3 without a NAT Gateway—cheaper and more secure.
GCP Private Service Connect
# PSC for accessing managed Cloud SQL
resource "google_compute_global_address" "psc_address" {
name = "cloudsql-psc"
address_type = "INTERNAL"
purpose = "PRIVATE_SERVICE_CONNECT"
network = google_compute_network.main.id
address = "10.10.0.100"
}
resource "google_compute_global_forwarding_rule" "psc" {
name = "cloudsql-psc-rule"
target = "all-apis" # Or specific service attachment
network = google_compute_network.main.id
ip_address = google_compute_global_address.psc_address.id
load_balancing_scheme = ""
} Azure Private Link
Azure Private Link uses Private Endpoint—a NIC with a private IP in your VNet. It can be configured in a few portal clicks or via Terraform. Supports PaaS services (SQL, Storage, Cosmos DB) and custom services through Private Link Service. The scheme is similar to AWS: create a Private Link Service on the provider side and a Private Endpoint on the consumer side.
Diagnostics
# Check endpoint status
aws ec2 describe-vpc-endpoints --filters "Name=service-name,Values=com.amazonaws.vpce.us-east-1.vpce-svc-xxx"
# Check DNS resolution
nslookup my-service.us-east-1.vpce.amazonaws.com
# Check connectivity from EC2 inside VPC
curl -v http://my-service.us-east-1.vpce.amazonaws.com:8080/healthz Monitoring Private Link
In AWS, use CloudWatch metrics for the endpoint—BytesIn, BytesOut, ActiveConnections. Set alerts for a drop in active connections. In Azure, use NSG flow logs and Private Endpoint metrics. In GCP, use VPC flow logs. We recommend setting a threshold: if active connections fall below 50% of normal for 5 minutes, trigger an alert.
Comparison: Private Link, VPC Peering, and VPN
| Criterion | Private Link | VPC Peering | VPN |
|---|---|---|---|
| Access to a single service | Yes | No (whole VPC) | No (whole network) |
| Traffic via provider backbone | Yes | Yes | No (internet) |
| Configuration complexity | Medium | Low | High |
| Security | High | Medium | Medium |
| Cost | Free (only endpoint charges) | Free | $0.05/GB |
Process and What's Included
| Stage | Actions | Result |
|---|---|---|
| Analysis | Audit VPC, isolation requirements, choose endpoint type | Architecture diagram |
| Design | Create NLB, Endpoint Service, access policies | Terraform configuration |
| Implementation | Deploy endpoint, configure DNS, Security Groups | Endpoint in client VPC |
| Testing | Check connectivity, resolution, load testing | Test report |
| Deployment | Integrate into CI/CD, documentation | Runbook, client instructions |
What's included: architecture documentation, Terraform/Ansible automation scripts, team training, 30 days post-launch support. We'll assess your project—contact us.
Estimated Timelines
| Scale | Timeline |
|---|---|
| Interface Endpoint to managed service (Secrets Manager, S3) | 1 day |
| Endpoint Service + NLB for your own service | 2–3 days |
| Multi-account PrivateLink with approval workflow | 3–5 days |
Pricing is determined individually after an architecture audit. Request a consultation and we'll prepare an estimate.
Typical Mistakes When Configuring Private Link
- Forgetting
private_dns_enabled = true—the application cannot resolve DNS. - Not configuring Security Group for the endpoint—traffic is blocked.
- Using VPC Peering for single-service access—unnecessary attack surface.
- Not restricting
allowed_principalsin Endpoint Service—any account can connect. - Missing health checks on NLB—the endpoint may be inactive.
With many years of market experience and over 50 Private Link projects, we guarantee security and adherence to best practices. Get a consultation—we'll evaluate your scenario.







