Back to: AWS-Basics-Advanced
Securely Exposing a Private NLB to the Internet Using ALB + VPC Endpoint Service
An application team needed to expose an internal service running behind a private Network Load Balancer (NLB) to the internet. However, the service itself was required to remain completely private, without directly attaching public IPs, NAT gateways, or internet-facing load balancers to the application subnets.
To achieve this, a joint solution was implemented by the Application Team and the Network Team using VPC Endpoint Service, Interface Endpoints, and a public ALB.
🟦 What We Achieve
We successfully built an architecture that allows public users to access a private NLB securely and indirectly.
At no point is the NLB publicly exposed.
🟩 How the Solution Works
1️⃣ Application Team
-
Deployed a Private NLB inside their VPC
-
Exposed the application over TCP/HTTP on a private port
-
Created a VPC Endpoint Service that fronts the Private NLB
-
Shared the Endpoint Service Name with the Network Team
This ensures the application remains internal, accessible only through authorized endpoints.
2️⃣ Network Team
-
Created a VPC Interface Endpoint (ENIs) to connect to the App Team’s Endpoint Service
-
The Interface Endpoint created private ENIs in their VPC (one per AZ)
-
These ENIs became the only allowed path into the Private NLB service
-
Then created a public ALB
-
Configured an IP-based Target Group containing the ENI private IPs
-
Mapped ALB listeners (HTTP/HTTPS) to this target group
This allowed the public ALB to forward traffic to the Interface Endpoint ENIs, and those ENIs connect privately to the NLB.
🟧 3️⃣ End Result: Secure Public Access to a Private System
✔ The ALB is public
✔ The target service stays private
✔ No direct route between Internet → Private NLB
✔ All traffic flows through a controlled, authorized chain
✔ No VPC peering, no transit gateway needed
✔ No private subnets are exposed
✔ No need to place application behind an internet-facing NLB
🟦 Final Flow of Traffic
🟩 Key Benefits
🔐 1. Security
-
Private NLB and application stay fully internal
-
Only authorized VPC interface endpoints can connect
-
No public exposure of backend services
🔄 2. Clean Separation of Responsibility
-
App team manages backend service + NLB
-
Network team manages public accessibility and routing
🌍 3. Public Access Without Public NLB
-
ALB is the only public entry point
-
Backend is 100% private
🔗 4. Flexible Cross-VPC / Cross-Account Access
-
Endpoint service supports cross-AZ, cross-region, even cross-account usage
PROPER STEP-BY-STEP IMPLEMENTATION
—————————————
🟦 PART 1: APP TEAM WORK
—————————————
STEP 1 — Create a Private Network Load Balancer
-
Go to EC2 → Load Balancers → Create Load Balancer
-
Select Network Load Balancer
-
Scheme: Internal
-
IP Address Type: IPv4
-
Select at least 2 private subnets
-
Create Listener:
-
Protocol: TCP
-
Port:
<APP_PORT>(example 80)
-
👉 This allows the NLB to be attached to a VPC Endpoint Service.
STEP 2 — Create Target Group for NLB
-
Target Type: Instance or IP (your backend)
-
Protocol: TCP
-
Port: 80
-
Register targets (EC2 private IPs / IPs)
STEP 3 — Create VPC Endpoint Service
-
Go to VPC → Endpoint Services → Create
-
Select your Private NLB
-
Set:
-
Acceptance Required: ON (recommended)
-
-
Add permissions:
-
Add Network Team AWS Account ID OR AWS Organization
- arn:aws:iam::094718051319:root
-
AWS generates a Service Name:
👉 Share this VPC Endpoint Service Name with Network Team.
—————————————
🟦 PART 2: NETWORK TEAM WORK
—————————————
STEP 4 — Create the VPC Interface Endpoint
-
Go to VPC → Endpoints → Create Endpoint
-
Type: Endpoint services that use NLBs and GWLBs
-
Paste the Service Name provided by App Team
-
Choose VPC
-
Choose private subnets in at least 2 AZs
-
Create a Security Group:
-
Allow inbound
<APP_PORT>from ALB Subnets
-
-
Create the endpoint
This creates one ENI per subnet, each with a private IP.
Example:
-
10.10.1.21 -
10.10.2.36
👉 Note these IPs — they will be added to ALB Target Group.
If “Acceptance Required” was enabled:
-
App Team must Accept the endpoint connection.
STEP 5 — Create a Public ALB
-
Go to Load Balancers → Create Load Balancer
-
Type: Application Load Balancer
-
Scheme: Internet-facing
-
Select public subnets
-
ALB Security Group:
-
Allow inbound 80/443 from Internet
-
Allow outbound to endpoint ENI IPs on 80
-
Listeners:
HTTP:
HTTPS (optional):
STEP 6 — Create ALB Target Group (VERY IMPORTANT)
-
Target Type: IP
-
Protocol:
Choose based on backend:
🔹 If app is HTTP → HTTP
🔹 If app is HTTPS → HTTPS
Always use the same port as Private NLB listener.
Example:
STEP 7 — Register ENI IPs as Targets
Add the Interface Endpoint ENI IPs:
Health checks:
-
Protocol: HTTP or TCP (match the target group type)
-
Path: “/” (for HTTP)
STEP 8 — Attach Target Group to ALB Listener
Select:
(And listener 443 if using HTTPS)
—————————————
🟩 FINAL CONNECTIVITY CHECK
—————————————
-
Hit your ALB DNS:
-
ALB forwards to IP Target Group
-
IPs are Interface Endpoint ENIs
-
ENIs forward to Private NLB via VPC Endpoint Service
-
Private NLB forwards to backend app
Everything is private except the ALB.