AWS CLI First #6: Advanced VPC: S3 Gateway Endpoints, Flow Logs & Reachability Simulator
Master enterprise VPC optimization and security auditing from the terminal. Learn how to eliminate NAT Gateway fees with zero-cost S3 Gateway Endpoints, capture traffic with VPC Flow Logs, apply Kubernetes subnet tags, and simulate packet routing with the Reachability Analyzer.
AWS with CLI: The Terminal-First Mastery Path
Part of the CLI-first comprehensive learning path from foundational setup to production cloud architectures.
In Part 5, we constructed our foundational multi-AZ VPC: provisioning custom subnets, Internet Gateways, NAT Gateways, and segregated Route Tables.
However, in enterprise production environments, a bare-bones VPC is not enough. Senior cloud architects must address four critical operational challenges:
- The Cost Trap: How do private servers download gigabytes of data from Amazon S3 without incurring expensive $0.045/GB NAT Gateway data transfer fees?
- The Compliance Requirement: How do security teams capture and audit network traffic metadata for SOC2, ISO 27001, and PCI-DSS compliance?
- The DevOps Standard: How do automated tools like the AWS Load Balancer Controller automatically discover where to deploy public and internal load balancers?
- The Verification Problem: How do we prove that a network route works without spending money to launch real virtual machines?
In this guide, we will solve all four challenges by diving into each advanced VPC phase with its underlying architectural concepts and hands-on CLI commands.
π° Estimated Lab Cost & Resource Architecture
| Component | Usage in Lab | AWS Free Tier | On-Demand Rate |
|---|---|---|---|
| S3 Gateway Endpoint | Zero-Cost Private VPC Endpoint | 100% Free | $0.00 |
| VPC Flow Logs & CloudWatch | Network Traffic Capture (~10 MB) | 5 GB/month Free | < $0.001 |
| VPC Reachability Analyzer | Packet Path Simulation (1β2 runs) | Pay-per-analysis | ~$0.01 / run |
| Total Estimated Cost | Complete Hands-On Session | ~$0.01 Total | ~$0.01 β $0.02 Total |
Prerequisites: Fast-Track VPC Provisioning
If you still have the Production-VPC running from Part 5, you can skip straight to Phase 1.
If you ran the teardown script at the end of Part 5 to save on NAT Gateway hourly charges, you can spin up the entire base VPC in 30 seconds with this 1-click script:
cat <<'EOF' > setup-base-vpc.sh
#!/usr/bin/env bash
set -e
PROFILE="cloud-dev-admin"
REGION="ap-southeast-1"
echo "=== Fast-Tracking Base VPC Provisioning for Part 6 ==="
# 1. Create VPC
VPC_ID=$(aws ec2 create-vpc \
--cidr-block "10.0.0.0/16" \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=Production-VPC}]' \
--profile "$PROFILE" --query "Vpc.VpcId" --output text)
aws ec2 modify-vpc-attribute --vpc-id "$VPC_ID" --enable-dns-support '{"Value":true}' --profile "$PROFILE"
aws ec2 modify-vpc-attribute --vpc-id "$VPC_ID" --enable-dns-hostnames '{"Value":true}' --profile "$PROFILE"
echo "Created VPC: $VPC_ID"
# 2. Create Subnets
PUB_SUB_A=$(aws ec2 create-subnet --vpc-id "$VPC_ID" --cidr-block "10.0.1.0/24" --availability-zone "${REGION}a" \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-A},{Key=Tier,Value=Public}]' \
--profile "$PROFILE" --query "Subnet.SubnetId" --output text)
PUB_SUB_B=$(aws ec2 create-subnet --vpc-id "$VPC_ID" --cidr-block "10.0.2.0/24" --availability-zone "${REGION}b" \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-B},{Key=Tier,Value=Public}]' \
--profile "$PROFILE" --query "Subnet.SubnetId" --output text)
aws ec2 modify-subnet-attribute --subnet-id "$PUB_SUB_A" --map-public-ip-on-launch --profile "$PROFILE"
aws ec2 modify-subnet-attribute --subnet-id "$PUB_SUB_B" --map-public-ip-on-launch --profile "$PROFILE"
PRIV_SUB_A=$(aws ec2 create-subnet --vpc-id "$VPC_ID" --cidr-block "10.0.10.0/24" --availability-zone "${REGION}a" \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-Subnet-A},{Key=Tier,Value=Private}]' \
--profile "$PROFILE" --query "Subnet.SubnetId" --output text)
PRIV_SUB_B=$(aws ec2 create-subnet --vpc-id "$VPC_ID" --cidr-block "10.0.20.0/24" --availability-zone "${REGION}b" \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-Subnet-B},{Key=Tier,Value=Private}]' \
--profile "$PROFILE" --query "Subnet.SubnetId" --output text)
# 3. Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=Production-IGW}]' \
--profile "$PROFILE" --query "InternetGateway.InternetGatewayId" --output text)
aws ec2 attach-internet-gateway --internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID" --profile "$PROFILE"
# 4. Elastic IP & NAT Gateway
EIP_ALLOC_ID=$(aws ec2 allocate-address --domain vpc --tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=NAT-Gateway-EIP}]' \
--profile "$PROFILE" --query "AllocationId" --output text)
NAT_GW_ID=$(aws ec2 create-nat-gateway --subnet-id "$PUB_SUB_A" --allocation-id "$EIP_ALLOC_ID" \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=Production-NAT-GW}]' \
--profile "$PROFILE" --query "NatGateway.NatGatewayId" --output text)
echo "Waiting for NAT Gateway ($NAT_GW_ID) to become available..."
aws ec2 wait nat-gateway-available --nat-gateway-ids "$NAT_GW_ID" --profile "$PROFILE"
# 5. Public Route Table
PUB_RTB_ID=$(aws ec2 create-route-table --vpc-id "$VPC_ID" --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Public-Route-Table}]' \
--profile "$PROFILE" --query "RouteTable.RouteTableId" --output text)
aws ec2 create-route --route-table-id "$PUB_RTB_ID" --destination-cidr-block "0.0.0.0/0" --gateway-id "$IGW_ID" --profile "$PROFILE"
aws ec2 associate-route-table --route-table-id "$PUB_RTB_ID" --subnet-id "$PUB_SUB_A" --profile "$PROFILE"
aws ec2 associate-route-table --route-table-id "$PUB_RTB_ID" --subnet-id "$PUB_SUB_B" --profile "$PROFILE"
# 6. Private Route Table
PRIV_RTB_ID=$(aws ec2 create-route-table --vpc-id "$VPC_ID" --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Private-Route-Table}]' \
--profile "$PROFILE" --query "RouteTable.RouteTableId" --output text)
aws ec2 create-route --route-table-id "$PRIV_RTB_ID" --destination-cidr-block "0.0.0.0/0" --nat-gateway-id "$NAT_GW_ID" --profile "$PROFILE"
aws ec2 associate-route-table --route-table-id "$PRIV_RTB_ID" --subnet-id "$PRIV_SUB_A" --profile "$PROFILE"
aws ec2 associate-route-table --route-table-id "$PRIV_RTB_ID" --subnet-id "$PRIV_SUB_B" --profile "$PROFILE"
echo "=== Base VPC Setup Complete! ==="
echo "VPC ID: $VPC_ID"
echo "Public Route Table: $PUB_RTB_ID"
echo "Private Route Table: $PRIV_RTB_ID"
EOF
chmod +x setup-base-vpc.sh
./setup-base-vpc.sh
Phase 1: Zero-Cost Private S3 Routing with VPC Gateway Endpoints
The Architecture: NAT Gateway Cost Trap vs. VPC Gateway Endpoints
When an EC2 instance in a private subnet communicates with Amazon S3 (e.g. pulling container images, downloading machine learning datasets, writing database backups), traffic by default routes through your Managed NAT Gateway:
+---------------------------------------------------------------------------------------+
| The NAT Gateway Data Transfer Problem |
+---------------------------------------------------------------------------------------+
1. DEFAULT ROUTING (Expensive):
[ Private EC2 Instance ] ====> [ NAT Gateway ($0.045/hr + $0.045/GB) ] ====> [ Amazon S3 ]
* A 10 TB dataset transfer incurs $450.00 in NAT Gateway data processing fees!
2. VPC GATEWAY ENDPOINT ROUTING (Zero Cost & Ultra-Fast):
[ Private EC2 Instance ] ====> [ S3 VPC Gateway Endpoint ] ============> [ Amazon S3 ]
* Routes directly over AWS internal fiber backbone.
* Cost: 100% FREE ($0.00 / hour + $0.00 / GB transferred).
Gateway Endpoints vs. Interface Endpoints (PrivateLink):
AWS provides two distinct mechanisms for connecting VPCs to AWS services privately:
| Endpoint Type | Supported Services | How It Works | Hourly & Data Cost |
|---|---|---|---|
| Gateway Endpoints | Amazon S3 & DynamoDB only | AWS injects a Prefix List Route (pl-xxxx) directly into your Route Table. | 100% Free ($0.00) |
| Interface Endpoints (PrivateLink) | 100+ AWS Services (SQS, SNS, Secrets Manager, ECR, etc.) | Deploys an Elastic Network Interface (ENI) with a private IP inside your subnet. | Hourly fee ( |
Step 1: Query the S3 Service Name in Your Region
Letβs begin by acting as our administrator persona (cloud-dev-admin) to query the available S3 endpoint service name:
aws ec2 describe-vpc-endpoint-services \
--service-names "com.amazonaws.ap-southeast-1.s3" \
--profile cloud-dev-admin \
--query "ServiceDetails[0].[ServiceName, ServiceType[0].ServiceType]" \
--output table
Expected Output:
--------------------------------------------------
| DescribeVpcEndpointServices |
+--------------------------------+---------------+
| com.amazonaws.ap-southeast-1.s3| Gateway |
+--------------------------------+---------------+
Step 2: Create the S3 Gateway Endpoint
Retrieve your VPC ID and Private Route Table ID from Part 5, then provision the endpoint:
# 1. Retrieve IDs
VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=Production-VPC" --query "Vpcs[0].VpcId" --output text --profile cloud-dev-admin)
PRIV_RTB_ID=$(aws ec2 describe-route-tables --filters "Name=tag:Name,Values=Private-Route-Table" --query "RouteTables[0].RouteTableId" --output text --profile cloud-dev-admin)
# 2. Create the S3 Gateway Endpoint
S3_VPCE_ID=$(aws ec2 create-vpc-endpoint \
--vpc-id "$VPC_ID" \
--service-name "com.amazonaws.ap-southeast-1.s3" \
--route-table-ids "$PRIV_RTB_ID" \
--tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=Production-S3-Gateway-Endpoint}]' \
--profile cloud-dev-admin \
--query "VpcEndpoint.VpcEndpointId" \
--output text)
π How to Validate S3 Gateway Routing:
Inspect your Private Route Table. You will see that AWS automatically injected a Prefix List route (pl-xxxx) pointing directly to your VPC Endpoint:
aws ec2 describe-route-tables \
--route-table-ids "$PRIV_RTB_ID" \
--query "RouteTables[0].Routes[*].[DestinationPrefixListId, GatewayId, State]" \
--output table \
--profile cloud-dev-admin
Expected Output:
--------------------------------------------------------------
| DescribeRouteTables |
+----------------------+-----------------------+-------------+
| pl-6fa54006 | vpce-0123456789abcdef| active |
+----------------------+-----------------------+-------------+
[!TIP] What this means: Any traffic destined for Amazon S3 automatically matches
pl-6fa54006and bypasses the NAT Gateway completely, saving 100% on data transfer fees!
Phase 2: Network Traffic Auditing with VPC Flow Logs
The Architecture: Observability & Security Compliance
VPC Flow Logs is an agentless, software-defined traffic capture system built into the VPC virtualization layer. It captures metadata on all IP traffic flowing to and from network interfaces in your VPC without consuming instance CPU or memory.
+-------------------------------------------------------------------------------+
| VPC Flow Logs Architecture |
+-------------------------------------------------------------------------------+
| |
| [ Network Interfaces (ENIs) ] |
| * EC2 Instances, NAT Gateways, Load Balancers |
| | |
| v (Captures 14 standard L3/L4 packet metadata fields) |
| [ VPC Flow Logs Engine ] |
| | |
| +---> [ Amazon CloudWatch Logs ] (Real-time alerting & alarms) |
| | |
| +---> [ Amazon S3 Bucket ] (Long-term compliance & Athena SQL) |
| |
+-------------------------------------------------------------------------------+
Anatomy of a Flow Log Record:
Every recorded packet generates a formatted record with 14 standardized fields:
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
2 123456789012 eni-01234567 10.0.1.50 142.250.190.46 49152 443 6 12 1840 1620000000 1620000060 ACCEPT OK
2 123456789012 eni-01234567 203.0.113.15 10.0.1.50 54210 22 6 1 40 1620000000 1620000060 REJECT OK
protocol: 6: TCP traffic (1 = ICMP, 17 = UDP).action: ACCEPT: Traffic was permitted by Security Groups and Network ACLs.action: REJECT: Traffic was blocked by a firewall (invaluable for detecting unauthorized port scans or brute-force SSH attempts).
Step 1: Create a CloudWatch Log Group
aws logs create-log-group \
--log-group-name "/aws/vpc/production-flow-logs" \
--profile cloud-dev-admin
Step 2: Create the IAM Role for Flow Logs Publishing
VPC Flow Logs requires an IAM role to deliver log events into CloudWatch.
Create the trust policy document:
cat <<'EOF' > flow-logs-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowVPCFlowLogsService",
"Effect": "Allow",
"Principal": {
"Service": "vpc-flow-logs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
Create the IAM Role:
FLOW_ROLE_ARN=$(aws iam create-role \
--role-name "VPCFlowLogsDeliveryRole" \
--assume-role-policy-document file://flow-logs-trust-policy.json \
--description "Role used by VPC Flow Logs to publish to CloudWatch" \
--query "Role.Arn" \
--output text \
--profile cloud-dev-admin)
Attach the required CloudWatch Logs publishing permissions:
cat <<'EOF' > flow-logs-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
}
]
}
EOF
aws iam put-role-policy \
--role-name "VPCFlowLogsDeliveryRole" \
--policy-name "VPCFlowLogsDeliveryPolicy" \
--policy-document file://flow-logs-policy.json \
--profile cloud-dev-admin
# Clean up local policy files
rm -f flow-logs-trust-policy.json flow-logs-policy.json
Step 3: Enable Flow Logs on the VPC
FLOW_LOG_ID=$(aws ec2 create-flow-logs \
--resource-type VPC \
--resource-ids "$VPC_ID" \
--traffic-type ALL \
--log-destination-type cloud-watch-logs \
--log-group-name "/aws/vpc/production-flow-logs" \
--deliver-logs-permission-arn "$FLOW_ROLE_ARN" \
--tag-specifications 'ResourceType=vpc-flow-log,Tags=[{Key=Name,Value=Production-VPC-Flow-Logs}]' \
--profile cloud-dev-admin \
--query "FlowLogIds[0]" \
--output text)
π How to Validate Flow Logs:
Verify that the Flow Log is in the ACTIVE state:
aws ec2 describe-flow-logs \
--flow-log-ids "$FLOW_LOG_ID" \
--query "FlowLogs[*].[FlowLogId, ResourceId, TrafficType, FlowLogStatus, LogDestinationType]" \
--output table \
--profile cloud-dev-admin
Expected Output:
-------------------------------------------------------------------------------------
| DescribeFlowLogs |
+---------------------+-----------------------+-------+---------+-------------------+
| fl-0123456789abc | vpc-0123456789abcdef | ALL | ACTIVE | cloud-watch-logs |
+---------------------+-----------------------+-------+---------+-------------------+
Phase 3: Standard Subnet Discovery Tags for Kubernetes & Load Balancers
The Architecture: Automated Subnet Discovery
When organizations deploy containerized applications on Amazon EKS (Elastic Kubernetes Service) or use the AWS Load Balancer Controller, the controller automatically scans your VPC to determine where to provision load balancers.
It relies on standardized subnet tags:
+-------------------------------------------------------------------------------+
| Kubernetes Subnet Discovery Tags |
+-------------------------------------------------------------------------------+
| |
| [ Public Subnets ] ---> Tag: `kubernetes.io/role/elb = 1` |
| (Tells controller: Place Internet-facing ALBs here) |
| |
| [ Private Subnets ] ---> Tag: `kubernetes.io/role/internal-elb = 1` |
| (Tells controller: Place internal microservice NLBs)|
| |
+-------------------------------------------------------------------------------+
Adding these tags during network provisioning ensures your VPC is instantly compatible with modern cloud-native architectures.
Step 1: Retrieve Subnet IDs
PUB_SUBS=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID" "Name=tag:Tier,Values=Public" --query "Subnets[*].SubnetId" --output text --profile cloud-dev-admin)
PRIV_SUBS=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID" "Name=tag:Tier,Values=Private" --query "Subnets[*].SubnetId" --output text --profile cloud-dev-admin)
Step 2: Apply Discovery Tags
# 1. Tag Public Subnets for Internet-Facing Load Balancers
aws ec2 create-tags \
--resources $PUB_SUBS \
--tags "Key=kubernetes.io/role/elb,Value=1" \
--profile cloud-dev-admin
# 2. Tag Private Subnets for Internal Microservice Load Balancers
aws ec2 create-tags \
--resources $PRIV_SUBS \
--tags "Key=kubernetes.io/role/internal-elb,Value=1" \
--profile cloud-dev-admin
π How to Validate Subnet Discovery Tags:
Query the subnets to confirm the tags were applied:
aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=$VPC_ID" \
--query "Subnets[*].[Tags[?Key=='Name'].Value | [0], SubnetId, Tags[?starts_with(Key, 'kubernetes.io')].Key | [0]]" \
--output table \
--profile cloud-dev-admin
Expected Output:
--------------------------------------------------------------------------------
| DescribeSubnets |
+-------------------+-----------------------+----------------------------------+
| Public-Subnet-A | subnet-011111111111 | kubernetes.io/role/elb |
| Public-Subnet-B | subnet-022222222222 | kubernetes.io/role/elb |
| Private-Subnet-A | subnet-033333333333 | kubernetes.io/role/internal-elb |
| Private-Subnet-B | subnet-044444444444 | kubernetes.io/role/internal-elb |
+-------------------+-----------------------+----------------------------------+
Phase 4: Mathematical Network Dry-Run with VPC Reachability Analyzer
The Architecture: Formal Automated Reasoning
How do you verify that your private subnets can reach the Internet through the NAT Gateway without spending money to boot up virtual machines?
The AWS VPC Reachability Analyzer uses Automated Reasoning (Formal Mathematical Logic) to analyze your network configuration (Route Tables, Gateways, Security Groups, NACLs) and prove whether a packet path exists.
+-------------------------------------------------------------------------------+
| Reachability Analyzer Hop-by-Hop Trace |
+-------------------------------------------------------------------------------+
| |
| [ Source: Private Subnet A ] |
| | |
| v (Hop 1: Evaluates Private Route Table -> Matches 0.0.0.0/0) |
| [ Private Route Table ] |
| | |
| v (Hop 2: Forwards packet to Target NAT Gateway) |
| [ NAT Gateway (Public Subnet A) ] |
| | |
| v (Hop 3: Evaluates Public Route Table -> Matches 0.0.0.0/0) |
| [ Public Route Table ] |
| | |
| v (Hop 4: Forwards to Internet Gateway) |
| [ Internet Gateway (IGW) ] |
| | |
| v |
| [ RESULT: Reachable = TRUE (Zero Real Packets Sent!) ] |
| |
+-------------------------------------------------------------------------------+
Step 1: Create a Network Insights Path
# 1. Retrieve Subnet A and IGW ID
PRIV_SUB_A=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID" "Name=tag:Name,Values=Private-Subnet-A" --query "Subnets[0].SubnetId" --output text --profile cloud-dev-admin)
IGW_ID=$(aws ec2 describe-internet-gateways --filters "Name=attachment.vpc-id,Values=$VPC_ID" --query "InternetGateways[0].InternetGatewayId" --output text --profile cloud-dev-admin)
# 2. Create the Reachability Path
PATH_ID=$(aws ec2 create-network-insights-path \
--source "$PRIV_SUB_A" \
--destination "$IGW_ID" \
--protocol TCP \
--tag-specifications 'ResourceType=network-insights-path,Tags=[{Key=Name,Value=PrivateSubnetToInternetPath}]' \
--profile cloud-dev-admin \
--query "NetworkInsightsPath.NetworkInsightsPathId" \
--output text)
Step 2: Start the Reachability Analysis
ANALYSIS_ID=$(aws ec2 start-network-insights-analysis \
--network-insights-path-id "$PATH_ID" \
--tag-specifications 'ResourceType=network-insights-analysis,Tags=[{Key=Name,Value=OutboundRoutingAnalysis}]' \
--profile cloud-dev-admin \
--query "NetworkInsightsAnalysis.NetworkInsightsAnalysisId" \
--output text)
Step 3: Inspect the Analysis Results
Wait 10β15 seconds for the formal mathematical verification engine to compute the path:
aws ec2 wait network-insights-analysis-succeeded \
--network-insights-analysis-ids "$ANALYSIS_ID" \
--profile cloud-dev-admin
aws ec2 get-network-insights-analysis \
--network-insights-analysis-id "$ANALYSIS_ID" \
--query "NetworkInsightsAnalysis.[Status, NetworkPathFound]" \
--output table \
--profile cloud-dev-admin
Simulator Output:
-------------------------
|GetNetworkInsightsAnalysis|
+------------+----------+
| succeeded | True |
+------------+----------+
NetworkPathFound: True! AWS mathematically proved that your Private Route Table, NAT Gateway, Public Route Table, and Internet Gateway form a valid, unblocked outbound route!
Phase 5: Enterprise Multi-VPC Architecture Framework
In large multi-account organizations, you will manage dozens or hundreds of VPCs. Here is the architectural decision matrix for connecting them:
+-------------------------------------------------------------------------------+
| Multi-VPC Interconnectivity Models |
+-------------------------------------------------------------------------------+
| |
| 1. VPC PEERING (1-to-1 Direct Mesh) |
| [ VPC A ] <=============================================> [ VPC B ] |
| * Best for: Simple 2-VPC connection, lowest latency, no bandwidth limits. |
| * Limitation: Non-transitive (A cannot talk to C through B). |
| |
| 2. AWS TRANSIT GATEWAY (Hub-and-Spoke Enterprise Cloud Router) |
| [ VPC A ] ---\ /--- [ VPC C ] |
| [ VPC B ] -----> [ AWS Transit Gateway (Cloud Router) ] |
| [ On-Prem ] -/ \--- [ VPC D ] |
| * Best for: 10 to 1,000+ VPCs, transitive routing, VPN & Direct Connect. |
| |
| 3. AWS PRIVATELINK (Microservice-Level Exposure) |
| [ Consumer VPC ] ===== ENI (10.0.1.25) =====> [ Producer Microservice ] |
| * Best for: Exposing a single API/database without full network routing. |
| * Prevents overlapping IP conflicts completely! |
| |
+-------------------------------------------------------------------------------+
| Topology | Use Case | Routing Behavior | Overlapping IP Support |
|---|---|---|---|
| VPC Peering | Connecting 2 VPCs directly with lowest possible latency. | Non-transitive 1-to-1 | β No |
| AWS Transit Gateway | Connecting 10+ VPCs and on-premises data centers in a centralized hub. | Transitive Hub-and-Spoke | β No |
| AWS PrivateLink | Exposing a SaaS API or single microservice to other accounts or customers. | Unidirectional TCP stream via ENI | β Yes |
Phase 6: Quick Reference & Teardown
If you are practicing in a personal sandbox environment, you can clean up the advanced components created in this guide:
# 1. Delete Flow Logs
aws ec2 delete-flow-logs --flow-log-ids "$FLOW_LOG_ID" --profile cloud-dev-admin
# 2. Delete CloudWatch Log Group
aws logs delete-log-group --log-group-name "/aws/vpc/production-flow-logs" --profile cloud-dev-admin
# 3. Delete IAM Role
aws iam delete-role-policy --role-name "VPCFlowLogsDeliveryRole" --policy-name "VPCFlowLogsDeliveryPolicy" --profile cloud-dev-admin
aws iam delete-role --role-name "VPCFlowLogsDeliveryRole" --profile cloud-dev-admin
# 4. Delete S3 Gateway Endpoint
aws ec2 delete-vpc-endpoints --vpc-endpoint-ids "$S3_VPCE_ID" --profile cloud-dev-admin
# 5. Delete Network Insights Path
aws ec2 delete-network-insights-path --network-insights-path-id "$PATH_ID" --profile cloud-dev-admin
Quick Reference: Advanced VPC CLI Commands
| Action | CLI Command |
|---|---|
| Create S3 Gateway Endpoint | aws ec2 create-vpc-endpoint --vpc-id <id> --service-name com.amazonaws.<region>.s3 --route-table-ids <rtb> |
| Delete VPC Endpoint | aws ec2 delete-vpc-endpoints --vpc-endpoint-ids <vpce> |
| Create CloudWatch Log Group | aws logs create-log-group --log-group-name <name> |
| Enable VPC Flow Logs | aws ec2 create-flow-logs --resource-type VPC --resource-ids <id> --traffic-type ALL --log-group-name <name> --deliver-logs-permission-arn <arn> |
| Describe Flow Logs | aws ec2 describe-flow-logs --flow-log-ids <id> |
| Create Reachability Path | aws ec2 create-network-insights-path --source <src> --destination <dst> --protocol TCP |
| Start Reachability Analysis | aws ec2 start-network-insights-analysis --network-insights-path-id <id> |
| Get Analysis Results | aws ec2 get-network-insights-analysis --network-insights-analysis-id <id> |
Summary & Whatβs Next
In this sixth installment of AWS with CLI, we elevated our network architecture to enterprise standards:
- We eliminated expensive NAT data transfer fees with a zero-cost S3 Gateway Endpoint.
- We configured VPC Flow Logs streaming to CloudWatch Logs for SOC2/ISO 27001 compliance.
- We applied standard Kubernetes / EKS subnet tags (
kubernetes.io/role/elb). - We mathematically verified our entire routing fabric using the VPC Reachability Analyzer.
- We reviewed the Multi-VPC Interconnectivity Framework (Peering vs. Transit Gateway vs. PrivateLink).
In Part 7, we begin Module 3: Compute Fleets & Security Firewalls, generating ED25519 Key Pairs, configuring stateful Security Groups vs stateless NACLs, delivering IAM instance profiles, and deploying hardened, self-bootstrapping Graviton EC2 instances with IMDSv2!