TerraformでAWS VPCを構築してみる

皆さん、こんにちは。技術開発グループのn-ozawanです。
今週から当社は35期となり18名の新入社員を迎え入れました。新入社員の皆さん、頑張ってください。

本題です。
今回はTerraformでVPC環境を構築します。TerraformでVPCやSubnet、Ineternet Gatewayなどの構築方法を紹介します。Terraformでの構築ってこんなんなんだ、という雰囲気が伝わっていただければと思います。

VPC構築

ゴール

今回のゴールは、Terraformで以下の構成を構築します。1つのAvailability ZoneにPublicとPrivateのSubnetを構築します。今回はやりませんが、アプリサーバやDBサーバなどはPrivate Subnetに配置することになります。

VPC

VPCを作成しないと始まりません。クラウド上で仮想ネットワークを構築するためにVPCを構築する必要があり、構築したVPCにSubnetなどのリソースを追加していきます。VPCはTerraformのaws_vpcで作成できます。

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "example-vpc"
  }
}

Subnet

次にSubnetを作成します。SubnetはPublicとPrivateの2つ作成します。

Subnetは、aws_subnetで作成することが出来るのですが、以下のコードを見ての通り、「このSubnetはPublicだよ」という指定はしません。AWSは、Internet Gatewayと直接な繋がりがあるSubnetはPublic、NAT Gateway経由で繋がっている(直接、Internet Gatewayと直接に繋がっていない)SubnetはPrivateであると自動的に判断しているためです。

resource "aws_subnet" "public" {
  vpc_id = aws_vpc.main.id                # Subnetを配置するVPCを指定
  cidr_block = "10.0.1.0/24"
  availability_zone = "ap-northeast-1a"   # Subnetを配置するAvailability Zoneを指定

  tags = {
    Name = "example-public-subnet"
  }
}

resource "aws_subnet" "private" {
  vpc_id = aws_vpc.main.id                # Subnetを配置するVPCを指定
  cidr_block = "10.0.10.0/24"
  availability_zone = "ap-northeast-1a"   # Subnetを配置するAvailability Zoneを指定

  tags = {
    Name = "example-private-subnet"
  }
}

Internet Gateway

Internet Gatewayを作成します。これがないと外部への接続が出来ません。

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id                # Internet Gatewayを配置するVPCを指定

  tags = {
    Name = "example-igw"
  }
}

NAT Gateway

NAT Gatewayを作成します。NAT Gatewayはネットワークアドレスを変換(NAT)するサービスです。Private Subnetから外部へ通信するために必要になります。NAT Gatewayには1つのElastic IPを紐付ける必要があるので、Elastic IPも作成します。

resource "aws_eip" "eip" {
  vpc = true

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

resource "aws_nat_gateway" "nat" {
  subnet_id     = aws_subnet.public.id   # NAT Gatewayを配置するSubnetを指定
  allocation_id = aws_eip.eip.id         # 紐付けるElasti IP

  tags = {
    Name = "example-natgw"
  }
}

Route Table

最後に通信を疎通させるための経路を設定してあげます。Route Tableは3つのリソースで構成されます。

・aws_route_table
  →経路情報を格納する箱です
・aws_route
  →経路情報をaws_route_tableへ追加します
・aws_route_table_association
  →aws_route_tableとaws_subnetを紐づけます。

Route Tableは2つ作成します。1つ目はInternet GatewayとPublic Subnetとの経路です。Public SubnetからInternet Gatewayを経由して通信が行えるようにします。

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id                                  # Route Tableを配置するVPCを指定

  tags = {
    Name = "example-public-rtb"
  }
}

resource "aws_route" "public" {
  destination_cidr_block = "0.0.0.0/0"
  route_table_id         = aws_route_table.public.id
  gateway_id             = aws_internet_gateway.main.id     # Internet Gateway への経路情報を追加
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id                     # Public Subnetと紐付け
  route_table_id = aws_route_table.public.id
}

2つ目はNAT GatewayとPrivate Subnetとの経路です。これにより、Private Subnetから外部へ通信が繋がるようになります。

resource "aws_route_table" "private" {
  vpc_id = var.vpc_id                                     # Route Tableを配置するVPCを指定

  tags = {
    Name = "example-private-rtb"
  }
}

resource "aws_route" "private" {
  destination_cidr_block = "0.0.0.0/0"
  route_table_id         = aws_route_table.private.id
  nat_gateway_id         = aws_nat_gateway.nat.id         # NAT Gateway への経路情報を追加
}

resource "aws_route_table_association" "private" {
  subnet_id      = aws_subnet.private.id                  # Private Subnetと紐付け
  route_table_id = aws_route_table.private.id
}

おわりに

いかがでしたでしょうか。今回はAvailability Zoneが1つだけなど、シンプルな構成となっています。実際にサービス展開を考えた場合、Availability Zoneを複数にしたり、AWS CloudFrontなどのサービスを考慮する必要があるかと思います。

なお、今回紹介したTerraform resourceの詳細はこちらを参照してください。

ではまた。

採用情報

「チームアイオス」入団者募集

〜就活で悩むアナタに来て欲しい〜