🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
đŸ’ŧ Servicesâ„šī¸ Aboutâœ‰ī¸ ContactView Pricing Plansfrom $10

Cloud Networking: VPC, Transit Gateway, PrivateLink

Cloud ArchitectureCloud Networking⭐ Premium

Advertisement

Cloud Networking: VPC, Transit Gateway, PrivateLink

Difficulty: Senior Level | Companies: AWS, Google, Microsoft, Cloudflare, Akamai

Interview Question

"Design a VPC architecture for a multi-account AWS environment with 50+ VPCs. How do you handle connectivity, security, and DNS resolution?"

â„šī¸Key Concepts

This question tests your understanding of cloud networking, VPC design patterns, and enterprise connectivity.

Complete Networking Architecture

Architecture Overview

ENTERPRISE NETWORK ARCHITECTUREENTERPRISE NETWORK A┌───────────────── OData CenterVPNDirect Connect└───────────────────┌───────────────── T┌───────────────────Transit Gateway(Hub-and-Spoke Topol└───────────────────└───────────────────┌───────────────── V┌──────────┐ ┌─────VPCVPCVPC(Shared)(App)(Data)┌──────┐┌──────┐┌──────┐SubnetSubnetSubnet└──────┘└──────┘└──────┘└──────────┘ └─────└───────────────────┌───────────────── SNACLsSecurity GroupsWAFFirewall└───────────────────

Mathematical Foundation: Network Planning

IP Address Planning:

  • Total VPCs: V = 50
  • Subnets per VPC: S = 10
  • IP addresses per subnet: I = 256 (/24)
  • Total IP addresses needed: T = V × S × I = 1,280,000
  • Available in /16 VPC: 65,536

Network Capacity:

  • Bandwidth per link: B = 10Gbps
  • Number of links: L = 10
  • Total bandwidth: T = B × L = 100Gbps
  • Throughput with redundancy: T = 90Gbps (10% overhead)

Latency Calculations:

  • Intra-AZ latency: L_az = 0.5ms
  • Inter-AZ latency: L_inter = 2ms
  • Inter-region latency: L_region = 50ms
  • On-premises latency: L_prem = 10ms

VPC Design

# Hub VPC for shared services
resource "aws_vpc" "hub" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "hub-vpc"
    Environment = "shared"
  }
}

# Spoke VPC for application
resource "aws_vpc" "app" {
  cidr_block           = "10.1.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "app-vpc"
    Environment = "production"
  }
}

# Subnets in hub VPC
resource "aws_subnet" "hub_public" {
  count             = 3
  vpc_id            = aws_vpc.hub.id
  cidr_block        = cidrsubnet(aws_vpc.hub.cidr_block, 8, count.index)
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "hub-public-${count.index + 1}"
  }
}

resource "aws_subnet" "hub_private" {
  count             = 3
  vpc_id            = aws_vpc.hub.id
  cidr_block        = cidrsubnet(aws_vpc.hub.cidr_block, 8, count.index + 10)
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "hub-private-${count.index + 1}"
  }
}

# Subnets in app VPC
resource "aws_subnet" "app_public" {
  count             = 3
  vpc_id            = aws_vpc.app.id
  cidr_block        = cidrsubnet(aws_vpc.app.cidr_block, 8, count.index)
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "app-public-${count.index + 1}"
  }
}

resource "aws_subnet" "app_private" {
  count             = 3
  vpc_id            = aws_vpc.app.id
  cidr_block        = cidrsubnet(aws_vpc.app.cidr_block, 8, count.index + 10)
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "app-private-${count.index + 1}"
  }
}

Transit Gateway Configuration

# Transit Gateway
resource "aws_ec2_transit_gateway" "main" {
  description = "Main Transit Gateway"

  default_route_table_association = "disable"
  default_route_table_propagation = "disable"

  tags = {
    Name = "main-tgw"
  }
}

# Transit Gateway VPC Attachment for hub
resource "aws_ec2_transit_gateway_vpc_attachment" "hub" {
  transit_gateway_id = aws_ec2_transit_gateway.main.id
  vpc_id            = aws_vpc.hub.id
  subnet_ids        = aws_subnet.hub_private[*].id

  transit_gateway_default_route_table_association = false
  transit_gateway_default_route_table_propagation = false

  tags = {
    Name = "hub-attachment"
  }
}

# Transit Gateway VPC Attachment for app
resource "aws_ec2_transit_gateway_vpc_attachment" "app" {
  transit_gateway_id = aws_ec2_transit_gateway.main.id
  vpc_id            = aws_vpc.app.id
  subnet_ids        = aws_subnet.app_private[*].id

  transit_gateway_default_route_table_association = false
  transit_gateway_default_route_table_propagation = false

  tags = {
    Name = "app-attachment"
  }
}

# Transit Gateway Route Table
resource "aws_ec2_transit_gateway_route_table" "main" {
  transit_gateway_id = aws_ec2_transit_gateway.main.id

  tags = {
    Name = "main-rt"
  }
}

# Route table associations
resource "aws_ec2_transit_gateway_route_table_association" "hub" {
  transit_gateway_attachment_id  = aws_ec2_transit_gateway_vpc_attachment.hub.id
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
}

resource "aws_ec2_transit_gateway_route_table_association" "app" {
  transit_gateway_attachment_id  = aws_ec2_transit_gateway_vpc_attachment.app.id
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
}

# Routes
resource "aws_ec2_transit_gateway_route" "hub_to_app" {
  destination_cidr_block         = aws_vpc.app.cidr_block
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
  transit_gateway_attachment_id  = aws_ec2_transit_gateway_vpc_attachment.app.id
}

resource "aws_ec2_transit_gateway_route" "app_to_hub" {
  destination_cidr_block         = aws_vpc.hub.cidr_block
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id
  transit_gateway_attachment_id  = aws_ec2_transit_gateway_vpc_attachment.hub.id
}

VPC Peering

# VPC peering management
import boto3
from typing import Dict, Any, List
from dataclasses import dataclass

@dataclass
class VPCPeeringRequest:
    request_id: str
    requester_vpc_id: str
    accepter_vpc_id: str
    status: str
    requester_cidr: str
    accepter_cidr: str

class VPCPeeringManager:
    """VPC peering management"""

    def __init__(self):
        self.ec2 = boto3.client('ec2')

    def create_peering(self, requester_vpc_id: str, accepter_vpc_id: str) -> VPCPeeringRequest:
        """Create VPC peering connection"""
        response = self.ec2.create_vpc_peering_connection(
            VpcId=requester_vpc_id,
            PeerVpcId=accepter_vpc_id
        )

        peering = response['VpcPeeringConnection']

        return VPCPeeringRequest(
            request_id=peering['VpcPeeringConnectionId'],
            requester_vpc_id=requester_vpc_id,
            accepter_vpc_id=accepter_vpc_id,
            status=peering['Status']['Code'],
            requester_cidr='',
            accepter_cidr=''
        )

    def accept_peering(self, peering_id: str):
        """Accept VPC peering connection"""
        self.ec2.accept_vpc_peering_connection(
            VpcPeeringConnectionId=peering_id
        )

    def add_routes(self, peering_id: str, requester_cidr: str, accepter_cidr: str):
        """Add routes for peering connection"""
        # Get VPC IDs from peering connection
        response = self.ec2.describe_vpc_peering_connections(
            VpcPeeringConnectionIds=[peering_id]
        )

        peering = response['VpcPeeringConnections'][0]
        requester_vpc_id = peering['RequesterVpcInfo']['VpcId']
        accepter_vpc_id = peering['AccepterVpcInfo']['VpcId']

        # Add route in requester VPC
        self._add_route_to_vpc(requester_vpc_id, accepter_cidr, peering_id)

        # Add route in accepter VPC
        self._add_route_to_vpc(accepter_vpc_id, requester_cidr, peering_id)

    def _add_route_to_vpc(self, vpc_id: str, destination_cidr: str, peering_id: str):
        """Add route to VPC route table"""
        # Get route table for VPC
        route_tables = self.ec2.describe_route_tables(
            Filters=[
                {'Name': 'vpc-id', 'Values': [vpc_id]},
                {'Name': 'association.main', 'Values': ['true']}
            ]
        )

        if route_tables['RouteTables']:
            route_table_id = route_tables['RouteTables'][0]['RouteTableId']
            self.ec2.create_route(
                RouteTableId=route_table_id,
                DestinationCidrBlock=destination_cidr,
                VpcPeeringConnectionId=peering_id
            )

PrivateLink Configuration

# VPC Endpoint Service
import boto3
from typing import Dict, Any, List
from dataclasses import dataclass

@dataclass
class VPCEndpoint:
    endpoint_id: str
    service_name: str
    vpc_id: str
    type: str
    status: str

class PrivateLinkManager:
    """VPC PrivateLink manager"""

    def __init__(self):
        self.ec2 = boto3.client('ec2')
        self.elbv2 = boto3.client('elbv2')

    def create_endpoint_service(self, load_balancer_arn: str) -> str:
        """Create VPC endpoint service"""
        response = self.ec2.create_vpc_endpoint_service_configuration(
            NetworkLoadBalancerArns=[load_balancer_arn],
            AcceptanceRequired=False,
            PayerResponsibility='SERVICE_OWNER'
        )

        return response['ServiceConfiguration']['ServiceId']

    def create_vpc_endpoint(self, vpc_id: str, service_name: str, 
                           subnet_ids: List[str]) -> VPCEndpoint:
        """Create VPC endpoint"""
        response = self.ec2.create_vpc_endpoint(
            VpcId=vpc_id,
            ServiceName=service_name,
            SubnetIds=subnet_ids,
            VpcEndpointType='Interface'
        )

        endpoint = response['VpcEndpoint']

        return VPCEndpoint(
            endpoint_id=endpoint['VpcEndpointId'],
            service_name=service_name,
            vpc_id=vpc_id,
            type='Interface',
            status=endpoint['State']
        )

    def create_gateway_endpoint(self, vpc_id: str, route_table_ids: List[str],
                               service_name: str = 'com.amazonaws.us-east-1.s3') -> VPCEndpoint:
        """Create gateway endpoint"""
        response = self.ec2.create_vpc_endpoint(
            VpcId=vpc_id,
            ServiceName=service_name,
            RouteTableIds=route_table_ids,
            VpcEndpointType='Gateway'
        )

        endpoint = response['VpcEndpoint']

        return VPCEndpoint(
            endpoint_id=endpoint['VpcEndpointId'],
            service_name=service_name,
            vpc_id=vpc_id,
            type='Gateway',
            status=endpoint['State']
        )

    def create_prefix_list_endpoint(self, vpc_id: str, prefix_list_id: str,
                                   subnet_ids: List[str]) -> VPCEndpoint:
        """Create endpoint for prefix list"""
        response = self.ec2.create_vpc_endpoint(
            VpcId=vpc_id,
            PrefixListId=prefix_list_id,
            SubnetIds=subnet_ids,
            VpcEndpointType='GatewayLoadBalancer'
        )

        endpoint = response['VpcEndpoint']

        return VPCEndpoint(
            endpoint_id=endpoint['VpcEndpointId'],
            service_name=f"prefix-list:{prefix_list_id}",
            vpc_id=vpc_id,
            type='GatewayLoadBalancer',
            status=endpoint['State']
        )

DNS Resolution

# Route53 private hosted zones
import boto3
from typing import Dict, Any, List
from dataclasses import dataclass

@dataclass
class PrivateHostedZone:
    zone_id: str
    domain_name: str
    vpc_id: str
    comment: str

class DNSManager:
    """DNS management for VPC"""

    def __init__(self):
        self.route53 = boto3.client('route53')

    def create_private_hosted_zone(self, domain_name: str, vpc_id: str) -> PrivateHostedZone:
        """Create private hosted zone"""
        response = self.route53.create_hosted_zone(
            Name=domain_name,
            CallerReference=str(hash(domain_name)),
            HostedZoneConfig={
                'Comment': f'Private zone for {domain_name}',
                'PrivateZone': True
            },
            VPC={
                'VPCRegion': 'us-east-1',
                'VPCId': vpc_id
            }
        )

        zone = response['HostedZone']

        return PrivateHostedZone(
            zone_id=zone['Id'].split('/')[-1],
            domain_name=domain_name,
            vpc_id=vpc_id,
            comment=f'Private zone for {domain_name}'
        )

    def create_record(self, zone_id: str, record_name: str, record_type: str,
                     record_values: List[str], ttl: int = 300):
        """Create DNS record"""
        self.route53.change_resource_record_sets(
            HostedZoneId=zone_id,
            ChangeBatch={
                'Changes': [
                    {
                        'Action': 'UPSERT',
                        'ResourceRecordSet': {
                            'Name': record_name,
                            'Type': record_type,
                            'TTL': ttl,
                            'ResourceRecords': [
                                {'Value': value} for value in record_values
                            ]
                        }
                    }
                ]
            }
        )

    def associate_vpc_with_zone(self, zone_id: str, vpc_id: str, vpc_region: str = 'us-east-1'):
        """Associate VPC with private hosted zone"""
        self.route53.associate_vpc_with_hosted_zone(
            HostedZoneId=zone_id,
            VPC={
                'VPCRegion': vpc_region,
                'VPCId': vpc_id
            }
        )

    def create_resolver_endpoint(self, vpc_id: str, subnet_ids: List[str],
                                direction: str = 'INBOUND') -> str:
        """Create Route53 Resolver endpoint"""
        route53resolver = boto3.client('route53resolver')

        response = route53resolver.create_resolver_endpoint(
            CreatorRequestId=str(hash(vpc_id)),
            Direction=direction,
            IpAddresses=[
                {
                    'SubnetId': subnet_id
                } for subnet_id in subnet_ids
            ],
            SecurityGroupIds=[self._get_security_group(vpc_id)],
            VpcId=vpc_id
        )

        return response['ResolverEndpoint']['Id']

    def _get_security_group(self, vpc_id: str) -> str:
        """Get security group for resolver endpoint"""
        ec2 = boto3.client('ec2')
        response = ec2.describe_security_groups(
            Filters=[
                {'Name': 'vpc-id', 'Values': [vpc_id]},
                {'Name': 'group-name', 'Values': ['dns-resolver']}
            ]
        )

        if response['SecurityGroups']:
            return response['SecurityGroups'][0]['GroupId']
        return ''

âš ī¸DNS Best Practices

Use private hosted zones for internal DNS resolution. Implement DNS failover for high availability. Use Route53 Resolver for hybrid DNS.

Network Security

# Security group management
import boto3
from typing import Dict, Any, List
from dataclasses import dataclass

@dataclass
class SecurityGroupRule:
    protocol: str
    from_port: int
    to_port: int
    cidr_blocks: List[str]
    description: str

class SecurityGroupManager:
    """Security group management"""

    def __init__(self):
        self.ec2 = boto3.client('ec2')

    def create_security_group(self, vpc_id: str, group_name: str, 
                             description: str, ingress_rules: List[SecurityGroupRule],
                             egress_rules: List[SecurityGroupRule] = None) -> str:
        """Create security group with rules"""
        # Create security group
        response = self.ec2.create_security_group(
            VpcId=vpc_id,
            GroupName=group_name,
            Description=description
        )

        group_id = response['GroupId']

        # Add ingress rules
        for rule in ingress_rules:
            self.ec2.authorize_security_group_ingress(
                GroupId=group_id,
                IpPermissions=[
                    {
                        'IpProtocol': rule.protocol,
                        'FromPort': rule.from_port,
                        'ToPort': rule.to_port,
                        'IpRanges': [
                            {'CidrIp': cidr, 'Description': rule.description}
                            for cidr in rule.cidr_blocks
                        ]
                    }
                ]
            )

        # Add egress rules
        if egress_rules:
            for rule in egress_rules:
                self.ec2.authorize_security_group_egress(
                    GroupId=group_id,
                    IpPermissions=[
                        {
                            'IpProtocol': rule.protocol,
                            'FromPort': rule.from_port,
                            'ToPort': rule.to_port,
                            'IpRanges': [
                                {'CidrIp': cidr, 'Description': rule.description}
                                for cidr in rule.cidr_blocks
                            ]
                        }
                    ]
                )

        return group_id

    def create_nacl(self, vpc_id: str, nacl_name: str, 
                   ingress_rules: List[Dict], egress_rules: List[Dict]) -> str:
        """Create network ACL"""
        # Create NACL
        response = self.ec2.create_network_acl(
            VpcId=vpc_id,
            TagSpecifications=[
                {
                    'ResourceType': 'network-acl',
                    'Tags': [{'Key': 'Name', 'Value': nacl_name}]
                }
            ]
        )

        nacl_id = response['NetworkAcl']['NetworkAclId']

        # Add ingress rules
        for i, rule in enumerate(ingress_rules):
            self.ec2.create_network_acl_entry(
                NetworkAclId=nacl_id,
                RuleNumber=rule.get('rule_number', (i + 1) * 100),
                Protocol=rule.get('protocol', '-1'),
                RuleAction=rule.get('action', 'allow'),
                Egress=False,
                CidrBlock=rule.get('cidr', '0.0.0.0/0'),
                PortRange={
                    'From': rule.get('from_port', 0),
                    'To': rule.get('to_port', 65535)
                }
            )

        # Add egress rules
        for i, rule in enumerate(egress_rules):
            self.ec2.create_network_acl_entry(
                NetworkAclId=nacl_id,
                RuleNumber=rule.get('rule_number', (i + 1) * 100),
                Protocol=rule.get('protocol', '-1'),
                RuleAction=rule.get('action', 'allow'),
                Egress=True,
                CidrBlock=rule.get('cidr', '0.0.0.0/0'),
                PortRange={
                    'From': rule.get('from_port', 0),
                    'To': rule.get('to_port', 65535)
                }
            )

        return nacl_id

✅Networking Benefits

A well-designed network architecture provides security, scalability, and performance. Use Transit Gateway for hub-and-spoke topology and PrivateLink for service access.

Summary

ComponentPurposeConfiguration
VPCNetwork isolationCIDR, subnets
Transit GatewayHub connectivityRoute tables, attachments
VPC PeeringDirect connectivityCross-region, cross-account
PrivateLinkService accessEndpoint services, interfaces
Route53DNS resolutionPrivate hosted zones
🔒

Premium Content

Cloud Networking: VPC, Transit Gateway, PrivateLink

You've previewed the first section. Unlock this full lesson and 900+ advanced tutorials with a Premium plan.

đŸŽ¯End-to-end Projects
đŸ’ŧInterview Prep
📜Certificates
🤝Community Access

Already a member? Log in

Advertisement