# Aws Vpc Networking

> 🌐 **Quick Start**: Membangun jaringan yang terisolasi dan aman di AWS dengan VPC untuk aplikasi Anda

## 📋 Table of Contents

* [🎯 VPC Overview](#-vpc-overview)
* [🏗️ VPC Components](#️-vpc-components)
* [🌍 CIDR Planning](#-cidr-planning)
* [🔧 VPC Creation](#-vpc-creation)
* [📡 Subnets](#-subnets)
* [🚪 Internet Gateway](#-internet-gateway)
* [🔀 Route Tables](#-route-tables)
* [🔒 Network ACLs](#-network-acls)
* [🔗 NAT Gateway](#-nat-gateway)
* [🔌 VPC Endpoints](#-vpc-endpoints)
* [🌐 VPC Peering](#-vpc-peering)
* [📊 Best Practices](#-best-practices)

## 🎯 VPC Overview

Virtual Private Cloud (VPC) adalah jaringan virtual yang terisolasi secara logis di AWS. VPC memungkinkan Anda untuk:

* **🏠 Network Isolation**: Membuat jaringan terisolasi dari resources lain
* **🌐 IP Address Management**: Mengatur alamat IP private dan public
* **🔒 Security Control**: Mengimplementasikan security layers
* **🌍 Global Connectivity**: Menghubungkan multiple regions dan on-premise
* **📊 Network Monitoring**: Memantau traffic dan performance

## 🏗️ VPC Components

### Core Components

```
VPC (10.0.0.0/16)
├── Subnets
│   ├── Public Subnets (10.0.1.0/24)
│   └── Private Subnets (10.0.10.0/24)
├── Internet Gateway
├── NAT Gateway
├── Route Tables
│   ├── Public Route Table
│   └── Private Route Table
├── Network ACLs
└── Security Groups
```

### Advanced Components

* **VPC Endpoints**: Private connectivity ke AWS services
* **VPC Peering**: Connect multiple VPCs
* **Transit Gateway**: Hub untuk multiple VPC connections
* **Flow Logs**: Network traffic monitoring
* **DNS Resolution**: Private DNS untuk internal services

## 🌍 CIDR Planning

### Private IP Ranges

```bash
# RFC 1918 Private Address Space
10.0.0.0    - 10.255.255.255   (10.0.0.0/8)
172.16.0.0  - 172.31.255.255   (172.16.0.0/12)
192.168.0.0 - 192.168.255.255 (192.168.0.0/16)
```

### CIDR Block Examples

```bash
# Large deployment (65,536 IPs)
VPC: 10.0.0.0/16

# Medium deployment (4,096 IPs)
VPC: 10.1.0.0/20

# Small deployment (256 IPs)
VPC: 10.2.0.0/24
```

### Subnet Sizing

```bash
# Public subnets (web tier)
10.0.1.0/24  # 254 usable IPs
10.0.2.0/24  # 254 usable IPs

# Private subnets (application tier)
10.0.11.0/24 # 254 usable IPs
10.0.12.0/24 # 254 usable IPs

# Database subnets (data tier)
10.0.21.0/28 # 14 usable IPs
10.0.22.0/28 # 14 usable IPs
```

## 🔧 VPC Creation

### Using AWS Management Console

```bash
1. Navigate to VPC Dashboard
2. Click "Create VPC"
3. Select "VPC and more"
4. Configure:
   - Name tag: my-app-vpc
   - IPv4 CIDR block: 10.0.0.0/16
   - Availability Zones: 2 AZs
   - Number of public subnets: 2
   - Number of private subnets: 2
   - NAT gateways: 1 per AZ
5. Click "Create VPC"
```

### Using AWS CLI

```bash
# Create VPC
aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=my-app-vpc}]'

# Get VPC ID
VPC_ID=$(aws ec2 describe-vpcs \
  --filters "Name=tag:Name,Values=my-app-vpc" \
  --query "Vpcs[0].VpcId" \
  --output text)

echo "Created VPC: $VPC_ID"

# Enable DNS hostnames and resolution
aws ec2 modify-vpc-attribute \
  --vpc-id $VPC_ID \
  --enable-dns-hostnames

aws ec2 modify-vpc-attribute \
  --vpc-id $VPC_ID \
  --enable-dns-support
```

### Using Terraform

```hcl
# main.tf
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name        = var.vpc_name
    Environment = var.environment
  }
}

variable "vpc_cidr" {
  description = "CIDR block for VPC"
  type        = string
  default     = "10.0.0.0/16"
}

variable "vpc_name" {
  description = "Name of the VPC"
  type        = string
  default     = "my-app-vpc"
}

variable "environment" {
  description = "Environment"
  type        = string
  default     = "production"
}

output "vpc_id" {
  description = "The ID of the VPC"
  value       = aws_vpc.main.id
}
```

## 📡 Subnets

### Public Subnets

```bash
# Create public subnet in AZ 1
aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1a}]'

# Create public subnet in AZ 2
aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1b \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1b}]'

# Enable auto-assign public IP
aws ec2 modify-subnet-attribute \
  --subnet-id $PUBLIC_SUBNET_ID \
  --map-public-ip-on-launch
```

### Private Subnets

```bash
# Create private subnet in AZ 1
aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.11.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1a}]'

# Create private subnet in AZ 2
aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.12.0/24 \
  --availability-zone us-east-1b \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1b}]'
```

### Database Subnets

```bash
# Create database subnet group
aws rds create-db-subnet-group \
  --db-subnet-group-name my-db-subnet-group \
  --db-subnet-group-description "Database subnet group" \
  --subnet-ids $PRIVATE_SUBNET_1_ID $PRIVATE_SUBNET_2_ID
```

### Subnet Selection Examples

```hcl
# Terraform subnet selection
resource "aws_subnet" "public" {
  count = 2

  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.${count.index + 1}.0/24"
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true

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

resource "aws_subnet" "private" {
  count = 2

  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index + 11}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "private-subnet-${count.index + 1}"
    Type = "private"
  }
}
```

## 🚪 Internet Gateway

### Create Internet Gateway

```bash
# Create Internet Gateway
aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=my-igw}]'

# Get IGW ID
IGW_ID=$(aws ec2 describe-internet-gateways \
  --filters "Name=tag:Name,Values=my-igw" \
  --query "InternetGateways[0].InternetGatewayId" \
  --output text)

# Attach to VPC
aws ec2 attach-internet-gateway \
  --vpc-id $VPC_ID \
  --internet-gateway-id $IGW_ID

echo "Internet Gateway: $IGW_ID attached to VPC: $VPC_ID"
```

### Route to Internet Gateway

```bash
# Create route table for public subnets
aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]'

# Get route table ID
PUBLIC_RT_ID=$(aws ec2 describe-route-tables \
  --filters "Name=tag:Name,Values=public-rt" \
  --query "RouteTables[0].RouteTableId" \
  --output text)

# Add route to internet gateway
aws ec2 create-route \
  --route-table-id $PUBLIC_RT_ID \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id $IGW_ID

# Associate route table with public subnets
aws ec2 associate-route-table \
  --route-table-id $PUBLIC_RT_ID \
  --subnet-id $PUBLIC_SUBNET_1_ID

aws ec2 associate-route-table \
  --route-table-id $PUBLIC_RT_ID \
  --subnet-id $PUBLIC_SUBNET_2_ID
```

## 🔀 Route Tables

### Public Route Table Configuration

```hcl
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name = "public-route-table"
  }
}

resource "aws_route_table_association" "public" {
  count = length(aws_subnet.public)

  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}
```

### Private Route Table Configuration

```hcl
resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.main.id
  }

  tags = {
    Name = "private-route-table"
  }
}

resource "aws_route_table_association" "private" {
  count = length(aws_subnet.private)

  subnet_id      = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private.id
}
```

## 🔒 Network ACLs

### Default Network ACL

```bash
# View default NACL
aws ec2 describe-network-acls \
  --filters "Name=vpc-id,Values=$VPC_ID" "Name=default,Values=true"

# Default NACL allows all inbound and outbound traffic
```

### Custom Network ACL

```bash
# Create custom NACL
aws ec2 create-network-acl \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=custom-nacl}]'

# Get NACL ID
NACL_ID=$(aws ec2 describe-network-acls \
  --filters "Name=tag:Name,Values=custom-nacl" \
  --query "NetworkAcls[0].NetworkAclId" \
  --output text)

# Inbound rules
aws ec2 create-network-acl-entry \
  --network-acl-id $NACL_ID \
  --rule-number 100 \
  --protocol -1 \
  --rule-action allow \
  --egress false \
  --cidr-block 10.0.0.0/16

# Outbound rules
aws ec2 create-network-acl-entry \
  --network-acl-id $NACL_ID \
  --rule-number 100 \
  --protocol -1 \
  --rule-action allow \
  --egress true \
  --cidr-block 0.0.0.0/0
```

## 🔗 NAT Gateway

### Create NAT Gateway

```bash
# Allocate Elastic IP
aws ec2 allocate-address \
  --domain vpc \
  --tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=nat-eip}]'

# Get Elastic IP ID
EIP_ALLOCATION_ID=$(aws ec2 describe-addresses \
  --filters "Name=tag:Name,Values=nat-eip" \
  --query "Addresses[0].AllocationId" \
  --output text)

# Create NAT Gateway
aws ec2 create-nat-gateway \
  --subnet-id $PUBLIC_SUBNET_1_ID \
  --allocation-id $EIP_ALLOCATION_ID \
  --tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=my-nat-gateway}]'

# Wait for NAT Gateway to be available
aws ec2 wait nat-gateway-available \
  --nat-gateway-ids $(aws ec2 describe-nat-gateways \
    --filters "Name=tag:Name,Values=my-nat-gateway" \
    --query "NatGateways[0].NatGatewayId" \
    --output text)
```

### Terraform NAT Gateway

```hcl
resource "aws_eip" "nat" {
  domain = "vpc"

  tags = {
    Name = "nat-eip"
  }
}

resource "aws_nat_gateway" "main" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public[0].id

  tags = {
    Name = "main-nat-gateway"
  }

  depends_on = [aws_internet_gateway.main]
}
```

## 🔌 VPC Endpoints

### Interface Endpoints

```bash
# Create S3 interface endpoint
aws ec2 create-vpc-endpoint \
  --vpc-id $VPC_ID \
  --service-name com.amazonaws.us-east-1.s3 \
  --vpc-endpoint-type Interface \
  --subnet-ids $PRIVATE_SUBNET_1_ID $PRIVATE_SUBNET_2_ID \
  --security-group-ids $PRIVATE_SG_ID \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=s3-endpoint}]'

# Create DynamoDB interface endpoint
aws ec2 create-vpc-endpoint \
  --vpc-id $VPC_ID \
  --service-name com.amazonaws.us-east-1.dynamodb \
  --vpc-endpoint-type Interface \
  --subnet-ids $PRIVATE_SUBNET_1_ID $PRIVATE_SUBNET_2_ID \
  --security-group-ids $PRIVATE_SG_ID \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=dynamodb-endpoint}]'
```

### Gateway Endpoints

```bash
# Create S3 gateway endpoint
aws ec2 create-vpc-endpoint \
  --vpc-id $VPC_ID \
  --service-name com.amazonaws.us-east-1.s3 \
  --vpc-endpoint-type Gateway \
  --route-table-ids $PRIVATE_RT_ID \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=s3-gateway-endpoint}]'

# Create DynamoDB gateway endpoint
aws ec2 create-vpc-endpoint \
  --vpc-id $VPC_ID \
  --service-name com.amazonaws.us-east-1.dynamodb \
  --vpc-endpoint-type Gateway \
  --route-table-ids $PRIVATE_RT_ID \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=dynamodb-gateway-endpoint}]'
```

## 🌐 VPC Peering

### Create VPC Peering Connection

```bash
# Requester VPC (Current VPC)
aws ec2 create-vpc-peering-connection \
  --vpc-id $VPC_ID \
  --peer-vpc-id $PEER_VPC_ID \
  --peer-region us-west-2 \
  --tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=vpc-peering-connection}]'

# Accepter VPC (Remote VPC)
aws ec2 accept-vpc-peering-connection \
  --vpc-peering-connection-id $PCX_ID

# Add route in requester VPC
aws ec2 create-route \
  --route-table-id $PRIVATE_RT_ID \
  --destination-cidr-block $PEER_VPC_CIDR \
  --vpc-peering-connection-id $PCX_ID

# Add route in accepter VPC
aws ec2 create-route \
  --route-table-id $PEER_PRIVATE_RT_ID \
  --destination-cidr-block $VPC_CIDR \
  --vpc-peering-connection-id $PCX_ID
```

## 📊 Best Practices

### 🔒 Security Best Practices

```hcl
# Use private subnets for databases
resource "aws_subnet" "database" {
  count = 2

  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index + 21}.0/28"  # Smaller subnet size
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "database-subnet-${count.index + 1}"
    Type = "database"
  }
}

# Security group for database
resource "aws_security_group" "database" {
  name_prefix = "database-"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = [aws_security_group.app.id]  # Only from app servers
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
```

### 📈 Performance Best Practices

```hcl
# Use enhanced networking
resource "aws_instance" "app" {
  ami                    = var.ami_id
  instance_type          = "m5.large"  # Enhanced networking enabled

  network_interface {
    network_interface_id = aws_network_interface.app.id
  }
}

# Dedicated tenancy for compliance
resource "aws_vpc" "compliance" {
  cidr_block           = "10.1.0.0/16"
  instance_tenancy     = "dedicated"
  enable_dns_hostnames = true
  enable_dns_support   = true
}
```

### 💰 Cost Optimization

```hcl
# Use NAT instance instead of NAT Gateway for non-production
resource "aws_instance" "nat" {
  count         = var.environment == "production" ? 0 : 1
  ami           = "ami-0c02fb55956c7d316"  # AWS NAT AMI
  instance_type = "t3.nano"

  source_dest_check = false

  tags = {
    Name = "nat-instance"
  }
}

# Use VPC endpoints to reduce data transfer costs
resource "aws_vpc_endpoint" "s3" {
  vpc_id       = aws_vpc.main.id
  service_name = "com.amazonaws.${data.aws_region.current.name}.s3"

  tags = {
    Name = "s3-endpoint"
  }
}
```

### 🔄 Operational Best Practices

```bash
# Enable flow logs for monitoring
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids $VPC_ID \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name vpc-flow-logs

# Create CloudWatch alarms for NAT Gateway data transfer
aws cloudwatch put-metric-alarm \
  --alarm-name "nat-gateway-bytes-out" \
  --alarm-description "NAT Gateway bytes out" \
  --metric-name NatGatewayBytesOutToDestination \
  --namespace AWS/NATGateway \
  --statistic Sum \
  --period 300 \
  --threshold 1000000000 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2
```

## 📚 References

* [VPC Documentation](https://docs.aws.amazon.com/vpc/)
* [VPC User Guide](https://docs.aws.amazon.com/vpc/latest/userguide/)
* [VPC Networking Concepts](https://docs.aws.amazon.com/vpc/latest/userguide/how-it-works.html)
* [VPC Best Practices](https://docs.aws.amazon.com/vpc/latest/userguide/best-practices.html)

***

*🌐 Generated with ❤️ using Catatan Seekor Documentation Framework*
