
TerraformでIPv6検証環境をサクッと作成する
お疲れさまです。とーちです。
先日、IPv6環境に対応したVPCからIPv6エンドポイントを持つSQSにアクセスするという記事を書きました。
今後もIPv6関連で検証を行いたいときにIPv6に対応したVPCをサクッと作りたいと思ったので、Terraformで作ってみようと思います。下記の図でいうところの赤枠部分を作成するのが今回の目的になります。
コードは以下のGitHubリポジトリに格納しました。
VPCの作成
まずはVPCから作成していきます。VPCはTerraformのパブリックモジュールを使って作成することにしました。
実は最初はパブリックモジュールだけでは、IPv6ネイティブ(IPv6のみ使用可能)なサブネットが作成できないと思っていたので、サブネットをモジュール外に別途追加していたのですが、後からパブリックモジュールのみでIPv6ネイティブなサブネットを作れることがわかりました。そのあたりを含めて解説します。
コードは以下の通りです。
IPv6関連のパラメータについて
IPv6関連のパラメータについて詳しく説明していきます。
enable_ipv6
enable_ipv6
でAmazon提供のIPv6 CIDRブロックを使用するよう指定しています。他には以下のような選択肢があります(マネージメントコンソールのVPC作成画面より)。本格的にIPv6を使うのであればIPAMで管理して払い出したいですね。
assign_ipv6_address_on_creation
***_assign_ipv6_address_on_creation
をtrueにするとPublicやPrivateなどパラメータ名に応じた各サブネットで新しくEC2やネットワークインターフェースが作成されたときに自動的にIPv6アドレスを割り当てられるようになるのでtrueにしておきます。
private_subnet_ipv6_native
private_subnet_ipv6_native
ですが、こちらをtrueにすることで対象種別のサブネットでIPv6ネイティブなサブネットを作成することができます。最初、このパラメータの存在を知らなかったので、IPv6のみのサブネットはパブリックモジュールでは作れないのかと勘違いしていました。
subnet_ipv6_prefixes
***_subnet_ipv6_prefixes
はVPCのIPv6 CIDRブロックから各サブネットに割り当てるIPv6サブネットの「プレフィックス番号」を指定するものです。リスト形式になっており、[1, 2]
といった感じでサブネットの数だけプレフィックス番号を指定します。
プレフィックス番号を説明するにはIPv6アドレスの基本構造から説明する必要があります。
IPv6アドレスは128ビット長で、通常は8つの16ビット(4桁の16進数)ブロックをコロン(:)で区切って表記します。例としてはこのような形です
2406:da14:aae:9900:0000:0000:0000:0000
IPv6 CIDRブロック表記は、IPv6アドレスの後にスラッシュ(/)とプレフィックス長を付けて表します。プレフィックス長によりアドレスの先頭から何ビットがネットワーク部分かを示します。このあたりはIPv4と同じですね。
VPCのプレフィックス長は以下の記事にもあるとおり、「Amazon提供のIPv6 CIDRブロック」でVPCを作成した場合は /56
で固定となります(IPAMの場合は/56
以外にすることも可)。
/56
のVPCをサブネットに分割する際には /56
, /60
, /64
のいずれかからサブネットのCIDRブロックを選択できますが(ご参考)、どうやらVPCパブリックモジュールではサブネットのプレフィックス長を/64
固定にしているようです(cidrsubnet 関数で8bitを追加、56+8で64bit)。
こちらのコードの以下の部分でそれを確認できます
ipv6_cidr_block = var.enable_ipv6 && length(var.public_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.public_subnet_ipv6_prefixes[count.index]) : null
2406:da14:aae:9900:0000:0000:0000:0000
を例にとると、VPC CIDRが/56
のプレフィックス長の場合、ネットワークアドレス部分は以下のようになります
2406:da14:aae:99__:____:____:____:____
またサブネットのCIDRである /64
の場合、ネットワークアドレスは以下の通りです
2406:da14:aae:9900:____:____:____:____
この末尾の00の部分を指定するのが、「プレフィックス番号」となります。例えば[1, 2]
なら以下のサブネットが出来上がるというわけです
2406:da14:aae:9901:____:____:____:____
2406:da14:aae:9902:____:____:____:____
create_egress_only_igw
create_egress_only_igw
はEgress Only InternetGatewayを作成するためのパラメータです。プライベートサブネットからインターネットにIPv6でアウトバウンド通信するために作成しておきます。
subnet_enable_dns64
***_subnet_enable_dns64
は各サブネットでDNS64を有効とするかどうかです。DNS64については以下の記事をご参照ください。プライベートサブネットからIPv4サービス(今回の用途でいうとSessionManager)と通信するために有効にします。
ということで、これだけで前回作ったIPv6対応のネットワークリソース一式が作成できてしまいました。VPCのパブリックモジュールは柔軟性があって使いやすくていいですね。
EC2インスタンスの作成
ここまで出来ればほぼ作成できたようなものですが、続いてEC2の作成をしていきます。
EC2作成のメインのコードは以下になります。
IPv6関連のパラメータについて
こちらもIPv6関連のパラメータについて説明していきます。
セキュリティグループのIPv6設定
まずEC2に付与するセキュリティグループですが、インバウンドルール、アウトバウンドルールの部分にIPv6関連のパラメータがあります。
cidr_ipv6
というパラメータがあり、こちらに通信を許可するIPv6アドレスをIPv4アドレスの代わりにいれる形となります。公開しているコードではすべてのIPv6アドレス(::/0
)へのアウトバウンド通信のみを許可しています。
EC2インスタンスのIPv6設定
次にEC2インスタンスに指定するIPv6関連のパラメータですが、以下の2つを指定しています。
ipv6_address_count
はプライマリネットワークインターフェースに割り当てるIPv6アドレスの数です。1つあれば事足りるので1としています。
private_dns_name_options
には以下の2つのパラメータがあります
enable_resource_name_dns_aaaa_record
はインスタンスのリソース名(例:i-05f495a4de1ece3a0.ap-northeast-1.compute.internal)をDNSクエリでAAAAレコード(IPv6アドレス)として解決できるようにするかどうかを指定するものです。hostname_type
はEC2インスタンスのホスト名としてIPアドレスをつけるかインスタンスIDをつけるかを選択するものになっています。
sh-5.2$ dig AAAA i-05f495a4de1ece3a0.ap-northeast-1.compute.internal
<中略>
;; QUESTION SECTION:
;i-05f495a4de1ece3a0.ap-northeast-1.compute.internal. IN AAAA
;; ANSWER SECTION:
i-05f495a4de1ece3a0.ap-northeast-1.compute.internal. 60 IN AAAA 2406:da14:1de8:eb01:b4aa:aa62:9b5:4fa5
作成結果の確認
Terraform applyすると以下のようにIPv6アドレスのみがついたEC2が作成できました。またSessionManagerでの接続もちゃんと出来ています。
まとめ
以上、TerraformでIPv6の検証環境をサクッと作ってみました。IPv6関連のパラメータの意味を調べたおかげで、理解が深まりました。IPv6の環境が必要になった際は試しに上記のTerraformコードを使ってみてください。
以上、とーちでした。