AWS PrivateLink

Secure, Private Connectivity for Your AWS Architecture

📋 Table of Contents

🔐 What is AWS PrivateLink?

AWS PrivateLink is a highly available, scalable technology that enables you to privately connect your VPC to supported AWS services, services hosted by other AWS accounts (VPC endpoint services), and supported AWS Marketplace partner services. It provides a secure way to access services without requiring the traffic to traverse the public internet.

🛡️ Enhanced Security

Traffic never leaves the AWS network, eliminating exposure to internet-based threats

🚀 Improved Performance

Reduced latency and increased bandwidth through private connectivity

📊 Simplified Network Architecture

No need for NAT gateways, internet gateways, or VPN connections

💰 Cost Optimization

Reduce data transfer costs and eliminate NAT gateway charges

🔧 Key Components

🏗️ Architecture Overview

graph TB subgraph "Consumer VPC" A[EC2 Instance] --> B[VPC Endpoint] C[Lambda Function] --> B end subgraph "AWS PrivateLink" B --> D[PrivateLink Connection] end subgraph "Provider Side" D --> E[Network Load Balancer] E --> F[Target Service] E --> G[Target Service] end subgraph "AWS Services" D --> H[S3] D --> I[DynamoDB] D --> J[EC2 API] end style A fill:#e1f5fe style B fill:#f3e5f5 style D fill:#fff3e0 style E fill:#e8f5e8

🔍 Architecture Diagram Explanation:

Consumer VPC: Your private network containing EC2 instances and Lambda functions that need to access services privately.

VPC Endpoint: The entry point in your VPC that enables private connectivity. Acts as a gateway for all PrivateLink traffic.

PrivateLink Connection: The secure, private tunnel that routes traffic without traversing the public internet.

Provider Side: Services hosted by other AWS accounts or third parties, fronted by Network Load Balancers for high availability.

AWS Services: Native AWS services like S3, DynamoDB, and EC2 API that can be accessed privately through PrivateLink.

📋 Detailed Component Analysis:

VPC Endpoints come in two types:

  • Gateway Endpoints: Used for S3 and DynamoDB, route traffic through route table entries. No hourly charges, only data processing fees.
  • Interface Endpoints: Used for all other AWS services and custom services. Create ENIs in your subnets with private IP addresses.

Network Load Balancer Role: For custom endpoint services, the NLB acts as the front-end that receives traffic from PrivateLink and distributes it to your backend services. It operates at Layer 4 (TCP/UDP) and can handle millions of requests per second while maintaining ultra-low latencies.

Security Benefits: All communication flows through AWS's private network backbone, eliminating exposure to DDoS attacks, data interception, and other internet-based threats. Traffic is encrypted in transit and never touches public routing tables.

Multi-AZ Deployment: Interface endpoints can be deployed across multiple Availability Zones for high availability. Each AZ gets its own network interface, ensuring service continuity even if an entire AZ becomes unavailable.

🔄 Traffic Flow

sequenceDiagram participant Client as Client Application participant VE as VPC Endpoint participant PL as PrivateLink participant NLB as Network Load Balancer participant Service as Target Service Client->>VE: 1. API Call VE->>PL: 2. Route through PrivateLink PL->>NLB: 3. Forward to Load Balancer NLB->>Service: 4. Distribute to Service Service->>NLB: 5. Response NLB->>PL: 6. Return via PrivateLink PL->>VE: 7. Back to VPC Endpoint VE->>Client: 8. Response to Client

🔄 Traffic Flow Sequence Explanation:

Step 1-2: Your application makes an API call which is intercepted by the VPC Endpoint and routed through the private PrivateLink network.

Step 3-4: PrivateLink forwards the request to the Network Load Balancer, which distributes traffic across healthy service instances.

Step 5-8: The response follows the reverse path, ensuring all traffic remains within the AWS private network backbone.

Key Benefit: At no point does traffic traverse the public internet, providing enhanced security, performance, and reliability.

🛠️ Detailed Traffic Flow Analysis:

DNS Resolution Process: When your application makes a call to an AWS service (e.g., s3.amazonaws.com), the VPC's DNS resolver redirects the request to the VPC endpoint's private IP address instead of the public IP. This happens transparently without any code changes.

Connection Establishment: The VPC endpoint establishes a persistent connection to the PrivateLink service. This connection is multiplexed, meaning multiple requests from different sources can share the same underlying connection for efficiency.

Load Balancing Strategy: The Network Load Balancer uses flow hash algorithm (source IP, source port, destination IP, destination port, protocol) to ensure session affinity. This means requests from the same source will consistently route to the same backend target, which is crucial for stateful applications.

Health Checking: The NLB continuously monitors the health of backend targets using configurable health checks. Unhealthy targets are automatically removed from the rotation, and traffic is redistributed to healthy instances.

Performance Characteristics: PrivateLink typically reduces latency by 10-50ms compared to internet routing, depending on geographic location. Bandwidth is not limited by NAT gateway constraints, often resulting in 2-3x better throughput for data-intensive operations.

Failure Scenarios: If the primary AZ's endpoint becomes unavailable, traffic automatically fails over to endpoints in other AZs within seconds. The service maintains connection state and can resume operations transparently.

💼 Common Use Cases

🏢 Multi-Account Architecture

Securely connect services across different AWS accounts without exposing them to the internet. Perfect for organizations with separate development, staging, and production accounts.

🏪 SaaS Integration

Provide customers with private access to your SaaS application, enabling them to consume your services without internet exposure.

📊 Data Analytics Pipeline

Connect analytics workloads to AWS services like S3, Redshift, or Kinesis privately, ensuring sensitive data never traverses the public internet.

🏭 Hybrid Cloud Connectivity

Extend on-premises infrastructure to AWS services securely through AWS Direct Connect and PrivateLink.

📈 Detailed Use Case Examples

Example 1: Cross-Account Database Access

A common enterprise scenario where the production database resides in a separate AWS account from the application servers for security and compliance reasons.

graph TB subgraph "Application Account (111111111111)" A1[Web Application] --> A2[Application Load Balancer] A2 --> A3[EC2 Auto Scaling Group] A3 --> A4[VPC Endpoint] A4 --> A5[PrivateLink Connection] end subgraph "Database Account (222222222222)" A5 --> B1[Network Load Balancer] B1 --> B2[RDS Proxy] B2 --> B3[Amazon RDS Primary] B2 --> B4[Amazon RDS Read Replica] end subgraph "Security Controls" C1[IAM Cross-Account Role] C2[Security Groups] C3[VPC Endpoint Policy] end style A1 fill:#e3f2fd style B3 fill:#f3e5f5 style A5 fill:#fff3e0 style B1 fill:#e8f5e8

🔍 Cross-Account Database Access Explanation:

Application Account: Contains the web tier and application logic, isolated from sensitive data infrastructure.

Database Account: Houses the RDS instances and data infrastructure with strict access controls.

PrivateLink Connection: Enables private connectivity between accounts without VPC peering or transit gateways.

RDS Proxy: Provides connection pooling, failover handling, and enhanced security for database connections.

Security Benefits: Database traffic never leaves AWS backbone, supports fine-grained IAM controls, and maintains network isolation.

🗄️ RDS Proxy Deep Dive

Amazon RDS Proxy is a fully managed database proxy service that sits between your applications and RDS databases. It's particularly powerful when combined with PrivateLink for cross-account or private database access scenarios.

graph TB subgraph "Application Layer" A1[Web Application] --> A2[Connection Pool 1] A3[Background Jobs] --> A4[Connection Pool 2] A5[Analytics Service] --> A6[Connection Pool 3] end subgraph "RDS Proxy Layer" A2 --> P1[RDS Proxy] A4 --> P1 A6 --> P1 P1 --> P2[Connection Multiplexing] P1 --> P3[Health Monitoring] P1 --> P4[IAM Authentication] P1 --> P5[Secret Management] end subgraph "Database Layer" P2 --> D1[Primary RDS Instance] P2 --> D2[Read Replica 1] P2 --> D3[Read Replica 2] P3 --> D1 P3 --> D2 P3 --> D3 end subgraph "Failure Scenarios" F1[Primary Failover] --> F2[Automatic Promotion] F2 --> F3[Connection Rerouting] F3 --> F4[<30s Recovery] end style P1 fill:#e8f5e8 style P2 fill:#f3e5f5 style D1 fill:#e3f2fd style F4 fill:#fff3e0

🔧 RDS Proxy Core Functions:

Connection Pooling: Maintains a pool of database connections and multiplexes application requests, reducing connection overhead and improving performance.

Health Monitoring: Continuously monitors database health and automatically removes unhealthy instances from the connection pool.

Failover Management: Handles RDS failover scenarios transparently, maintaining application connections during database failover events.

IAM Integration: Supports IAM database authentication, eliminating the need to manage database passwords in application code.

Secrets Manager Integration: Automatically retrieves and rotates database credentials from AWS Secrets Manager.

RDS Proxy Benefits & Use Cases

graph LR subgraph "Without RDS Proxy" W1[App Instance 1] --> W4[Direct DB Connection] W2[App Instance 2] --> W5[Direct DB Connection] W3[App Instance 3] --> W6[Direct DB Connection] W4 --> W7[Database] W5 --> W7 W6 --> W7 W8[Connection Limit: 100] --> W7 W9[Failover: 2-3 minutes] --> W7 end subgraph "With RDS Proxy" P1[App Instance 1] --> P4[RDS Proxy] P2[App Instance 2] --> P4 P3[App Instance 3] --> P4 P4 --> P5[Optimized Connections] P5 --> P6[Database] P7[Connection Limit: 1000+] --> P6 P8[Failover: <30 seconds] --> P6 end style W7 fill:#fef2f2 style P6 fill:#e8f5e8 style P4 fill:#f3e5f5

📊 RDS Proxy Advantages:

Scalability: Supports thousands of concurrent connections while maintaining optimal database connection counts.

Availability: Reduces failover time from 2-3 minutes to under 30 seconds by maintaining persistent connections.

Security: Enforces SSL/TLS encryption and integrates with IAM for fine-grained access control.

Performance: Reduces database CPU utilization by up to 50% through connection reuse and query optimization.

Serverless Compatibility: Perfect for Lambda functions and other serverless workloads that create many short-lived connections.

🛠️ RDS Proxy Configuration with PrivateLink

# Step 1: Create IAM role for RDS Proxy
aws iam create-role \
    --role-name rds-proxy-role \
    --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [{
            "Effect": "Allow",
            "Principal": {"Service": "rds.amazonaws.com"},
            "Action": "sts:AssumeRole"
        }]
    }'

# Attach policy for Secrets Manager access
aws iam attach-role-policy \
    --role-name rds-proxy-role \
    --policy-arn arn:aws:iam::aws:policy/AmazonRDSProxyRole

# Step 2: Create database credentials in Secrets Manager
aws secretsmanager create-secret \
    --name prod-db-credentials \
    --description "Production database credentials" \
    --secret-string '{
        "username": "dbadmin",
        "password": "SecurePassword123!",
        "engine": "postgres",
        "host": "prod-db.cluster-xyz.us-west-2.rds.amazonaws.com",
        "port": 5432,
        "dbname": "productiondb"
    }'

📝 Prerequisites Setup:

IAM Role: RDS Proxy needs permissions to access Secrets Manager and RDS resources

Secrets Manager: Stores database credentials securely with automatic rotation capabilities

Policy Attachment: AmazonRDSProxyRole provides the minimum required permissions

# Step 3: Create RDS Proxy
aws rds create-db-proxy \
    --db-proxy-name production-db-proxy \
    --engine-family POSTGRESQL \
    --auth '{
        "AuthScheme": "SECRETS",
        "SecretArn": "arn:aws:secretsmanager:us-west-2:123456789012:secret:prod-db-credentials-AbCdEf",
        "IAMAuth": "REQUIRED"
    }' \
    --role-arn arn:aws:iam::123456789012:role/rds-proxy-role \
    --vpc-subnet-ids subnet-db-1a subnet-db-1b subnet-db-1c \
    --vpc-security-group-ids sg-rds-proxy \
    --require-tls \
    --idle-client-timeout 1800 \
    --max-connections-percent 100 \
    --max-idle-connections-percent 50

# Step 4: Register RDS target with proxy
aws rds register-db-proxy-targets \
    --db-proxy-name production-db-proxy \
    --target-group-name default \
    --db-cluster-identifiers prod-db-cluster

📝 RDS Proxy Configuration:

--engine-family: Specifies database engine (MYSQL, POSTGRESQL, SQLSERVER)

IAMAuth REQUIRED: Enforces IAM authentication for enhanced security

--require-tls: Ensures all connections are encrypted

--max-connections-percent: Percentage of max_connections that proxy can use

--idle-client-timeout: Seconds before idle connections are closed (1800 = 30 minutes)

# Step 5: Create Network Load Balancer targeting RDS Proxy
# Get RDS Proxy endpoint
aws rds describe-db-proxies \
    --db-proxy-name production-db-proxy \
    --query 'DBProxies[0].Endpoint' \
    --output text

# Create target group for RDS Proxy
aws elbv2 create-target-group \
    --name rds-proxy-targets \
    --protocol TCP \
    --port 5432 \
    --vpc-id vpc-database-account \
    --target-type ip \
    --health-check-protocol TCP \
    --health-check-port 5432 \
    --health-check-interval-seconds 30 \
    --healthy-threshold-count 2 \
    --unhealthy-threshold-count 2

# Register RDS Proxy IP with target group
# Note: Get RDS Proxy IP using: nslookup 
aws elbv2 register-targets \
    --target-group-arn arn:aws:elasticloadbalancing:us-west-2:222222222222:targetgroup/rds-proxy-targets/abcdef1234567890 \
    --targets Id=10.0.1.100,Port=5432

📝 NLB Integration:

Target Type IP: Allows targeting RDS Proxy by its private IP address

Health Check Settings: Configured for database-specific health monitoring

TCP Protocol: Uses TCP health checks suitable for database connections

Proxy IP Discovery: Use nslookup or dig to find the RDS Proxy's private IP address

🤔 Why Do We Need a Network Load Balancer?

This is a common question that deserves a detailed explanation. The Network Load Balancer isn't for traditional load balancing in this scenario - it serves as the required entry point for PrivateLink endpoint services.

graph TB subgraph "PrivateLink Requirement" A1[VPC Endpoint Service] --> A2[MUST have NLB] A2 --> A3[Cannot directly target other resources] end subgraph "What NLB Enables" B1[Consumer VPC] --> B2[VPC Endpoint] B2 --> B3[PrivateLink Network] B3 --> B4[Network Load Balancer] B4 --> B5[Your Service] end subgraph "Without NLB (Not Possible)" C1[Consumer VPC] --> C2[VPC Endpoint] C2 --> C3[PrivateLink Network] C3 --> C4[❌ Direct to RDS Proxy] C3 --> C5[❌ Direct to EC2] C3 --> C6[❌ Direct to Lambda] end subgraph "NLB as Gateway Pattern" D1[Multiple Consumers] --> D2[Single NLB] D2 --> D3[Single RDS Proxy] D4[High Availability] --> D2 D5[Health Monitoring] --> D2 D6[Traffic Distribution] --> D2 end style A2 fill:#e8f5e8 style B4 fill:#f3e5f5 style C4 fill:#fef2f2 style C5 fill:#fef2f2 style C6 fill:#fef2f2 style D2 fill:#e3f2fd

🔧 NLB Role in PrivateLink Explained:

AWS Requirement: VPC Endpoint Services can ONLY be created with Network Load Balancers as targets. You cannot create an endpoint service that directly targets RDS, EC2 instances, Lambda functions, or other AWS services.

Gateway Function: The NLB acts as a "gateway" or "proxy" that receives traffic from PrivateLink and forwards it to your actual service (RDS Proxy in this case).

Single Point of Entry: Even if you have only one backend service, the NLB provides a consistent entry point that PrivateLink can connect to.

Future Flexibility: The NLB allows you to add multiple targets, implement health checks, and provide high availability without changing the PrivateLink configuration.

NLB Configuration Patterns

graph TB subgraph "Pattern 1: Single Service (Our RDS Example)" P1A[Consumer Apps] --> P1B[VPC Endpoint] P1B --> P1C[NLB] P1C --> P1D[Single RDS Proxy] P1E[Health Check] --> P1D P1F[Port 5432] --> P1C end subgraph "Pattern 2: Multiple Database Replicas" P2A[Consumer Apps] --> P2B[VPC Endpoint] P2B --> P2C[NLB] P2C --> P2D[RDS Proxy 1 - Primary] P2C --> P2E[RDS Proxy 2 - Replica] P2C --> P2F[RDS Proxy 3 - Replica] P2G[Round Robin] --> P2C end subgraph "Pattern 3: Multi-Service Endpoint" P3A[Consumer Apps] --> P3B[VPC Endpoint] P3B --> P3C[NLB] P3C --> P3D[API Service :80] P3C --> P3E[Database Service :5432] P3C --> P3F[Cache Service :6379] P3G[Port-based Routing] --> P3C end style P1C fill:#e8f5e8 style P2C fill:#f3e5f5 style P3C fill:#e3f2fd

📊 NLB Configuration Patterns:

Pattern 1 - Single Service: NLB forwards all traffic to one backend (our RDS Proxy example). Still provides health checking and consistent endpoint.

Pattern 2 - Load Distribution: NLB distributes traffic across multiple identical services for performance and availability.

Pattern 3 - Multi-Service: Single PrivateLink endpoint can expose multiple services on different ports through one NLB.

Key Insight: Even with one backend target, the NLB is mandatory for PrivateLink but provides valuable health monitoring and future scalability.

🛠️ Practical NLB Configuration Examples

# Scenario 1: Simple pass-through NLB (our RDS Proxy case)
aws elbv2 create-load-balancer \
    --name rds-proxy-gateway \
    --type network \
    --scheme internal \
    --subnets subnet-db-1a subnet-db-1b

# Create listener that simply forwards traffic
aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/rds-proxy-gateway/xyz \
    --protocol TCP \
    --port 5432 \
    --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/rds-proxy-targets/abc

📝 Simple Pass-Through Configuration:

--scheme internal: NLB only accessible within AWS network (required for PrivateLink)

TCP Protocol: Layer 4 forwarding with minimal processing overhead

Port Mapping: Client connects to port 5432 on NLB, traffic forwarded to port 5432 on RDS Proxy

No Load Balancing: Even with one target, NLB provides the required PrivateLink interface

# Scenario 2: Multi-port service exposure
aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/multi-service-nlb/xyz \
    --protocol TCP \
    --port 5432 \
    --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/postgres-targets/abc

aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/multi-service-nlb/xyz \
    --protocol TCP \
    --port 3306 \
    --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/mysql-targets/def

aws elbv2 create-listener \
    --load-balancer-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/multi-service-nlb/xyz \
    --protocol TCP \
    --port 6379 \
    --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/redis-targets/ghi

📝 Multi-Service Configuration:

Multiple Listeners: One NLB can expose multiple services on different ports through a single PrivateLink endpoint

Port-based Routing: Traffic to port 5432 goes to PostgreSQL, port 3306 to MySQL, port 6379 to Redis

Cost Efficiency: Single PrivateLink endpoint serves multiple services instead of creating separate endpoints

Simplified Management: Consumers only need to connect to one endpoint with different ports

# Check NLB health and status
aws elbv2 describe-load-balancers \
    --load-balancer-arns arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/rds-proxy-gateway/xyz

# Monitor target health
aws elbv2 describe-target-health \
    --target-group-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/rds-proxy-targets/abc

# View NLB metrics in CloudWatch
aws cloudwatch get-metric-statistics \
    --namespace AWS/NetworkELB \
    --metric-name ActiveFlowCount \
    --dimensions Name=LoadBalancer,Value=net/rds-proxy-gateway/xyz \
    --start-time 2025-01-01T00:00:00Z \
    --end-time 2025-01-01T01:00:00Z \
    --period 300 \
    --statistics Average

📝 NLB Monitoring and Health:

Load Balancer Status: Verify NLB is active and healthy across all AZs

Target Health: Confirm backend services (RDS Proxy) are passing health checks

Flow Metrics: Monitor active connections and data transfer through the NLB

Performance Insight: NLB adds minimal latency (<1ms) while providing the required PrivateLink interface

⚠️ Important NLB Considerations:
  • Required Component: NLB is mandatory for VPC Endpoint Services - you cannot bypass it
  • Cost Impact: NLB has hourly charges (~$16/month) plus data processing fees
  • Single Point: If NLB becomes unhealthy, the entire PrivateLink connection fails
  • Multi-AZ Deployment: Deploy NLB across multiple AZs for high availability
  • Security Groups: NLB doesn't use security groups - use target security groups instead

RDS Proxy Security & Performance Features

# Configure IAM database authentication
aws rds modify-db-proxy \
    --db-proxy-name production-db-proxy \
    --auth '{
        "AuthScheme": "SECRETS",
        "SecretArn": "arn:aws:secretsmanager:us-west-2:123456789012:secret:prod-db-credentials-AbCdEf",
        "IAMAuth": "REQUIRED",
        "ClientPasswordAuthType": "POSTGRES_SCRAM_SHA_256"
    }'

# Create IAM policy for database access
aws iam create-policy \
    --policy-name DatabaseAccessPolicy \
    --policy-document '{
        "Version": "2012-10-17",
        "Statement": [{
            "Effect": "Allow",
            "Action": "rds-db:connect",
            "Resource": "arn:aws:rds-db:us-west-2:123456789012:dbuser:prod-db-proxy/*"
        }]
    }'

# Example application connection with IAM auth
# Python boto3 example:
# import boto3
# import psycopg2
# 
# rds_client = boto3.client('rds')
# token = rds_client.generate_db_auth_token(
#     DBHostname='production-db-proxy.proxy-xyz.us-west-2.rds.amazonaws.com',
#     Port=5432,
#     DBUsername='app_user'
# )
# 
# conn = psycopg2.connect(
#     host='production-db-proxy.proxy-xyz.us-west-2.rds.amazonaws.com',
#     port=5432,
#     database='productiondb',
#     user='app_user',
#     password=token,
#     sslmode='require'
# )

📝 Advanced Security Features:

IAM Authentication: Applications use IAM credentials instead of database passwords

Token-Based Access: 15-minute authentication tokens eliminate long-lived passwords

SCRAM Authentication: Advanced password hashing for PostgreSQL connections

Fine-Grained Permissions: IAM policies control database user access at the resource level

Audit Trail: All database connections are logged through CloudTrail with IAM user identity

# Monitor RDS Proxy performance
aws logs create-log-group \
    --log-group-name /aws/rds/proxy/production-db-proxy

# Enable detailed monitoring
aws rds modify-db-proxy \
    --db-proxy-name production-db-proxy \
    --debug-logging

# CloudWatch metrics to monitor:
# - DatabaseConnections
# - DatabaseConnectionsCurrentlyBorrowed
# - DatabaseConnectionsCurrentlyInTransaction
# - DatabaseConnectionsCurrentlySessionPinned
# - MaxDatabaseConnectionsAllowed
# - QueryDatabaseResponseLatency
# - QueryRequestsNoTLS

📊 Performance Monitoring:

Connection Metrics: Track active, borrowed, and pinned connections for optimization

Latency Monitoring: Measure query response times through the proxy

Security Monitoring: Alert on non-TLS connections for security compliance

Debug Logging: Detailed logs for troubleshooting connection and query issues

Capacity Planning: Monitor connection utilization to plan scaling activities

🛠️ Configuration for Cross-Account Database Access

# Database Account (Provider): Create NLB targeting RDS Proxy
aws elbv2 create-load-balancer \
    --name database-access-nlb \
    --type network \
    --scheme internal \
    --subnets subnet-db-1a subnet-db-1b \
    --security-groups sg-database-nlb

# Create target group for RDS Proxy
aws elbv2 create-target-group \
    --name rds-proxy-targets \
    --protocol TCP \
    --port 5432 \
    --vpc-id vpc-database-account \
    --target-type ip \
    --health-check-protocol TCP \
    --health-check-port 5432

📝 Database Provider Setup:

--scheme internal: NLB is only accessible within AWS network, not from internet

--target-type ip: Allows targeting RDS Proxy by IP address for flexibility

--health-check-protocol TCP: Simple TCP health checks for database connectivity

# Register RDS Proxy with target group
aws elbv2 register-targets \
    --target-group-arn arn:aws:elasticloadbalancing:us-west-2:222222222222:targetgroup/rds-proxy-targets/abcdef1234567890 \
    --targets Id=10.0.1.100,Port=5432

# Create VPC Endpoint Service
aws ec2 create-vpc-endpoint-service-configuration \
    --network-load-balancer-arns arn:aws:elasticloadbalancing:us-west-2:222222222222:loadbalancer/net/database-access-nlb/xyz123 \
    --acceptance-required \
    --tag-specifications 'ResourceType=vpc-endpoint-service,Tags=[{Key=Name,Value=DatabaseService},{Key=Environment,Value=Production}]'
# Allow Application Account to connect
aws ec2 modify-vpc-endpoint-service-permissions \
    --service-id vpce-svc-database123 \
    --add-allowed-principals arn:aws:iam::111111111111:root

# Application Account (Consumer): Create VPC Endpoint
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-application-account \
    --service-name com.amazonaws.vpce.us-west-2.vpce-svc-database123 \
    --vpc-endpoint-type Interface \
    --subnet-ids subnet-app-1a subnet-app-1b \
    --security-group-ids sg-database-client \
    --policy-document file://database-endpoint-policy.json

📝 Cross-Account Connection Setup:

--add-allowed-principals: Grants specific AWS account permission to create endpoints

Service Name Format: Uses the VPC endpoint service ID in the standard AWS service name format

Multi-Subnet Deployment: Ensures high availability across multiple AZs

Example 2: SaaS Customer Private Access

A SaaS provider offering private API access to enterprise customers, eliminating internet exposure and providing better performance.

graph TB subgraph "Customer VPC (333333333333)" C1[Customer Applications] --> C2[VPC Endpoint] C3[Customer Data Pipeline] --> C2 C2 --> C4[PrivateLink Connection] end subgraph "SaaS Provider (444444444444)" C4 --> S1[Network Load Balancer] S1 --> S2[API Gateway Private] S1 --> S3[Direct Service Access] S2 --> S4[Lambda Functions] S3 --> S5[ECS Services] S4 --> S6[Business Logic] S5 --> S6 S6 --> S7[Data Layer] end subgraph "Monitoring & Security" M1[CloudWatch Metrics] M2[API Key Management] M3[Rate Limiting] end style C1 fill:#e8f5e8 style S1 fill:#fff3e0 style S6 fill:#f3e5f5 style C4 fill:#e3f2fd

🔍 SaaS Private Access Explanation:

Customer Benefits: Private connectivity eliminates data egress charges, improves latency, and meets compliance requirements for data isolation.

Provider Benefits: Differentiates service offering, enables premium pricing for private access, and reduces support burden from connectivity issues.

Dual Access Patterns: API Gateway for REST APIs with built-in features, or direct service access for custom protocols and maximum performance.

Scalability: NLB can handle millions of requests per second, auto-scaling backend services based on demand.

🛠️ Configuration for SaaS Private Access

# SaaS Provider: Create API Gateway VPC Link for private APIs
aws apigatewayv2 create-vpc-link \
    --name saas-private-api-link \
    --subnet-ids subnet-saas-1a subnet-saas-1b \
    --security-group-ids sg-api-gateway-link

# Create private API Gateway
aws apigatewayv2 create-api \
    --name saas-private-api \
    --protocol-type HTTP \
    --description "Private API for enterprise customers" \
    --cors-configuration AllowOrigins="*",AllowMethods="GET,POST,PUT,DELETE",AllowHeaders="*"

📝 API Gateway Private Setup:

VPC Link: Connects API Gateway to resources in your VPC privately

Protocol HTTP: Modern HTTP API with better performance and lower cost than REST API

CORS Configuration: Enables browser-based applications to access the API

# Create NLB for direct service access
aws elbv2 create-load-balancer \
    --name saas-service-nlb \
    --type network \
    --scheme internal \
    --subnets subnet-saas-1a subnet-saas-1b

# Create endpoint service for customer access
aws ec2 create-vpc-endpoint-service-configuration \
    --network-load-balancer-arns arn:aws:elasticloadbalancing:us-west-2:444444444444:loadbalancer/net/saas-service-nlb/xyz789 \
    --acceptance-required \
    --supported-platforms EC2-VPC

# Set up customer-specific access control
aws ec2 modify-vpc-endpoint-service-permissions \
    --service-id vpce-svc-saas123 \
    --add-allowed-principals arn:aws:iam::333333333333:root \
    --add-allowed-principals arn:aws:iam::555555555555:root

📝 Customer Access Management:

--acceptance-required: Allows manual approval of each customer connection for security

--supported-platforms EC2-VPC: Ensures compatibility with customer VPC environments

Granular Permissions: Each customer account is explicitly allowed, enabling audit trails and access control

# Customer Side: Create endpoint with custom DNS
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-customer-production \
    --service-name com.amazonaws.vpce.us-west-2.vpce-svc-saas123 \
    --vpc-endpoint-type Interface \
    --subnet-ids subnet-customer-1a subnet-customer-1b \
    --security-group-ids sg-saas-client \
    --private-dns-enabled \
    --policy-document file://saas-access-policy.json

# Create Route 53 private zone for custom domain
aws route53 create-hosted-zone \
    --name api.yourcompany.internal \
    --vpc VPCRegion=us-west-2,VPCId=vpc-customer-production \
    --caller-reference customer-saas-$(date +%s)

📝 Customer Configuration Benefits:

--private-dns-enabled: Enables automatic DNS resolution for AWS service endpoints

Custom Domain: Provides branded endpoint (api.yourcompany.internal) for easier application integration

Policy Control: Customer retains control over which services and actions are allowed through the endpoint

# Example saas-access-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalVpc": "vpc-customer-production"
                },
                "DateGreaterThan": {
                    "aws:CurrentTime": "2025-01-01T00:00:00Z"
                },
                "DateLessThan": {
                    "aws:CurrentTime": "2025-12-31T23:59:59Z"
                }
            }
        }
    ]
}

📝 Advanced Policy Features:

VPC Restriction: Ensures only traffic from customer's VPC can use the endpoint

Time-based Access: Automatically expires access based on contract terms

Audit Trail: All access attempts are logged with source VPC information

Compliance: Meets enterprise requirements for network isolation and access control

⚙️ Configuration & Setup

1️⃣ Creating a VPC Endpoint for AWS Services

# Create a VPC endpoint for S3
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-12345678 \
    --service-name com.amazonaws.us-west-2.s3 \
    --vpc-endpoint-type Gateway \
    --route-table-ids rtb-12345678

📝 Command Explanation:

--vpc-id: Specifies the VPC where the endpoint will be created

--service-name: The AWS service endpoint (format: com.amazonaws.region.service)

--vpc-endpoint-type: Gateway type for S3 and DynamoDB, Interface for other services

--route-table-ids: Route tables that will be updated with the endpoint routes

2️⃣ Creating an Interface Endpoint

# Create an interface endpoint for EC2 API
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-12345678 \
    --service-name com.amazonaws.us-west-2.ec2 \
    --vpc-endpoint-type Interface \
    --subnet-ids subnet-12345678 subnet-87654321 \
    --security-group-ids sg-12345678 \
    --policy-document file://endpoint-policy.json \
    --private-dns-enabled

📝 Command Explanation:

--subnet-ids: Subnets where endpoint network interfaces will be created (use multiple for HA)

--security-group-ids: Security groups controlling access to the endpoint

--policy-document: IAM policy controlling which actions are allowed through the endpoint

--private-dns-enabled: Enables private DNS names for the endpoint

3️⃣ Creating Endpoint Policy

# Create endpoint-policy.json file
cat > endpoint-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeImages",
                "ec2:DescribeSnapshots"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalVpc": "vpc-12345678"
                }
            }
        }
    ]
}
EOF

📝 Policy Explanation:

This policy restricts endpoint access to specific EC2 actions and ensures only resources within your VPC can use the endpoint. The condition aws:PrincipalVpc ensures that only requests originating from the specified VPC are allowed.

4️⃣ Security Group Configuration

# Create security group for VPC endpoint
aws ec2 create-security-group \
    --group-name vpc-endpoint-sg \
    --description "Security group for VPC endpoints" \
    --vpc-id vpc-12345678

# Add inbound rule for HTTPS traffic
aws ec2 authorize-security-group-ingress \
    --group-id sg-12345678 \
    --protocol tcp \
    --port 443 \
    --cidr 10.0.0.0/16

📝 Security Configuration:

Port 443: Required for HTTPS communication to AWS services

CIDR Block: Allow traffic from your VPC's CIDR range

Protocol: TCP is required for HTTPS connections

🚀 Advanced Configurations

🌐 Private DNS Deep Dive

Private DNS is a critical component of PrivateLink that enables seamless integration without code changes. Understanding how DNS resolution works in PrivateLink environments is essential for successful implementations.

DNS Resolution Architecture

graph TB subgraph "Application Layer" A1[Application Code] --> A2["API Call: s3.amazonaws.com"] end subgraph "DNS Resolution Process" A2 --> B1[VPC DNS Resolver] B1 --> B2{Private DNS Enabled?} B2 -->|Yes| B3[Route 53 Resolver] B2 -->|No| B4[Public DNS Resolution] B3 --> B5[Private Hosted Zone] B4 --> B6[Public DNS Servers] B5 --> B7["Returns: 10.0.1.100"] B6 --> B8["Returns: 52.95.142.x"] end subgraph "Traffic Routing" B7 --> C1[VPC Endpoint ENI] B8 --> C2[Internet Gateway] C1 --> C3[PrivateLink Network] C2 --> C4[Public Internet] C3 --> C5[AWS Service] C4 --> C5 end style B3 fill:#e8f5e8 style B5 fill:#f3e5f5 style C1 fill:#e3f2fd style C3 fill:#fff3e0

🔍 DNS Resolution Flow Explanation:

Application Layer: Your code makes standard AWS API calls using public service names like s3.amazonaws.com - no code changes required.

VPC DNS Resolver: AWS-provided DNS resolver at VPC CIDR +2 address (e.g., 10.0.0.2) handles all DNS queries within your VPC.

Private DNS Decision: When private DNS is enabled, Route 53 Resolver intercepts queries for AWS service domains and redirects them to private IP addresses.

Private Hosted Zone: AWS automatically creates and manages private hosted zones for each service endpoint, mapping service names to endpoint IPs.

Traffic Routing: With private DNS, traffic flows through the VPC endpoint; without it, traffic goes through the internet gateway.

Private DNS Configuration Options

graph TB subgraph "Option 1: AWS Managed Private DNS" O1A[Application] --> O1B["s3.amazonaws.com"] O1B --> O1C[AWS Route 53 Resolver] O1C --> O1D[Auto-Created Private Zone] O1D --> O1E["10.0.1.100 (VPC Endpoint)"] O1E --> O1F[S3 Service] end subgraph "Option 2: Custom Private DNS" O2A[Application] --> O2B["api.mycompany.internal"] O2B --> O2C[Customer Route 53 Zone] O2C --> O2D[Custom CNAME/A Record] O2D --> O2E["10.0.1.101 (Custom Endpoint)"] O2E --> O2F[Custom Service] end subgraph "Option 3: Manual DNS Management" O3A[Application] --> O3B["vpce-xxx.s3.us-west-2.vpce.amazonaws.com"] O3B --> O3C[VPC DNS Resolver] O3C --> O3D[Direct Endpoint Resolution] O3D --> O3E["10.0.1.102"] O3E --> O3F[S3 Service] end style O1D fill:#e8f5e8 style O2C fill:#f3e5f5 style O3D fill:#fff3e0

🔧 DNS Configuration Options Explained:

Option 1 - AWS Managed: Zero configuration, works automatically with existing code. AWS creates private hosted zones and manages DNS records.

Option 2 - Custom Private DNS: Provides branded endpoints for better user experience and easier service discovery in enterprise environments.

Option 3 - Manual Management: Direct endpoint access, useful for troubleshooting or when you need explicit control over DNS resolution.

Best Practice: Use Option 1 for AWS services, Option 2 for custom endpoint services, and Option 3 for debugging only.

DNS Resolution Troubleshooting Flow

flowchart TD A[DNS Query Initiated] --> B{VPC DNS Resolver?} B -->|No| C[Check VPC DHCP Options] B -->|Yes| D{Private DNS Enabled?} C --> C1[Fix DHCP Domain Name Servers] D -->|No| E[Query Goes to Public DNS] D -->|Yes| F{Private Hosted Zone Exists?} E --> E1[Traffic Routes via Internet] F -->|No| G[Check Endpoint Configuration] F -->|Yes| H{A/AAAA Record Found?} G --> G1[Enable Private DNS on Endpoint] H -->|No| I[Check Route 53 Records] H -->|Yes| J{Security Group Allows Port 53?} I --> I1[Create Missing DNS Records] J -->|No| K[Update Security Groups] J -->|Yes| L[DNS Resolution Successful] K --> L I1 --> L G1 --> L style L fill:#e8f5e8 style C1 fill:#fef2f2 style E1 fill:#fef2f2 style G1 fill:#f3e5f5

🔧 DNS Troubleshooting Guide:

VPC DNS Resolver Check: Ensure your VPC uses AWS-provided DNS (enableDnsSupport and enableDnsHostnames both true).

Private DNS Verification: Confirm that --private-dns-enabled is set when creating interface endpoints.

Security Group Rules: DNS requires outbound access on port 53 (UDP/TCP) to the VPC resolver.

Route 53 Records: For custom domains, verify A/CNAME records point to the correct endpoint addresses.

DHCP Options: Custom DHCP option sets may override default DNS servers - ensure domain-name-servers points to VPC resolver.

🛠️ DNS Configuration Commands

# Enable DNS support and hostnames on VPC (prerequisite)
aws ec2 modify-vpc-attribute \
    --vpc-id vpc-12345678 \
    --enable-dns-support

aws ec2 modify-vpc-attribute \
    --vpc-id vpc-12345678 \
    --enable-dns-hostnames

# Create interface endpoint with private DNS enabled
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-12345678 \
    --service-name com.amazonaws.us-west-2.s3 \
    --vpc-endpoint-type Interface \
    --subnet-ids subnet-12345678 subnet-87654321 \
    --security-group-ids sg-12345678 \
    --private-dns-enabled \
    --dns-options DnsRecordIpType=ipv4

📝 DNS Prerequisites:

--enable-dns-support: Enables AWS DNS resolver for the VPC at the reserved IP address (VPC CIDR +2)

--enable-dns-hostnames: Enables DNS hostnames for EC2 instances to resolve to private IP addresses

--private-dns-enabled: Creates private hosted zone entries for the AWS service domain

DnsRecordIpType: Specifies IPv4 records (ipv4), IPv6 records (ipv6), or both (dualstack)

# Create custom private hosted zone for endpoint service
aws route53 create-hosted-zone \
    --name api.internal.company.com \
    --vpc VPCRegion=us-west-2,VPCId=vpc-12345678 \
    --caller-reference dns-setup-$(date +%s) \
    --hosted-zone-config Comment="Private zone for internal API access",PrivateZone=true

# Get VPC endpoint DNS names
aws ec2 describe-vpc-endpoints \
    --vpc-endpoint-ids vpce-12345678 \
    --query 'VpcEndpoints[0].DnsEntries[*].[DnsName,HostedZoneId]' \
    --output table

# Create A record pointing to VPC endpoint
aws route53 change-resource-record-sets \
    --hosted-zone-id Z1D633PJN98FT9 \
    --change-batch '{
        "Changes": [{
            "Action": "CREATE",
            "ResourceRecordSet": {
                "Name": "api.internal.company.com",
                "Type": "A",
                "AliasTarget": {
                    "DNSName": "vpce-12345678-abcdefg.s3.us-west-2.vpce.amazonaws.com",
                    "EvaluateTargetHealth": false,
                    "HostedZoneId": "Z7HUB22UULQXV"
                }
            }
        }]
    }'

📝 Custom DNS Setup:

Private Hosted Zone: Creates a DNS zone that's only accessible from within the associated VPC

Caller Reference: Unique identifier for the request, using timestamp ensures uniqueness

Alias Target: Points to the VPC endpoint using AWS Route 53 alias functionality for better performance

Hosted Zone ID: Use the zone ID from the VPC endpoint description for alias records

# Verify DNS resolution is working correctly
# Run these commands from an EC2 instance in your VPC:

# Test AWS service DNS resolution
nslookup s3.amazonaws.com
dig s3.amazonaws.com

# Test custom domain resolution
nslookup api.internal.company.com
dig api.internal.company.com

# Verify the resolver being used
cat /etc/resolv.conf

# Test connectivity to resolved IP
curl -I https://s3.amazonaws.com
telnet $(nslookup s3.amazonaws.com | grep Address | tail -1 | cut -d' ' -f2) 443

📝 DNS Verification Commands:

nslookup/dig: Verify that service domains resolve to private IP addresses (10.x.x.x, 172.16-31.x.x, 192.168.x.x)

/etc/resolv.conf: Should show your VPC's DNS resolver IP address (typically VPC CIDR +2)

Connectivity Test: Confirms that the resolved IP addresses are reachable on the expected ports

Expected Results: Private IPs for AWS services indicate successful PrivateLink resolution

Advanced DNS Scenarios

# Scenario 1: Multi-region endpoint with failover DNS
aws route53 change-resource-record-sets \
    --hosted-zone-id Z1D633PJN98FT9 \
    --change-batch '{
        "Changes": [{
            "Action": "CREATE",
            "ResourceRecordSet": {
                "Name": "api-primary.company.com",
                "Type": "A",
                "SetIdentifier": "primary-us-west-2",
                "Failover": "PRIMARY",
                "TTL": 60,
                "ResourceRecords": [{"Value": "10.0.1.100"}]
            }
        }, {
            "Action": "CREATE", 
            "ResourceRecordSet": {
                "Name": "api-primary.company.com",
                "Type": "A",
                "SetIdentifier": "secondary-us-east-1",
                "Failover": "SECONDARY",
                "TTL": 60,
                "ResourceRecords": [{"Value": "10.1.1.100"}]
            }
        }]
    }'

# Scenario 2: Weighted routing for A/B testing
aws route53 change-resource-record-sets \
    --hosted-zone-id Z1D633PJN98FT9 \
    --change-batch '{
        "Changes": [{
            "Action": "CREATE",
            "ResourceRecordSet": {
                "Name": "api-test.company.com",
                "Type": "A",
                "SetIdentifier": "version-a",
                "Weight": 80,
                "TTL": 300,
                "ResourceRecords": [{"Value": "10.0.1.100"}]
            }
        }, {
            "Action": "CREATE",
            "ResourceRecordSet": {
                "Name": "api-test.company.com", 
                "Type": "A",
                "SetIdentifier": "version-b",
                "Weight": 20,
                "TTL": 300,
                "ResourceRecords": [{"Value": "10.0.1.101"}]
            }
        }]
    }'

📝 Advanced DNS Patterns:

Failover Routing: Automatically routes traffic to secondary endpoint if primary becomes unhealthy

Weighted Routing: Distributes traffic between different endpoint versions for A/B testing or gradual rollouts

Health Checks: Can be combined with Route 53 health checks for automated failover based on endpoint health

TTL Considerations: Lower TTLs enable faster failover but increase DNS query load

1️⃣ Creating a Custom Endpoint Service

# First, create a Network Load Balancer
aws elbv2 create-load-balancer \
    --name my-private-service-nlb \
    --type network \
    --scheme internal \
    --subnets subnet-12345678 subnet-87654321

# Create the endpoint service
aws ec2 create-vpc-endpoint-service-configuration \
    --network-load-balancer-arns arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/net/my-private-service-nlb/abcdef1234567890 \
    --acceptance-required \
    --tag-specifications 'ResourceType=vpc-endpoint-service,Tags=[{Key=Name,Value=MyPrivateService}]'

📝 Endpoint Service Configuration:

--network-load-balancer-arns: ARN of the NLB that will handle traffic

--acceptance-required: Requires manual approval for endpoint connections

--scheme internal: NLB is only accessible within AWS network

2️⃣ Cross-Account Access Configuration

# Allow specific AWS accounts to create endpoints
aws ec2 modify-vpc-endpoint-service-permissions \
    --service-id vpce-svc-12345678 \
    --add-allowed-principals arn:aws:iam::111122223333:root \
    --add-allowed-principals arn:aws:iam::444455556666:root

# Create endpoint in consumer account
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-consumer123 \
    --service-name com.amazonaws.vpce.us-west-2.vpce-svc-12345678 \
    --vpc-endpoint-type Interface \
    --subnet-ids subnet-consumer123

📝 Cross-Account Setup:

Service Provider: Grants permission to specific AWS accounts

Service Consumer: Creates endpoint using the service name format

The service name follows the pattern: com.amazonaws.vpce.region.vpce-svc-xxxxx

3️⃣ DNS Configuration for Custom Services

# Create Route 53 private hosted zone
aws route53 create-hosted-zone \
    --name myservice.internal \
    --vpc VPCRegion=us-west-2,VPCId=vpc-12345678 \
    --caller-reference $(date +%s)

# Create DNS record pointing to VPC endpoint
aws route53 change-resource-record-sets \
    --hosted-zone-id Z1234567890 \
    --change-batch file://dns-change.json
# dns-change.json content
{
    "Changes": [
        {
            "Action": "CREATE",
            "ResourceRecordSet": {
                "Name": "api.myservice.internal",
                "Type": "A",
                "AliasTarget": {
                    "DNSName": "vpce-12345678-abcdefg.ec2.us-west-2.vpce.amazonaws.com",
                    "EvaluateTargetHealth": false,
                    "HostedZoneId": "Z1HI4U5UVQT65I"
                }
            }
        }
    ]
}

📝 DNS Configuration:

Creates a private hosted zone for internal service discovery. The alias record points your custom domain to the VPC endpoint DNS name, enabling easy service discovery within your VPC.

📊 Monitoring & Troubleshooting

1️⃣ Enabling VPC Flow Logs

# Create IAM role for Flow Logs
aws iam create-role \
    --role-name flowlogsRole \
    --assume-role-policy-document file://flowlogs-trust-policy.json

# Create flow logs for VPC endpoint monitoring
aws ec2 create-flow-logs \
    --resource-type VPC \
    --resource-ids vpc-12345678 \
    --traffic-type ALL \
    --log-destination-type cloud-watch-logs \
    --log-group-name VPCFlowLogs \
    --deliver-logs-permission-arn arn:aws:iam::123456789012:role/flowlogsRole

📝 Flow Logs Benefits:

VPC Flow Logs help monitor traffic to and from your VPC endpoints, enabling you to troubleshoot connectivity issues and analyze traffic patterns.

2️⃣ CloudWatch Metrics and Alarms

# Create CloudWatch alarm for endpoint connectivity
aws cloudwatch put-metric-alarm \
    --alarm-name "VPCEndpoint-HighErrorRate" \
    --alarm-description "VPC Endpoint error rate is high" \
    --metric-name ClientErrorCount \
    --namespace AWS/PrivateLink \
    --statistic Sum \
    --period 300 \
    --threshold 10 \
    --comparison-operator GreaterThanThreshold \
    --evaluation-periods 2

📝 Monitoring Strategy:

This alarm monitors client errors to the VPC endpoint. Key metrics to monitor include ClientErrorCount, PacketDropCount, and ConnectionCount for comprehensive endpoint health monitoring.

3️⃣ Common Troubleshooting Commands

# Check endpoint status and configuration
aws ec2 describe-vpc-endpoints \
    --vpc-endpoint-ids vpce-12345678

# Verify route table entries
aws ec2 describe-route-tables \
    --filters "Name=vpc-id,Values=vpc-12345678"

# Test connectivity from EC2 instance
# Run on EC2 instance:
nslookup s3.amazonaws.com
curl -I https://s3.amazonaws.com

# Check security group rules
aws ec2 describe-security-groups \
    --group-ids sg-12345678

📝 Troubleshooting Steps:

1. Verify Endpoint Status: Ensure the endpoint is in "available" state

2. Check Route Tables: Confirm routes are properly configured

3. Test DNS Resolution: Verify private DNS is working correctly

4. Security Groups: Ensure proper inbound/outbound rules

⚠️ Common Issues:
  • Security groups blocking traffic on port 443
  • Route table missing endpoint routes (for Gateway endpoints)
  • DNS resolution issues when private DNS is disabled
  • Endpoint policy restricting required actions

🎯 Best Practices & Recommendations

🔒 Security Best Practices

💰 Cost Optimization

🚀 Performance Optimization