Scenario Lab · 2 of 10

Do VPCs ki baat-cheet: peering + private DNS

Orders team ki VPC Payments team ki VPC ke internal API ko naam se call kare — internet ke bina.

⏱ 1.5–2 hours
📶 Intermediate
💰 Cost: ~$0.05
🧰 Skills: VPC peering, route tables, cross-VPC SG referencing, Route 53 private zone on 2 VPCs, overlapping CIDR
0 / 0 checks done
Scenario

Company mein do teams ki alag-alag VPCs hain. Payments team (VPC 10.10.0.0/16) port 8080 pe ek internal API chalati hai. Orders team (VPC 10.20.0.0/16) ko har order pe yeh API call karni hai. Yeh call private network se honi chahiye, internet se nahi, aur naam se (payments.corp.internal) honi chahiye, IP se nahi, taaki agar Payments team apna server badle toh Orders team ko apna code na badalna pade. Security ka niyam yeh hai ki Payments API sirf Orders ke servers se aayi requests accept kare, aur kisi se nahi.

PL-065 course se — console preview
Create peering connection form
consoleCreate peering connection form
Create hosted zone form, public vs private
consoleCreate hosted zone form, public vs private

VPC peering aur hosted zone ka console — poore steps 'Guided solution' mein hain.

┌──────── orders-vpc 10.20.0.0/16 ───────┐ ┌─────── payments-vpc 10.10.0.0/16 ───────┐ │ [orders EC2] │ │ [payments EC2 : API :8080] │ │ curl payments.corp.internal:8080 ─────┼── pcx ───┼──► SG: 8080 ← orders-sg (cross-VPC ref) │ │ route 10.10.0.0/16 → pcx │ │ route 10.20.0.0/16 → pcx │ └─────────────────────────────────────────┘ └──────────────────────────────────────────┘ Route 53 private zone "corp.internal" — associated with BOTH VPCs
Requirements — solution tabhi complete jab yeh sab sach ho
  1. Orders EC2 se curl http://payments.corp.internal:8080/pay chalane pe JSON jawab aana chahiye.
  2. Traffic VPC peering ke through private IPs pe jaana chahiye, internet se nahi.
  3. Payments SG ke inbound rule ka source Orders ka security group hona chahiye; koi CIDR ya 0.0.0.0/0 nahi.
  4. Payments instance ka AWS public DNS name (ec2-x-x-x-x...) bhi Orders VPC se private IP pe resolve hona chahiye.
  5. Yeh saabit karna hai ki overlapping CIDR wali VPC ke saath peering sambhav nahi hai.
Hints (sirf zaroorat ho toh)
  • Peering ke baad dono VPCs ki route tables mein doosre VPC ka CIDR pcx-... ki taraf hona chahiye.
  • Jab peering ek hi account aur ek hi region mein ho, toh SG rule doosri VPC ke SG ko source bana sakta hai.
  • Ek private hosted zone ko ek se zyada VPCs se joda ja sakta hai (associate-vpc-with-hosted-zone se).
  • Public DNS name ko private IP pe resolve karwana peering ka ek option hai, jiska naam DNS resolution from peer VPC hai.
Guided solution dekho (pehle khud try karo!)
1
Do VPCs + instances (Payments API user-data ke saath)

Pehle region aur instance type set hote hain, kaam ka folder banta hai aur Amazon Linux ki latest AMI ID nikaali jaati hai.

Phir payments-userdata.sh banti hai. Yeh Payments server pe port 8080 pe ek chhoti Python API chalati hai. Har request pe API JSON mein "APPROVED" lautati hai, aur saath mein caller field mein request bhejne wale ka IP bhi batati hai. Isi field se baad mein saabit hoga ki traffic private raaste se aaya. API ko systemd service banaya gaya hai, taaki woh hamesha chalti rahe. Orders server ko kuch nahi chalana, isliye uske liye ek khaali user-data file banti hai.

Uske baad mkvpc function ek VPC, public subnet, internet gateway, route table, khaali security group aur ek instance banata hai, aur IDs ko payments_VPC, orders_SG jaise variables mein rakh deta hai. Function do baar chalta hai, ek baar Payments ke liye aur ek baar Orders ke liye.

Aakhir mein Payments server ka private IP aur public DNS name nikaal ke print kiya jaata hai.

export AWS_DEFAULT_REGION=us-east-1 TYPE=t3.micro
mkdir -p ~/deepdive/scn2 && cd ~/deepdive/scn2
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 > payments-userdata.sh <<'EOF'
#!/bin/bash
cat > /opt/payments.py <<'PY'
import json, socket
from http.server import BaseHTTPRequestHandler, HTTPServer

class H(BaseHTTPRequestHandler):
    def do_GET(self):
        body = json.dumps({"service": "payments", "status": "APPROVED", "path": self.path,
                           "host": socket.gethostname(), "caller": self.client_address[0]}).encode()
        self.send_response(200); self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(body))); self.end_headers(); self.wfile.write(body)

HTTPServer(("0.0.0.0", 8080), H).serve_forever()
PY
cat > /etc/systemd/system/payments.service <<'UNIT'
[Unit]
Description=payments api
[Service]
ExecStart=/usr/bin/python3 /opt/payments.py
Restart=always
[Install]
WantedBy=multi-user.target
UNIT
systemctl daemon-reload && systemctl enable --now payments
EOF
echo '#!/bin/bash' > empty-userdata.sh

mkvpc() {   # name cidr subnet userdata-file
  local VPC SUB IGW RT SG IID
  VPC=$(aws ec2 create-vpc --cidr-block $2 --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=$1},{Key=Project,Value=deepdive-scn2}]" --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 $3 --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://$4 \
    --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=$1-host},{Key=Project,Value=deepdive-scn2}]" \
    --query 'Instances[0].InstanceId' --output text)
  eval "${1}_VPC=$VPC ${1}_RT=$RT ${1}_SG=$SG ${1}_IID=$IID"
  echo "$1: vpc=$VPC sg=$SG instance=$IID"
}
mkvpc payments 10.10.0.0/16 10.10.1.0/24 payments-userdata.sh
mkvpc orders   10.20.0.0/16 10.20.1.0/24 empty-userdata.sh
aws ec2 wait instance-running --instance-ids $payments_IID $orders_IID
PAY_IP=$(aws ec2 describe-instances --instance-ids $payments_IID --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text)
PAY_DNS=$(aws ec2 describe-instances --instance-ids $payments_IID --query 'Reservations[0].Instances[0].PublicDnsName' --output text)
echo "payments private IP: $PAY_IP   public DNS: $PAY_DNS"
2
Peering + dono taraf routes

Yeh block Orders VPC se Payments VPC tak ek peering connection ki request bhejta hai aur use turant accept kar leta hai; ek hi account hone ki wajah se tum khud accept kar sakte ho. Phir dono route tables mein routes jode jaate hain. Orders ki table mein "10.10.0.0/16 peering se jao" aur Payments ki table mein "10.20.0.0/16 peering se jao" daala jaata hai, taaki request aur reply dono ka raasta ho.

PCX=$(aws ec2 create-vpc-peering-connection --vpc-id $orders_VPC --peer-vpc-id $payments_VPC \
  --tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=orders-to-payments}]' \
  --query VpcPeeringConnection.VpcPeeringConnectionId --output text)
aws ec2 accept-vpc-peering-connection --vpc-peering-connection-id $PCX >/dev/null
aws ec2 create-route --route-table-id $orders_RT   --destination-cidr-block 10.10.0.0/16 --vpc-peering-connection-id $PCX >/dev/null
aws ec2 create-route --route-table-id $payments_RT --destination-cidr-block 10.20.0.0/16 --vpc-peering-connection-id $PCX >/dev/null
🖱 Console se bhi ho sakta hai
  1. Orders VPC se: Peering connections → Create → Local VPC = orders, Other VPC = payments (same account/region) → Create.
  2. Payments taraf se: pending request kholo → Accept.
  3. Dono route tables mein Edit routes se doosre VPC ka CIDR → target peering connection.
PL-065 course se — asli console reference
Create peering connection form
consoleCreate peering connection form
Peering active
consolePeering active
Edit routes add peer CIDR target peering connection
consoleEdit routes add peer CIDR target peering connection

Peering request, accept, aur route table mein peer CIDR add karna.

3
Cross-VPC security group reference

Yeh command Payments SG pe port 8080 ka ek rule jodti hai, jiska source koi IP range nahi balki doosri VPC ka orders-sg hai. Doosri command SG ke rules print karke dikhati hai ki rule sahi se laga.

aws ec2 authorize-security-group-ingress --group-id $payments_SG \
  --ip-permissions "IpProtocol=tcp,FromPort=8080,ToPort=8080,UserIdGroupPairs=[{GroupId=$orders_SG,Description=orders-servers}]"
aws ec2 describe-security-groups --group-ids $payments_SG --query 'SecurityGroups[0].IpPermissions'
🖱 Console se bhi ho sakta hai
  1. payments-sg kholo → Inbound rules → Edit → Add rule: Custom TCP, port 8080, source Custom, dropdown mein search karke orders-sg chuno (doosri VPC ka SG bhi is dropdown mein dikhta hai jab peering active ho).

Ab yeh rule har us instance ko allow karta hai jo orders-sg mein hai. Agar Orders team 10 naye servers lagaye, toh bhi Payments team ko kuch badalna nahi padega.

4
Private hosted zone — dono VPCs mein

Pehli command corp.internal naam ka private hosted zone banati hai, jo shuru mein sirf Payments VPC se juda hota hai, aur uska ID nikaal leti hai. Doosri command isi zone ko Orders VPC se bhi jodti hai, taaki Orders ke servers bhi yeh naam resolve kar sakein. Teesri command zone mein payments.corp.internal naam ka A record banati hai, jo Payments server ke private IP ki taraf hai.

ZONE=$(aws route53 create-hosted-zone --name corp.internal --caller-reference scn2-$(date +%s) \
  --vpc VPCRegion=us-east-1,VPCId=$payments_VPC --hosted-zone-config PrivateZone=true \
  --query HostedZone.Id --output text | cut -d/ -f3)
aws route53 associate-vpc-with-hosted-zone --hosted-zone-id $ZONE --vpc VPCRegion=us-east-1,VPCId=$orders_VPC
aws route53 change-resource-record-sets --hosted-zone-id $ZONE --change-batch "{
  \"Changes\": [{\"Action\": \"UPSERT\", \"ResourceRecordSet\": {
    \"Name\": \"payments.corp.internal\", \"Type\": \"A\", \"TTL\": 60,
    \"ResourceRecords\": [{\"Value\": \"$PAY_IP\"}]}}]}"
🖱 Console se bhi ho sakta hai
  1. Route 53 → Hosted zones → Create hosted zone — domain corp.internal, type Private, VPC payments chuno.
  2. Zone kholo → VPCs tab-jaisa section mein orders VPC bhi add karo (ya "Associate VPC").
  3. Create record — naam payments, type A, value Payments ka private IP, TTL 60.
PL-065 course se — asli console reference
Create hosted zone form, public vs private
consoleCreate hosted zone form, public vs private

Private hosted zone bhi isi 'Create hosted zone' form se banti hai — Type private chunna hoga.

5
DNS resolution over peering (public DNS name → private IP)

Yeh command peering connection ke dono taraf "DNS resolution from peer VPC" option chalu karti hai.

aws ec2 modify-vpc-peering-connection-options --vpc-peering-connection-id $PCX \
  --requester-peering-connection-options AllowDnsResolutionFromRemoteVpc=true \
  --accepter-peering-connection-options AllowDnsResolutionFromRemoteVpc=true
🖱 Console se bhi ho sakta hai
  1. Peering connection kholo → DNS settings tab (ya Actions → Edit DNS settings) → dono taraf "Allow DNS resolution from peer VPC" tick karo.

Is option ke bina Orders VPC mein $PAY_DNS ka jawab public IP hota. Tab traffic internet se jaata, aur Payments SG use rok deta, kyunki woh sirf orders-sg ko allow karta hai. Verification V2 mein tum option ko ek baar band karke pehle aur baad, dono haalat dekhoge.

✓ Verification tests

V1
Naam se, private raaste se

Session Manager se orders-host ke shell mein jao. Neeche ki commands pehle dig install karti hain aur check karti hain ki naam private IP pe resolve hota hai. Phir naam se API call hoti hai, aur tracepath se dekha jaata hai ki raaste mein kitne hops hain (angle brackets mein Payments ka private IP daalo):

sudo dnf install -y bind-utils >/dev/null
dig +short payments.corp.internal                     # 10.10.1.x
curl -s http://payments.corp.internal:8080/pay        # {"service": "payments", "status": "APPROVED", "caller": "10.20.1.x", ...}
tracepath -n <PAY_IP> | tail -2                        # 1 hop — seedha peering, koi internet router nahi

Jawab ke caller field mein Orders server ka private IP hai. Yeh saboot hai ki traffic private raaste se aaya.

Acceptance criteria (verify)
  • Naam private IP pe resolve hua aur API ne APPROVED lautaya.
  • caller field mein Orders ka 10.20.x wala IP hai.
V2
Public DNS name ka private resolution

orders-host pe Payments ka public DNS name resolve karo aur usse API call karo (angle brackets mein $PAY_DNS ki value daalo):

# orders-host pe:
dig +short <PAY_DNS>                  # option ON → 10.10.1.x ; OFF → public IP
curl -m 5 -s http://<PAY_DNS>:8080/   # ON → chalega ; OFF → timeout (internet path, SG block)

Ab laptop se option band karo: aws ec2 modify-vpc-peering-connection-options --vpc-peering-connection-id $PCX --requester-peering-connection-options AllowDnsResolutionFromRemoteVpc=false --accepter-peering-connection-options AllowDnsResolutionFromRemoteVpc=false. Phir orders-host pe wahi test dobara chalao, aur aakhir mein option ko wapas true kar do.

Acceptance criteria (verify)
  • Option ON hone pe public DNS name private IP pe resolve hua aur curl chal gaya; OFF hone pe public IP mila aur curl timeout hua.
V3
Overlapping CIDR — peering fail

Yeh block Payments wale CIDR (10.10.0.0/16) se hi ek nayi VPC payments-clone banata hai aur use Payments VPC se peer karne ki koshish karta hai. 5 second baad peering ka status dikhaya jaata hai, aur phir clone VPC delete kar di jaati hai:

DUP=$(aws ec2 create-vpc --cidr-block 10.10.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=payments-clone}]' --query Vpc.VpcId --output text)
BAD=$(aws ec2 create-vpc-peering-connection --vpc-id $DUP --peer-vpc-id $payments_VPC --query VpcPeeringConnection.VpcPeeringConnectionId --output text)
sleep 5
aws ec2 describe-vpc-peering-connections --vpc-peering-connection-ids $BAD --query 'VpcPeeringConnections[0].Status'
aws ec2 delete-vpc --vpc-id $DUP

AWS ya toh request ke waqt hi error dega, ya connection ka status failed dikhayega (message mein overlapping CIDR likha hoga); dono ka matlab ek hi hai. Isiliye companies pehle din se hi ek company-wide IP address plan (IPAM) banati hain. Agar overlap ho hi chuka ho, toh uska hal PrivateLink hai, jo tum Scenario 4 mein karoge.

Acceptance criteria (verify)
  • Overlapping CIDR wali peering fail hui (error aaya ya status failed dikha).
Break & Fix
  1. Payments route table se 10.20.0.0/16 → pcx wala route hatao. Ab Orders se curl timeout hoga, kyunki request toh pahunch gayi lekin reply ke liye raasta nahi hai (asymmetric routing). Route wapas laga do.
  2. disassociate-vpc-from-hosted-zone se hosted zone aur Orders VPC ka rishta hatao. Ab dig payments.corp.internal khaali jawab (NXDOMAIN) dega, lekin IP se curl phir bhi chalega. Isse samajh aata hai ki DNS aur network do alag layers hain. Zone ko wapas associate kar do.
Challenge — no steps given

Ek teesri VPC analytics (10.30.0.0/16) banao. Ise Payments API chahiye, lekin Orders se iska koi connection nahi hona chahiye. Yeh kaam peering se karo, aur SG aur routes ki madad se saabit karo ki analytics se orders tak raasta band hai. Phir socho ki agar 15 teams ho jaayein toh kya karoge. (Hint: Lab 9 ka Transit Gateway.)

🧹 Cleanup

Yeh commands pehle DNS record delete karti hain, zone se Orders VPC ko alag karti hain aur zone delete karti hain. Phir dono instances terminate hote hain, peering delete hoti hai, aur instances ke poori tarah band hone ka intezaar kiya jaata hai:

aws route53 change-resource-record-sets --hosted-zone-id $ZONE --change-batch "{\"Changes\":[{\"Action\":\"DELETE\",\"ResourceRecordSet\":{\"Name\":\"payments.corp.internal\",\"Type\":\"A\",\"TTL\":60,\"ResourceRecords\":[{\"Value\":\"$PAY_IP\"}]}}]}"
aws route53 disassociate-vpc-from-hosted-zone --hosted-zone-id $ZONE --vpc VPCRegion=us-east-1,VPCId=$orders_VPC
aws route53 delete-hosted-zone --id $ZONE
aws ec2 terminate-instances --instance-ids $payments_IID $orders_IID >/dev/null
aws ec2 delete-vpc-peering-connection --vpc-peering-connection-id $PCX
aws ec2 wait instance-terminated --instance-ids $payments_IID $orders_IID

Uske baad VPC console se payments aur orders VPCs delete kar do.