Scenario Lab · 4 of 10

Overlapping CIDRs? PrivateLink se service share karo

Do VPCs dono 10.0.0.0/16 — peering impossible. Ek service ko bina network jode share karo.

⏱ 2 hours
📶 Intermediate → Advanced
💰 Cost: ~$0.10 (NLB + endpoint)
🧰 Skills: NLB, VPC endpoint service, interface endpoint, acceptance, overlapping CIDRs
0 / 0 checks done
Scenario

Hamari company ne ek doosri company khareed li hai. Dono companies ki VPCs 10.0.0.0/16 hain, isliye overlap ki wajah se peering sambhav nahi hai, aur IP addresses badalne mein mahine lag jaayenge. Lekin khareedi gayi company ke apps ko hamari Inventory service abhi chahiye. Security team ki shart hai: "poora network mat jodo. Sirf ek service aur ek port kholo, aur har naye consumer ko hum khud manually approve karenge."

┌──── consumer-vpc 10.0.0.0/16 ────┐ ┌──── provider-vpc 10.0.0.0/16 ─────────────┐ │ [consumer EC2] │ │ │ │ curl vpce-...amazonaws.com ──► │ [interface │ endpoint service ──► [internal NLB :80] │ │ │ endpoint ENI]══╪══ PrivateLink ═══════► │ │ │ (sirf yeh ENI dikhta hai) │ 10.0.1.x │ ▼ │ └───────────────────────────────────┘ │ [inventory EC2 :80] │ SAME CIDR — no peering, no routes └────────────────────────────────────────────┘
Requirements — solution tabhi complete jab yeh sab sach ho
  1. Do VPCs banani hain, aur dono ka CIDR 10.0.0.0/16 hona chahiye.
  2. Provider VPC mein Inventory service (port 80) ek internal NLB ke peeche chalni chahiye.
  3. NLB ko ek VPC endpoint service banana hai, jisme har naye connection ke liye manual acceptance zaroori ho.
  4. Consumer VPC mein ek interface endpoint banana hai, aur consumer EC2 se service call honi chahiye, bina peering, bina routes aur bina internet ke.
  5. Consumer se provider ke kisi aur IP ya port tak koi access nahi hona chahiye.
Hints (sirf zaroorat ho toh)
  • PrivateLink sirf NLB (ya GWLB) ke saath banta hai. Endpoint service ko consumer ka AZ support karna chahiye, isliye NLB aur consumer subnet, dono ek hi AZ (us-east-1a) mein rakho.
  • Service ke "allowed principals" mein apna account jodna padta hai.
  • Endpoint tab tak pendingAcceptance state mein rahega jab tak provider ki taraf se use accept nahi kiya jaata.
  • Agar NLB bina security group ke banaoge, toh target ke SG mein provider VPC ke CIDR se port 80 allow karna hoga, kyunki traffic NLB ke private IPs se aata hai.
Guided solution dekho (pehle khud try karo!)
1
Do overlapping VPCs + instances

Pehle region, instance type aur account ID set hote hain, folder banta hai aur AMI ID nikaali jaati hai. Phir inventory-userdata.sh banti hai, jo provider server pe port 80 pe ek chhota web server chalati hai. Yeh server inventory ka JSON lautata hai. Consumer server ke liye khaali user-data file banti hai.

mkvpc function har baar ek hi CIDR (10.0.0.0/16) aur ek hi subnet (10.0.1.0/24, us-east-1a) ke saath VPC banata hai, taaki overlap jaan-boojh ke paida ho. Saath mein woh internet gateway, route table, khaali SG aur instance bhi banata hai. Function do baar chalta hai: provider aur consumer ke liye.

Aakhir mein provider SG pe port 80 sirf provider VPC ke CIDR se khola jaata hai, kyunki NLB ka traffic isi range ke IPs se aayega. Phir dono instances ke chalu hone ka intezaar kiya jaata hai.

export AWS_DEFAULT_REGION=us-east-1 TYPE=t3.micro
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
mkdir -p ~/deepdive/scn4 && cd ~/deepdive/scn4
AMI_ID=$(aws ssm get-parameter --name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 --query Parameter.Value --output text)
cat > inventory-userdata.sh <<'EOF'
#!/bin/bash
mkdir -p /opt/www && echo '{"service":"inventory","items":{"keyboard":42,"mouse":17}}' > /opt/www/index.html
cat > /etc/systemd/system/inv.service <<'UNIT'
[Unit]
Description=inventory
[Service]
ExecStart=/usr/bin/python3 -m http.server 80 --directory /opt/www
Restart=always
[Install]
WantedBy=multi-user.target
UNIT
systemctl daemon-reload && systemctl enable --now inv
EOF
echo '#!/bin/bash' > empty.sh

mkvpc() {   # name userdata  (dono 10.0.0.0/16, subnet 10.0.1.0/24 in us-east-1a)
  local VPC SUB IGW RT SG IID
  VPC=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=$1-vpc},{Key=Project,Value=deepdive-scn4}]" --query Vpc.VpcId --output text)
  aws ec2 modify-vpc-attribute --vpc-id $VPC --enable-dns-hostnames
  SUB=$(aws ec2 create-subnet --vpc-id $VPC --cidr-block 10.0.1.0/24 --availability-zone us-east-1a --query Subnet.SubnetId --output text)
  aws ec2 modify-subnet-attribute --subnet-id $SUB --map-public-ip-on-launch
  IGW=$(aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text)
  aws ec2 attach-internet-gateway --internet-gateway-id $IGW --vpc-id $VPC
  RT=$(aws ec2 create-route-table --vpc-id $VPC --query RouteTable.RouteTableId --output text)
  aws ec2 create-route --route-table-id $RT --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW >/dev/null
  aws ec2 associate-route-table --route-table-id $RT --subnet-id $SUB >/dev/null
  SG=$(aws ec2 create-security-group --group-name $1-sg --description "$1" --vpc-id $VPC --query GroupId --output text)
  IID=$(aws ec2 run-instances --image-id $AMI_ID --instance-type $TYPE --subnet-id $SUB --security-group-ids $SG \
    --iam-instance-profile Name=deepdive-ec2-role --user-data file://$2 \
    --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=$1-host},{Key=Project,Value=deepdive-scn4}]" \
    --query 'Instances[0].InstanceId' --output text)
  eval "${1}_VPC=$VPC ${1}_SUB=$SUB ${1}_SG=$SG ${1}_IID=$IID"
  echo "$1: vpc=$VPC subnet=$SUB instance=$IID"
}
mkvpc provider inventory-userdata.sh
mkvpc consumer empty.sh
# provider target: port 80 sirf apni VPC CIDR se (NLB ke private IPs)
aws ec2 authorize-security-group-ingress --group-id $provider_SG --protocol tcp --port 80 --cidr 10.0.0.0/16 >/dev/null
aws ec2 wait instance-running --instance-ids $provider_IID $consumer_IID
2
Internal NLB (provider)

Yeh block provider VPC mein ek internal Network Load Balancer banata hai, yaani aisa NLB jo internet se nahi dikhta. Phir ek TCP target group banta hai jisme provider instance register kiya jaata hai, aur port 80 ka listener banta hai jo traffic ko target group pe bhejta hai. NLB ke available hone ka intezaar karke aakhir mein target ki health dikhayi jaati hai. Pehle yeh initial ho sakti hai, aur kuch der baad healthy ho jaani chahiye.

NLB_ARN=$(aws elbv2 create-load-balancer --name inventory-nlb --type network --scheme internal \
  --subnets $provider_SUB --query 'LoadBalancers[0].LoadBalancerArn' --output text)
TG_ARN=$(aws elbv2 create-target-group --name inventory-tg --protocol TCP --port 80 \
  --vpc-id $provider_VPC --target-type instance --query 'TargetGroups[0].TargetGroupArn' --output text)
aws elbv2 register-targets --target-group-arn $TG_ARN --targets Id=$provider_IID
aws elbv2 create-listener --load-balancer-arn $NLB_ARN --protocol TCP --port 80 \
  --default-actions Type=forward,TargetGroupArn=$TG_ARN >/dev/null
aws elbv2 wait load-balancer-available --load-balancer-arns $NLB_ARN
aws elbv2 describe-target-health --target-group-arn $TG_ARN --query 'TargetHealthDescriptions[].TargetHealth.State'
🖱 Console se bhi ho sakta hai
  1. Target Groups → Create — type Instances, protocol TCP, port 80, VPC provider-vpc, target provider instance register karo.
  2. Load Balancers → Create → Network Load Balancer — naam inventory-nlb, scheme Internal, provider-vpc ka subnet chuno, listener TCP:80 → forward to inventory-tg.
3
Endpoint service (acceptance required)

Pehli command NLB ko ek VPC endpoint service mein badalti hai. --acceptance-required ka matlab hai ki har naye consumer ko provider ko khud approve karna padega. Command service ka ID aur naam lautati hai. Doosri command tumhare apne account ko "allowed principals" mein jodti hai, taaki is account ki VPCs is service se endpoint bana sakein.

read SVC_ID SVC_NAME <<< "$(aws ec2 create-vpc-endpoint-service-configuration \
  --network-load-balancer-arns $NLB_ARN --acceptance-required \
  --query 'ServiceConfiguration.[ServiceId,ServiceName]' --output text)"
echo "$SVC_ID  $SVC_NAME"
aws ec2 modify-vpc-endpoint-service-permissions --service-id $SVC_ID \
  --add-allowed-principals arn:aws:iam::$ACCOUNT_ID:root
🖱 Console se bhi ho sakta hai
  1. VPC → Endpoint Services → Create endpoint service — Load balancer type NLB, apna NLB chuno, Require acceptance for endpoint tick karo, Create.
  2. Service kholo → Allow principals tab → Allow principals → apna account ARN daalo.

SVC_NAME (jo com.amazonaws.vpce.us-east-1.vpce-svc-... jaisa dikhta hai) hi woh cheez hai jo tum consumer team ko doge. Unhe IP ranges dene ki zaroorat nahi padti.

4
Consumer: interface endpoint → provider: accept

Pehle consumer VPC mein endpoint ke liye ek SG banta hai, jo port 80 sirf consumer ke servers (consumer-sg) se allow karta hai.

Phir consumer VPC mein service ke naam se ek interface endpoint banaya jaata hai. Uska state is waqt pendingAcceptance hoga, kyunki provider ne abhi approve nahi kiya hai.

Uske baad provider ki taraf se connection accept kiya jaata hai aur endpoint ke available hone tak intezaar kiya jaata hai. Aakhir mein endpoint ka DNS naam nikaala jaata hai; consumer isi naam se service ko call karega.

EP_SG=$(aws ec2 create-security-group --group-name inventory-endpoint-sg --description "endpoint" \
  --vpc-id $consumer_VPC --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id $EP_SG --protocol tcp --port 80 --source-group $consumer_SG >/dev/null

VPCE=$(aws ec2 create-vpc-endpoint --vpc-endpoint-type Interface --vpc-id $consumer_VPC \
  --service-name $SVC_NAME --subnet-ids $consumer_SUB --security-group-ids $EP_SG \
  --query VpcEndpoint.VpcEndpointId --output text)
aws ec2 describe-vpc-endpoints --vpc-endpoint-ids $VPCE --query 'VpcEndpoints[0].State'   # pendingAcceptance

aws ec2 accept-vpc-endpoint-connections --service-id $SVC_ID --vpc-endpoint-ids $VPCE
until [ "$(aws ec2 describe-vpc-endpoints --vpc-endpoint-ids $VPCE --query 'VpcEndpoints[0].State' --output text)" = available ]; do sleep 10; echo -n .; done; echo
EP_DNS=$(aws ec2 describe-vpc-endpoints --vpc-endpoint-ids $VPCE --query 'VpcEndpoints[0].DnsEntries[0].DnsName' --output text)
echo "endpoint DNS: $EP_DNS"
🖱 Console se bhi ho sakta hai
  1. Consumer taraf: VPC → Endpoints → Create endpoint — service category Other endpoint services, service name paste karo ($SVC_NAME), verify, subnet aur SG chuno, Create.
  2. Provider taraf: Endpoint Services → apni service kholo → Endpoint connections tab → pending connection select karo → Accept.

✓ Verification tests

V1
Consumer se service — aur kuch nahi

Session Manager se consumer-host mein jao. Neeche ki commands dikhati hain ki endpoint ka naam consumer VPC ke andar ke ek IP pe resolve hota hai aur us naam se service ka JSON aata hai. Aakhri command consumer ka apna IP dikhati hai, jo bhi 10.0.1.x hai (angle brackets mein $EP_DNS ki value daalo):

sudo dnf install -y bind-utils >/dev/null
dig +short <EP_DNS>                  # 10.0.1.x — consumer VPC ke andar ek ENI ka IP
curl -s http://<EP_DNS>/             # {"service":"inventory",...}
ip -4 addr show | grep inet          # consumer ka apna IP bhi 10.0.1.x — overlap, phir bhi kaam kar raha hai

Ab consumer se provider instance ke private IP (jaise 10.0.1.25) pe curl karke dekho. Woh IP consumer ki apni VPC ka koi address hoga, ya wahan kuch hoga hi nahi, kyunki provider ka network consumer ko dikhta hi nahi. Consumer ko sirf ek ENI aur ek port milta hai.

Acceptance criteria (verify)
  • Endpoint ka DNS naam consumer VPC ke private IP pe resolve hua aur service ka JSON aaya.
  • Consumer se provider ke doosre IPs tak nahi pahuncha ja sakta.
V2
Provider ki nazar se

provider-host pe sudo journalctl -u inv -n 5 chalao. Tum dekhoge ki requests ka source IP NLB ka private IP hai, consumer ka nahi. Phir console mein VPC → Endpoint services mein apni service kholo aur Endpoint connections dekho. Wahan consumer ka endpoint Available state mein dikhega, aur yahin se tum kisi bhi consumer ko Reject karke uska access turant kaat sakte ho.

Acceptance criteria (verify)
  • Provider ke logs mein NLB ka IP dikha, aur endpoint connections ki list mein consumer dikha.
Break & Fix
  1. aws ec2 reject-vpc-endpoint-connections --service-id $SVC_ID --vpc-endpoint-ids $VPCE se endpoint connection ko Reject karo. Ab consumer ka curl fail hoga. Yeh provider ka "kill switch" hai. Dhyan rakho ki reject kiya gaya endpoint dobara accept nahi hota; uske liye naya endpoint banana padta hai.
  2. inventory-endpoint-sg ka rule hata do. Ab consumer ka curl timeout hoga, jabki provider ki taraf sab theek hai. Isse yeh seekh milti hai ki endpoint ke ENI pe bhi SG lagta hai.
Challenge — no steps given

Endpoint ko ek aasaan naam do. Consumer VPC mein partner.internal naam ka private hosted zone banao, aur usme inventory.partner.internal ka CNAME record banao jo endpoint ke DNS naam ki taraf ho. Phir PrivateLink, peering aur Transit Gateway, teeno ka ek-ek use-case likho. AWS khud apni services ke liye yahi pattern use karta hai; Lab 4 ke SSM interface endpoints bhi PrivateLink hi the.

🧹 Cleanup

Yeh commands pehle endpoint delete karti hain aur ek minute rukti hain. Phir endpoint service, NLB aur (30 second baad) target group delete hote hain, aur dono instances terminate kiye jaate hain:

aws ec2 delete-vpc-endpoints --vpc-endpoint-ids $VPCE
sleep 60
aws ec2 delete-vpc-endpoint-service-configurations --service-ids $SVC_ID
aws elbv2 delete-load-balancer --load-balancer-arn $NLB_ARN
sleep 30 && aws elbv2 delete-target-group --target-group-arn $TG_ARN
aws ec2 terminate-instances --instance-ids $provider_IID $consumer_IID >/dev/null

Instances terminate hone ke baad console se provider-vpc aur consumer-vpc delete kar do.