23_2 ‐ OCI Hub‐and‐Spoke: Public Hub VCN Private Spoke VCN (with DRG, NGW, SGW, Bastion) - SanjeevOCI/Study GitHub Wiki

OCI Hub & Spoke (DRG): Public Hub + Private Spoke

Goal

Centralize internet egress & admin in the Hub VCN, keep Spoke VCN private (no direct internet), while enabling:

  • Object Storage / OSMS privately (Service Gateway)
  • OS updates / public repos via Hub NAT Gateway
  • Admin via Bastion in Hub

Quick Architecture

                  +--------------------+
                  |   On-Prem / VPN    |
                  | (Optional Future)  |
                  +---------+----------+
                            |
                            v
                     +-------------+
                     |    DRG      |
                     | (Transit)   |
                     +------+------+  
                            |
+---------------------------+---------------------------+
|                                                       |   
v                                                       v    

+-------------------+ +-------------------+
| HUB VCN | | SPOKE VCN |
| 10.0.0.0/16 | | 10.1.0.0/16 |
| | | |
| +-------------+ | | +-------------+ |
| | Hub-Public |<-------- Admin (SSH/RDP) ---------| | Spoke-Priv | |
| | 10.0.1.0/24 | | | | 10.1.1.0/24 | |
| | Bastion | | | | VM (no PIP) | |
| +-------------+ | | +-------------+ |
| | | |
| +-------------+ | | |
| | Hub-Priv | | | |
| | 10.0.2.0/24 | | | |
| | NAT GW ---> IGW -----------------+ | |
| +-------------+ \ | |
| \ \ | |
| +-------------+ \ \ | |
| | SGW-HUB(opt)|----X (SGW non-transit) X | |
| +-------------+ +-------------+ |
+-------------------+ | SGW-SPOKE | |
| (ObjStor) | |
+-------------+ |
Tenancy
└─ Compartments
├─ Network-Hub
│ └─ VCN HUB 10.0.0.0/16
│ ├─ Subnet Hub-Public 10.0.1.0/24 [IGW] (Bastion, optional tools)
│ ├─ Subnet Hub-Private 10.0.2.0/24 [NAT path/NVA optional]
│ ├─ IGW, NAT GW, DRG, (SGW-HUB optional for hub workloads)
└─ App-Spoke
└─ VCN SPOKE 10.1.0.0/16
├─ Subnet Spoke-Private 10.1.1.0/24 (VMs, no public IPs)
├─ SGW-SPOKE (required for private PaaS access)
└─ DRG attachment (to Hub’s DRG)

Key change vs standalone labs:

  • NAT Gateway is in the Hub (not in Spoke).
  • Spoke sends 0.0.0.0/0 to DRG (centralized egress via Hub NAT).
  • Each VCN that needs private PaaS must have its own Service Gateway (SGW is not transitive).

Addressing (example)

  • HUB VCN: 10.0.0.0/16

    • Hub-Public: 10.0.1.0/24
    • Hub-Private: 10.0.2.0/24
  • SPOKE VCN: 10.1.0.0/16

    • Spoke-Private: 10.1.1.0/24

Build Steps (High-Level)

A) Create Hub VCN (Internet-enabled)

  1. VCN (10.0.0.0/16) with subnets:

    • Hub-Public (10.0.1.0/24) for Bastion
    • Hub-Private (10.0.2.0/24) for NAT path / future NVA
  2. Gateways in Hub:

    • IGW (Internet Gateway)
    • NAT Gateway
    • DRG
    • (Optional) SGW-HUB if hub workloads need private PaaS
  3. Route Tables (Hub):

    • Hub-Public RT: 0.0.0.0/0 → IGW
    • Hub-Private RT:
      • 0.0.0.0/0 → NAT GW
      • (optional) all-oci-services-in-oracle-services-network → SGW-HUB

B) Deploy Bastion in Hub

  • Place OCI Bastion in Hub-Public subnet (uses IGW).
  • Use Bastion session to reach Spoke VM (no public IP on Spoke VM).

C) Create Spoke VCN (No Internet)

  1. VCN (10.1.0.0/16) with Spoke-Private (10.1.1.0/24)
  2. SGW-SPOKE (Service Gateway) — required for Object Storage/OSMS
  3. Attach Spoke VCN to Hub’s DRG

D) DRG Transit Configuration

  • Create DRG attachments: Hub VCN & Spoke VCN
  • DRG Route Tables & Distributions (simple, centralized egress):
    • Hub → Spoke: Export default route 0.0.0.0/0 to Spoke
    • Spoke → Hub: Export Spoke CIDR 10.1.0.0/16 to Hub
    • (Optional) Add on-prem later by attaching VPN/FC to the same DRG

E) Spoke Route Table (attach to Spoke-Private)

  • all-oci-services-in-oracle-services-network → SGW-SPOKE (private PaaS)
  • 0.0.0.0/0 → DRG (centralized egress via Hub NAT)

F) Security Lists / NSGs

Spoke (subnet or NSG at VNIC):

  • Egress:
    • all-oci-services-in-oracle-services-network, TCP 443 (SGW)
    • 0.0.0.0/0, TCP 443 (NAT path via DRG → Hub)
  • Ingress:
    • From Hub Bastion/VPN CIDR on admin ports (22/3389 as required)
    • No inbound from internet

Hub (Bastion + NAT path):

  • Bastion subnet: allow inbound from trusted admin IPs (SSH session establishment)
  • If using NVA (optional): allow spoke CIDR → NVA, and NVA → IGW as required

G) Spoke VM

  • Create VM in Spoke-Private, no public IP
  • Connect via Bastion (Hub-Public)

Verification (from Spoke VM via Bastion)

Object Storage / OSMS via SGW (private path):

oci os ns get --region <region>                     
oci os bucket list --compartment-id <compartment_ocid> --region <region>
# Oracle Linux repos via OSMS (private):
sudo dnf check-update    # or: sudo yum check-update

Outbound updates via Hub NAT (public repos):

sudo dnf install -y wget       # or: sudo yum install -y wget

No broad internet (if you limited egress to 443):

curl http://example.com:80     # should fail (NSG egress locked to 443)

Path sanity:

  • Spoke VNIC → Effective Routes show:
    • all-oci-services... → SGW-SPOKE
    • 0.0.0.0/0 → DRG
  • Hub NAT subnet RT → 0.0.0.0/0 → IGW

Why NAT GW (when Hub has IGW)?

  • NAT GW = outbound-only for private workloads; no unsolicited inbound possible.
  • Using IGW for Spoke traffic opens inbound paths unless heavily firewalled (breaks “no-internet Spoke” posture).
  • Best practice:
    • Public subnets → IGW
    • Private subnets → NAT GW

Interview Soundbite

“We centralize egress by moving NAT to the Hub and point the Spoke’s 0.0.0.0/0 to the DRG.
This preserves the Spoke’s no-internet posture while enabling updates, and aligns with OCI’s gateway semantics.”


Common Pitfalls (and Fixes)

  • Trying to use Hub SGW for Spoke: Not supported (SGW is not transitive). Create SGW in each VCN that needs private PaaS.
  • Missing DRG export/import: Spoke won’t see default route. Fix DRG RT + distributions.
  • Asymmetric routing with an NVA: Ensure return routes in Hub point back to DRG for Spoke CIDR and to IGW for internet.
  • Wrong route table attached to Spoke subnet: Double-check association.
  • Security rules too open: Keep Spoke egress TCP/443 only; prefer NSGs for per-VM control.

Interview Nuggets (Prove Hands-On)

  • Gateways are VCN-level (NAT/SGW): create gateway → reference in subnet RT.
  • DRG provides transit + policy (DRG RTs & distributions) across many VCNs and on-prem.
  • SGW is non-transitive: every VCN needs its own SGW.
  • Bastion in Hub Public for admin; Spoke VMs never get public IPs.
  • Effective routes & flow logs: verify NIC routes and use VCN flow logs.
  • Egress least privilege: 443 only; switch to NVA/OCI Network Firewall for FQDN/domain allow-listing.

Quick Checklist

  • Hub: IGW, NAT GW, DRG (+ optional SGW-HUB), Bastion in Hub-Public
  • Spoke: SGW-SPOKE, DRG attachment; no IGW
  • DRG: Export 0.0.0.0/0 (Hub → Spoke), import Spoke CIDR (Spoke → Hub)
  • Routes (Spoke): all-oci-services… → SGW-SPOKE, 0.0.0.0/0 → DRG
  • Routes (Hub): Hub-Public → IGW, Hub-Private → NAT GW (+ returns to Spoke CIDR)
  • Security: Spoke egress TCP/443 to SGW + 0.0.0.0/0; admin from Bastion/VPN only
  • Validate:
    oci os ns get
    curl ifconfig.me
    dnf/yum check-update
⚠️ **GitHub.com Fallback** ⚠️