👌

AWS学びなおし(+TF)_VPC

2025/02/24に公開

AWS VPC (Amazon Virtual Private Cloud) は、AWS クラウド内にプライベートなネットワーク空間を構築できるサービスです。例えるなら、AWS という広大な土地の中に、あなた専用の区画を作り、自由にネットワークを設計・構築できるイメージです。

VPC の主な役割:

  • ネットワークの分離: パブリックインターネットから完全に隔離されたプライベートネットワークを構築できます。これにより、セキュリティを向上させ、機密性の高いシステムを安全に運用できます。
  • ネットワーク構成の自由度: IP アドレス範囲、サブネット、ルートテーブル、セキュリティグループなど、ネットワーク構成要素を自由に設計できます。オンプレミス環境でネットワークを構築するのと同様の柔軟性があります。
  • AWS サービスとの連携: VPC 内で EC2 インスタンス、RDS データベース、Lambda 関数など、様々な AWS サービスを安全に利用できます。これらのサービスは VPC 内のプライベート IP アドレスで通信できるため、インターネット経由での不要なアクセスを避けることができます。
  • ハイブリッドクラウドの実現: VPN や Direct Connect を利用して、オンプレミス環境と VPC を接続し、ハイブリッドクラウド環境を構築できます。

VPC の主要コンポーネント:

  • VPC (Virtual Private Cloud): 独立したネットワーク空間そのものです。リージョン内に作成され、CIDR ブロック (IP アドレス範囲) を指定します。
  • サブネット (Subnet): VPC をさらに細分化したネットワーク区画です。アベイラビリティーゾーン (AZ) に紐づけられ、CIDR ブロックを指定します。
    • パブリックサブネット: インターネットゲートウェイ (IGW) へのルートを持つサブネットです。インターネットからのアクセスを受け付けたり、インターネットへアウトバウンド通信を行うことができます。
    • プライベートサブネット: IGW へのルートを持たないサブネットです。インターネットからの直接アクセスはできませんが、NAT ゲートウェイなどを経由してアウトバウンド通信を行うことができます。
  • ルートテーブル (Route Table): ネットワークトラフィックの経路を定義するテーブルです。サブネットごとにルートテーブルが関連付けられ、宛先 IP アドレスに基づいてトラフィックをどこに転送するかを決定します。
    • ローカルルート: VPC 内の通信を処理するルートです。デフォルトで設定されています。
    • インターネットゲートウェイ (IGW) ルート: インターネットへの通信を IGW に転送するルートです。パブリックサブネットで必要になります。
    • NAT ゲートウェイ ルート: プライベートサブネットからインターネットへのアウトバウンド通信を NAT ゲートウェイに転送するルートです。
    • VPC エンドポイント ルート: AWS サービスへの通信を VPC エンドポイントに転送するルートです。インターネットを経由せずに AWS サービスにアクセスできます。
  • インターネットゲートウェイ (Internet Gateway - IGW): VPC をインターネットに接続するためのゲートウェイです。VPC に一つだけアタッチできます。
  • NAT ゲートウェイ (NAT Gateway): プライベートサブネットからインターネットへのアウトバウンド通信を可能にするマネージドサービスです。インスタンスごとにパブリック IP アドレスを割り当てる必要がなく、セキュアにアウトバウンド通信を実現できます。
  • セキュリティグループ (Security Group): インスタンスレベルのファイアウォールです。インバウンド (受信) とアウトバウンド (送信) のトラフィックを許可または拒否するルールを定義します。ステートフルファイアウォールとして動作し、許可されたトラフィックに対する応答トラフィックは自動的に許可されます。
  • ネットワーク ACL (Network Access Control List - NACL): サブネットレベルのファイアウォールです。インバウンドとアウトバウンドのトラフィックを許可または拒否するルールを定義します。ステートレスファイアウォールとして動作し、リクエストとレスポンスの両方向のルールを設定する必要があります。
  • VPC エンドポイント (VPC Endpoint): VPC 内から AWS サービスへプライベートに接続するためのサービスです。インターネットを経由せずに、VPC 内から S3 や DynamoDB などの AWS サービスにアクセスできます。
    • ゲートウェイ型エンドポイント: S3 や DynamoDB など、特定のサービスで利用可能です。ルートテーブルにプレフィックスリストとして追加されます。
    • インターフェース型エンドポイント: EC2 や ECS など、多くのサービスで利用可能です。VPC 内に ENI (Elastic Network Interface) が作成され、プライベート IP アドレスでサービスにアクセスできます。
  • VPN ゲートウェイ (VPN Gateway): VPC とオンプレミス環境を VPN 接続するためのゲートウェイです。
  • Direct Connect ゲートウェイ (Direct Connect Gateway): VPC とオンプレミス環境を Direct Connect 接続するためのゲートウェイです。

【実務レベルの内容と重要事項】

実務における VPC 設計・構築の重要事項:

  • CIDR 設計: VPC およびサブネットの CIDR ブロックは、将来の拡張性も考慮して慎重に設計する必要があります。後から変更することは困難なため、十分な IP アドレス空間を確保することが重要です。
    • RFC1918 プライベートアドレス: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 の範囲を使用するのが一般的です。
    • 重複しない CIDR: オンプレミス環境や他の VPC と CIDR が重複しないように注意が必要です。
    • サブネット分割: 要件に応じて、パブリックサブネット、プライベートサブネット、データベースサブネットなど、適切な数のサブネットに分割します。AZ を考慮して、可用性を高める設計が重要です。
  • セキュリティ設計: セキュリティグループとネットワーク ACL を適切に設定し、必要なポートのみを開放するようにします。
    • 最小権限の原則: 必要最小限のポートのみを許可し、不要なポートは閉じるようにします。
    • セキュリティグループ vs ネットワーク ACL: セキュリティグループはインスタンスレベル、ネットワーク ACL はサブネットレベルで適用されるファイアウォールであることを理解し、適切に使い分けます。一般的には、セキュリティグループで細かなアクセス制御を行い、ネットワーク ACL でサブネット全体の基本的なアクセス制御を行うことが多いです。
  • ルーティング設計: ルートテーブルを適切に設定し、トラフィックが意図した経路を通るようにします。
    • デフォルトルート: パブリックサブネットでは IGW へのデフォルトルート (0.0.0.0/0 を IGW に向ける) を設定します。
    • プライベートサブネットのインターネットアクセス: NAT ゲートウェイや NAT インスタンスを利用して、プライベートサブネットからインターネットへのアウトバウンド通信を可能にする設計を検討します。
    • VPC エンドポイントの活用: S3 や DynamoDB などの AWS サービスへのアクセスは、VPC エンドポイントを利用することで、セキュリティとパフォーマンスを向上させることができます。
  • 可用性設計: 複数の AZ にサブネットを分散配置し、AZ 障害時にもシステムが継続稼働できるように設計します。
    • マルチ AZ 構成: EC2 インスタンスや RDS データベースなどを複数の AZ に跨って配置し、冗長化します。
    • ロードバランサー: ALB (Application Load Balancer) や NLB (Network Load Balancer) を利用して、トラフィックを複数のインスタンスに分散し、可用性を高めます。
  • パフォーマンス設計: ネットワーク帯域幅やレイテンシを考慮し、パフォーマンス要件を満たすように設計します。
    • インスタンスタイプ: ネットワークパフォーマンスの高いインスタンスタイプ (例: Nitro System 搭載インスタンス) を選択します。
    • プレイスメントグループ: EC2 インスタンスをプレイスメントグループに配置することで、ネットワークレイテンシを低減できます。
    • ジャンボフレーム: 可能な場合はジャンボフレーム (MTU 9001) を有効にすることで、ネットワーク効率を向上させることができます。
  • コスト最適化: 不要なリソースを削除したり、適切なリソースサイズを選択したりすることで、コストを最適化します。
    • NAT ゲートウェイの料金: NAT ゲートウェイは時間課金とデータ処理量課金が発生するため、不要な場合は削除することを検討します。VPC エンドポイント (インターフェース型) を利用することで、NAT ゲートウェイの利用を削減できる場合があります。
    • VPC フローログ: VPC フローログはログ出力に費用が発生するため、必要な期間のみ有効にするなど、コストを考慮した運用が必要です。
  • 運用・監視: VPC フローログや CloudWatch メトリクスなどを活用して、ネットワーク状況を監視し、問題発生時に迅速に対応できるようにします。
    • VPC フローログ: ネットワークトラフィックのログを記録し、セキュリティ分析やトラブルシューティングに役立てます。
    • CloudWatch メトリクス: VPC のネットワーク利用状況やエラーレートなどを監視し、異常を検知します。

実務上の注意点:

  • VPC はリージョンリソース: VPC はリージョンに紐づくリソースであり、異なるリージョン間で VPC を共有することはできません。
  • デフォルト VPC: AWS アカウント作成時に自動的に作成されるデフォルト VPC は、検証環境などでの利用には便利ですが、本番環境ではセキュリティや構成の自由度の観点から、カスタム VPC を作成して利用することが推奨されます。
  • VPC Peering: 異なる VPC 間を接続する VPC Peering は、シンプルな構成には適していますが、大規模なネットワーク構成では、Transit Gateway の利用を検討する方が、管理性や拡張性の面で優れています。
  • Transit Gateway: 複数の VPC やオンプレミス環境をハブ&スポーク型で接続するためのマネージドサービスです。大規模なネットワーク構成や、VPC 間ルーティングの複雑さを解消したい場合に有効です。

【実務でどの程度使用されるのか】

VPC は、AWS を利用する上で 必須 と言っても過言ではない、非常に重要なサービスです。

実務での使用頻度:

  • ほぼ全ての AWS 環境で利用: AWS 上でシステムを構築する場合、VPC を利用しないケースはほぼありません。EC2 インスタンス、RDS データベース、Lambda 関数など、ほとんどの AWS サービスは VPC 内で利用することを前提としています。
  • インフラ構築の初期段階で必ず設計・構築: AWS 環境構築の初期段階で、VPC の設計・構築は必ず行われます。VPC の設計は、その後のネットワーク構成やセキュリティ設計に大きな影響を与えるため、非常に重要な作業となります。
  • 継続的な運用・管理: VPC は構築して終わりではなく、継続的な運用・管理が必要です。セキュリティルールの見直し、ルートテーブルの更新、ネットワークパフォーマンスの監視など、運用フェーズでも VPC は常に意識する必要があります。

具体的な使用例:

  • Web サービス/アプリケーション: Web サーバー (EC2) やアプリケーションサーバー (EC2, ECS, EKS) を VPC 内に構築し、ALB 経由でインターネット公開します。データベース (RDS, Aurora) はプライベートサブネットに配置し、セキュリティグループで Web サーバーからのアクセスのみを許可します。
  • 基幹システム: 機密性の高い基幹システムを VPC 内に構築し、オンプレミス環境と VPN/Direct Connect で接続します。セキュリティを強化するために、複数の AZ にサブネットを分散配置し、ネットワーク ACL や VPC エンドポイントなどを活用します。
  • データ分析基盤: 大量のデータを処理するデータ分析基盤 (EMR, Redshift) を VPC 内に構築し、S3 や Glue などの AWS サービスと連携します。VPC エンドポイントを利用することで、データ転送のセキュリティとパフォーマンスを向上させます。
  • DevOps 環境: 開発環境、ステージング環境、本番環境をそれぞれ異なる VPC に分離し、セキュリティと隔離性を高めます。Transit Gateway や VPC Peering を利用して、環境間のネットワーク接続を構築します。

このように、VPC は様々なシステムや環境で利用されており、AWS を活用する上で欠かせない、基盤となるサービスです。AWS エンジニアとして、VPC に関する深い理解と実務経験は必須と言えるでしょう。

【terraformのコードで記述する場合の基本的内容と実務レベルの内容】

Terraform コード (基本)

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "main-vpc"
  }
}

resource "aws_subnet" "public_subnet_az1" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-1a"
  map_public_ip_on_launch = true # パブリック IP アドレスを自動割り当て
  tags = {
    Name = "public-subnet-az1"
  }
}

resource "aws_subnet" "private_subnet_az1" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "private-subnet-az1"
  }
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "main-igw"
  }
}

resource "aws_route_table" "public_route_table" {
  vpc_id = aws_vpc.main.id

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

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

resource "aws_route_table_association" "public_subnet_assoc_az1" {
  subnet_id      = aws_subnet.public_subnet_az1.id
  route_table_id = aws_route_table.public_route_table.id
}

コード解説 (基本)

  • resource "aws_vpc" "main": VPC リソースを定義します。
    • cidr_block: VPC の CIDR ブロックを指定します。
    • tags: リソースにタグを付与します (Name タグは必須ではありませんが、管理のために推奨されます)。
  • resource "aws_subnet" "public_subnet_az1" / resource "aws_subnet" "private_subnet_az1": サブネットリソースを定義します。
    • vpc_id: サブネットを関連付ける VPC の ID を指定します (aws_vpc.main.id で VPC リソースを参照)。
    • cidr_block: サブネットの CIDR ブロックを指定します。
    • availability_zone: サブネットを配置する AZ を指定します。
    • map_public_ip_on_launch: パブリックサブネットの場合、true に設定することで、インスタンス起動時にパブリック IP アドレスを自動割り当てます。
  • resource "aws_internet_gateway" "igw": インターネットゲートウェイリソースを定義します。
    • vpc_id: IGW を関連付ける VPC の ID を指定します。
  • resource "aws_route_table" "public_route_table": ルートテーブルリソースを定義します。
    • vpc_id: ルートテーブルを関連付ける VPC の ID を指定します。
    • route: ルートテーブルのエントリを定義します。
      • cidr_block: 宛先 CIDR ブロック (0.0.0.0/0 は全てのアドレス宛先を意味します)。
      • gateway_id: ターゲットゲートウェイ (ここでは IGW) の ID を指定します。
  • resource "aws_route_table_association" "public_subnet_assoc_az1": サブネットとルートテーブルの関連付けを定義します。
    • subnet_id: 関連付けるサブネットの ID を指定します。
    • route_table_id: 関連付けるルートテーブルの ID を指定します。

Terraform コード (実務レベル)

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.15.2" # バージョン固定を推奨

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-1a", "ap-northeast-1c"] # 複数 AZ を指定
  public_subnets  = ["10.0.1.0/24", "10.0.2.0/24"] # 複数パブリックサブネット
  private_subnets = ["10.0.11.0/24", "10.0.12.0/24"] # 複数プライベートサブネット

  enable_nat_gateway = true # NAT ゲートウェイを有効化
  single_nat_gateway = true # シングル NAT ゲートウェイ (コスト削減のため)
  reuse_nat_ips      = true # NAT ゲートウェイの Elastic IP を再利用 (更新時のダウンタイム削減)
  number_of_nat_gateways = 1 # NAT ゲートウェイ数を指定 (シングル NAT の場合は 1)

  enable_vpn_gateway = false # VPN ゲートウェイは不要なため無効化

  tags = {
    Environment = "Production"
    Terraform   = "true"
  }
}

# セキュリティグループ (例: Web サーバー用)
resource "aws_security_group" "web_sg" {
  name        = "web-sg"
  description = "Security group for web servers"
  vpc_id      = module.vpc.vpc_id # VPC モジュールから VPC ID を参照

  # HTTP アクセス許可 (インバウンド)
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # 実際にはアクセス元を制限すべき
  }

  # HTTPS アクセス許可 (インバウンド)
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # 実際にはアクセス元を制限すべき
  }

  # アウトバウンドは全て許可 (必要に応じて制限)
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1" # all protocols
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "web-sg"
  }
}

コード解説 (実務レベル)

  • Terraform Module の利用: terraform-aws-modules/vpc/aws モジュールを利用することで、複雑な VPC 構成を簡潔に記述できます。モジュールは再利用性も高く、コードの可読性・保守性を向上させます。
    • source: 利用するモジュールのソース (Terraform Registry) を指定します。
    • version: モジュールのバージョンを固定することで、意図しない変更を防ぎます。
    • name, cidr, azs, public_subnets, private_subnets: モジュールの変数に値を渡すことで、VPC の基本構成を定義します。
    • enable_nat_gateway, single_nat_gateway, reuse_nat_ips, number_of_nat_gateways: NAT ゲートウェイに関する設定をモジュール変数で制御します。
  • 複数 AZ 構成: azs 変数に複数の AZ を指定することで、複数 AZ にサブネットが自動的に作成されます。可用性の高い構成を容易に実現できます。
  • NAT ゲートウェイ設定: enable_nat_gateway = true で NAT ゲートウェイを有効化し、プライベートサブネットからインターネットへのアウトバウンド通信を可能にします。single_nat_gateway = true でシングル NAT 構成にすることで、コストを削減できます (本番環境では可用性を考慮して複数 NAT 構成を検討する場合もあります)。
  • セキュリティグループの定義: aws_security_group リソースでセキュリティグループを定義し、インバウンド/アウトバウンドルールを設定します。VPC モジュールで作成された VPC ID を module.vpc.vpc_id で参照しています。
  • タグの活用: tags 引数でリソースにタグを付与することで、リソース管理やコスト分析を容易にします。環境 (Environment) や Terraform 管理 (Terraform) などのタグは、実務でよく利用されます。

実務レベルの Terraform コードのポイント:

  • モジュール化: VPC などのインフラ構成はモジュール化することで、コードの再利用性、可読性、保守性を高めます。
  • 変数 (Variables) の活用: 環境 (開発/ステージング/本番) やリージョンなど、可変的なパラメータは変数として定義し、コードの柔軟性を高めます。
  • outputs の活用: VPC ID やサブネット ID など、他のリソースで利用する情報は outputs として出力し、参照しやすくします。
  • Backend 設定: Terraform State ファイルをリモートストレージ (S3 など) で管理し、チームでの共同作業や State ファイルの破損対策を行います。
  • バージョン管理: Terraform コードは Git などのバージョン管理システムで管理し、変更履歴の追跡やロールバックを可能にします。
  • CI/CD パイプライン: Terraform コードの変更を自動的に AWS 環境に反映する CI/CD パイプラインを構築し、効率的かつ安全なインフラ運用を実現します。

上記は VPC の Terraform コードの基本的な内容と実務レベルの内容の例です。実際の現場では、要件や環境に合わせて、より複雑な構成や高度なテクニックが用いられることもあります。

Discussion