TerraformでプライベートサブネットとNATゲートウェイを管理する
AWSのNATゲートウェイ構成をTerraformで管理する方法を調べたのでまとめます。
NATゲートウェイ構成とは下記のような構成を指します。
次の図は、NAT ゲートウェイを使用した VPC のアーキテクチャを示しています。メインルートテーブルは、プライベートサブネットのインスタンスから NAT ゲートウェイにインターネットトラフィックを送信します。NAT ゲートウェイは、NAT ゲートウェイの Elastic IP アドレスをソース IP アドレスとして使用し、インターネットゲートウェイにトラフィックを送信します。
https://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html
マネジメントコンソールでNATゲートウェイを構成する場合は以下の流れで行います。パブリックサブネットはすでに存在する前提です。
- プライベートサブネットを作成する。
- EIPを確保する。
- パブリックサブネットにNATゲートウェイを作成する。
- ルートテーブルを作成し、デフォルトゲートウェイをNATゲートウェイに向ける。
- プライベートサブネットにルートテーブルをアタッチする。
Terraformの場合は以下のリソースを定義します。
- プライベートサブネット (
aws_subnet
) - EIP (
aws_eip
) - NATゲートウェイ (
aws_nat_gateway
) - ルートテーブル (
aws_route_table
) - ルートテーブルの関連付け (
aws_route_table_association
)
実装例
具体的なコードを見ていきましょう。
説明を簡単にするため、ここではVPCとパブリックサブネットがすでに存在しており、そこにNATゲートウェイを付け加える場面を考えます。
# すでに存在するVPCを参照 data "aws_vpc" "example" { tags { Name = "example_vpc" } } # すでに存在するパブリックサブネットを参照 data "aws_subnet" "public" { vpc_id = "${data.aws_vpc.example.id}" tags { Name = "example_public_subnet" } } resource "aws_subnet" "private" { vpc_id = "${data.aws_vpc.example.id}" cidr_block = "${cidrsubnet(data.aws_vpc.example.cidr_block, 3, 4)}" tags { Name = "example_private_subnet" } } resource "aws_eip" "nat_gateway" { vpc = true tags { Name = "example_nat_gateway_eip" } } resource "aws_nat_gateway" "private" { allocation_id = "${aws_eip.nat_gateway.id}" subnet_id = "${data.aws_subnet.public.id}" tags { Name = "example_nat_gateway" } } resource "aws_route_table" "private" { vpc_id = "${aws_subnet.private.vpc_id}" route { cidr_block = "0.0.0.0/0" nat_gateway_id = "${aws_nat_gateway.private.id}" } tags { Name = "example_private_subnet_route_table" } } resource "aws_route_table_association" "private" { route_table_id = "${aws_route_table.private.id}" subnet_id = "${aws_subnet.private.id}" }
サブネットのCIDRはべた書きしてもよいですが、ここでは cidrsubnet() を使ってVPC CIDRから自動計算しています。以下のように記述すると、VPC CIDRの上位3ビットをサブネットに確保します。
cidr_block = "${cidrsubnet(data.aws_vpc.example.cidr_block, 3, 0)}"
例えば、VPC CIDRが 172.20.0.0/16
の場合、サブネットのCIDRは 172.20.0.0/19
が割り当てられます。サブネットマスク長が16 + 3 = 19になるということです。
cidr_block = "${cidrsubnet(data.aws_vpc.example.cidr_block, 3, 4)}"
と記述すると、サブネットのCIDRは 172.20.128.0/19
が割り当てられます。/16
の上位3ビットに4(100
)を割り当てるので128(1000 0000
)になるということです。説明が難しい。
まとめ
TerraformでプライベートサブネットとNATゲートウェイを定義するのは意外と簡単でした。
See Also: