Skip to content

VPC 実務Tips

実務で役立つVPCの設定方法、ベストプラクティス、トラブルシューティングを解説します。

手順:
1. VPCダッシュボード → 「VPCを作成」
2. リソース: 「VPCなど」を選択
3. 名前タグ: my-production-vpc
4. IPv4 CIDR: 10.0.0.0/16
5. テナンシー: デフォルト
6. AZ数: 2
7. パブリックサブネット数: 2
8. プライベートサブネット数: 2
9. NAT Gateway: AZごとに1つ
10. VPCエンドポイント: S3
11. 「VPCを作成」クリック
自動作成されるリソース:
- VPC
- サブネット (パブリック×2、プライベート×2)
- インターネットゲートウェイ
- NAT Gateway (×2)
- ルートテーブル (パブリック、プライベート)
- S3 Gateway Endpoint
Web層SG:
1. セキュリティグループ → 「セキュリティグループを作成」
2. 名前: web-tier-sg
3. VPC: 作成したVPC選択
4. インバウンドルール:
- HTTP (80): 0.0.0.0/0
- HTTPS (443): 0.0.0.0/0
5. アウトバウンドルール: デフォルト(全て許可)
App層SG:
1. 名前: app-tier-sg
2. インバウンドルール:
- Custom TCP (8080): ソース=web-tier-sg
3. アウトバウンドルール:
- MySQL (3306): 宛先=db-tier-sg
Terminal window
# VPC作成
VPC_ID=$(aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=my-production-vpc}]' \
--query 'Vpc.VpcId' \
--output text)
echo "VPC ID: $VPC_ID"
# DNS解決有効化
aws ec2 modify-vpc-attribute \
--vpc-id $VPC_ID \
--enable-dns-hostnames
# インターネットゲートウェイ作成
IGW_ID=$(aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=my-igw}]' \
--query 'InternetGateway.InternetGatewayId' \
--output text)
# IGWアタッチ
aws ec2 attach-internet-gateway \
--vpc-id $VPC_ID \
--internet-gateway-id $IGW_ID
Terminal window
# パブリックサブネット1 (AZ-1a)
PUBLIC_SUBNET_1=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.1.0/24 \
--availability-zone ap-northeast-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1a}]' \
--query 'Subnet.SubnetId' \
--output text)
# パブリックサブネット2 (AZ-1c)
PUBLIC_SUBNET_2=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.2.0/24 \
--availability-zone ap-northeast-1c \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1c}]' \
--query 'Subnet.SubnetId' \
--output text)
# プライベートサブネット1 (AZ-1a)
PRIVATE_SUBNET_1=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.11.0/24 \
--availability-zone ap-northeast-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1a}]' \
--query 'Subnet.SubnetId' \
--output text)
# プライベートサブネット2 (AZ-1c)
PRIVATE_SUBNET_2=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.12.0/24 \
--availability-zone ap-northeast-1c \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1c}]' \
--query 'Subnet.SubnetId' \
--output text)
# パブリックIPアドレス自動割り当て
aws ec2 modify-subnet-attribute \
--subnet-id $PUBLIC_SUBNET_1 \
--map-public-ip-on-launch
aws ec2 modify-subnet-attribute \
--subnet-id $PUBLIC_SUBNET_2 \
--map-public-ip-on-launch
Terminal window
# Elastic IP割り当て (AZ-1a)
EIP_1=$(aws ec2 allocate-address \
--domain vpc \
--tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=nat-eip-1a}]' \
--query 'AllocationId' \
--output text)
# NAT Gateway作成 (AZ-1a)
NAT_GW_1=$(aws ec2 create-nat-gateway \
--subnet-id $PUBLIC_SUBNET_1 \
--allocation-id $EIP_1 \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=nat-gw-1a}]' \
--query 'NatGateway.NatGatewayId' \
--output text)
# NAT Gateway利用可能まで待機
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW_1
# 同様にAZ-1c用も作成
EIP_2=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
NAT_GW_2=$(aws ec2 create-nat-gateway --subnet-id $PUBLIC_SUBNET_2 --allocation-id $EIP_2 --query 'NatGateway.NatGatewayId' --output text)
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW_2
Terminal window
# パブリックルートテーブル作成
PUBLIC_RT=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]' \
--query 'RouteTable.RouteTableId' \
--output text)
# インターネットゲートウェイへのルート追加
aws ec2 create-route \
--route-table-id $PUBLIC_RT \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id $IGW_ID
# サブネット関連付け
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_1 --route-table-id $PUBLIC_RT
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_2 --route-table-id $PUBLIC_RT
# プライベートルートテーブル (AZ-1a)
PRIVATE_RT_1=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=private-rt-1a}]' \
--query 'RouteTable.RouteTableId' \
--output text)
# NAT Gatewayへのルート追加
aws ec2 create-route \
--route-table-id $PRIVATE_RT_1 \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id $NAT_GW_1
# サブネット関連付け
aws ec2 associate-route-table --subnet-id $PRIVATE_SUBNET_1 --route-table-id $PRIVATE_RT_1
# 同様にAZ-1c用も作成
PRIVATE_RT_2=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PRIVATE_RT_2 --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GW_2
aws ec2 associate-route-table --subnet-id $PRIVATE_SUBNET_2 --route-table-id $PRIVATE_RT_2
# VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "my-production-vpc"
}
}
# インターネットゲートウェイ
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "my-igw"
}
}
# パブリックサブネット
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}"
}
}
# プライベートサブネット
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}"
}
}
# Elastic IP (NAT Gateway用)
resource "aws_eip" "nat" {
count = 2
domain = "vpc"
tags = {
Name = "nat-eip-${count.index + 1}"
}
}
# NAT Gateway
resource "aws_nat_gateway" "main" {
count = 2
allocation_id = aws_eip.nat[count.index].id
subnet_id = aws_subnet.public[count.index].id
tags = {
Name = "nat-gw-${count.index + 1}"
}
depends_on = [aws_internet_gateway.main]
}
# パブリックルートテーブル
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-rt"
}
}
# パブリックサブネット関連付け
resource "aws_route_table_association" "public" {
count = 2
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# プライベートルートテーブル
resource "aws_route_table" "private" {
count = 2
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main[count.index].id
}
tags = {
Name = "private-rt-${count.index + 1}"
}
}
# プライベートサブネット関連付け
resource "aws_route_table_association" "private" {
count = 2
subnet_id = aws_subnet.private[count.index].id
route_table_id = aws_route_table.private[count.index].id
}
推奨CIDR範囲:
小規模: /24 (256アドレス)
中規模: /20 (4,096アドレス)
大規模: /16 (65,536アドレス)
予約IPアドレス:
- .0: ネットワークアドレス
- .1: VPCルーター
- .2: DNS (Amazon provided DNS)
- .3: AWS予約
- .255: ブロードキャストアドレス
実際の使用可能IPアドレス:
/24: 251個 (256 - 5)
/20: 4,091個 (4,096 - 5)
サブネット分割例 (10.0.0.0/16):
パブリック:
- 10.0.0.0/20 (AZ-1a)
- 10.0.16.0/20 (AZ-1c)
プライベート (App):
- 10.0.32.0/20 (AZ-1a)
- 10.0.48.0/20 (AZ-1c)
プライベート (DB):
- 10.0.64.0/20 (AZ-1a)
- 10.0.80.0/20 (AZ-1c)
予備:
- 10.0.96.0/19 (将来の拡張用)
セキュリティグループ:
- デフォルト拒否、必要な通信のみ許可
- ソースにIPではなくSG IDを指定
- 定期的な見直しと不要ルール削除
NACL:
- 特定IPブロック用
- ステートレスなので注意
- エフェメラルポート許可忘れに注意
VPC Flow Logs:
- 異常トラフィック検出
- セキュリティ分析
- コンプライアンス監査
NAT Gateway:
- 開発環境: シングルNAT Gateway
- 本番環境: マルチAZ (高可用性優先)
- VPC Endpoints活用でコスト削減
データ転送:
- 同一AZ内: 無料
- 異なるAZ間: $0.01/GB
- VPC Peering (同一リージョン): 無料
- VPC Endpoints: データ転送料削減
Terminal window
# 1. セキュリティグループ確認
aws ec2 describe-security-groups --group-ids sg-xxxxx
# 2. NACL確認
aws ec2 describe-network-acls --filters "Name=association.subnet-id,Values=subnet-xxxxx"
# 3. ルートテーブル確認
aws ec2 describe-route-tables --filters "Name=association.subnet-id,Values=subnet-xxxxx"
# 4. VPC Flow Logs確認
aws logs filter-log-events \
--log-group-name /aws/vpc/flowlogs \
--filter-pattern "[version, account, eni, source, destination, srcport, destport, protocol, packets, bytes, start, end, action=REJECT, logstatus]"
Terminal window
# 到達可能性分析
aws ec2 create-network-insights-path \
--source i-xxxxx \
--destination i-yyyyy \
--protocol tcp \
--destination-port 443
# 分析実行
aws ec2 start-network-insights-analysis \
--network-insights-path-id nip-xxxxx
# 結果確認
aws ec2 describe-network-insights-analyses \
--network-insights-analysis-ids nia-xxxxx

実務で重要なポイント:

  • 設計段階: 適切なCIDR範囲、将来の拡張考慮
  • セキュリティ: 多層防御、最小権限の原則
  • 高可用性: マルチAZ配置、冗長化
  • コスト最適化: VPC Endpoints、適切なNAT Gateway配置
  • 監視: VPC Flow Logs、CloudWatch、GuardDuty
  • 自動化: IaC (Terraform, CloudFormation) の活用

適切なVPC設計と運用により、安全で拡張可能なクラウドインフラを実現できます。