zaki work log

作業ログやら生活ログやらなんやら

[Terraform / AWS] Data Sourcesでデフォルト(メイン)のルートテーブルを参照する

VPCの作成を行うコードからそのままデフォルトのルートテーブルを使いたい場合は何も問題ないけど、VPCは作成済みで、そのデフォルトのルートテーブルを使いたい場合にプチはまりしたのでその備忘録。

Resourcesで実装する元のコード

TerraoformコードでVPCを作成し、それを使ってルートテーブルを参照するには以下でOK

resource "aws_vpc" "example_dev_vpc" {
  cidr_block           = "10.1.0.0/16"
  enable_dns_hostnames = true

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

resource "aws_vpc_endpoint" "example_dev_endpoint_to_s3" {
  vpc_id = aws_vpc.example_dev_vpc.id
  service_name = "com.amazonaws.${var.region_name}.s3"
  vpc_endpoint_type = "Gateway"

  # これはオフラインのサブネットはデフォルトのルートテーブルを使用してる場合
  route_table_ids = [aws_vpc.example_dev_vpc.default_route_table_id]

  tags = {
    Name = "example-endpoint-s3"
  }
}

元コードはこちらで、今回モジュール分割したくてData Sources経由で実装しようとしたらVPCのData Sourcesが使えなかった、という話。

zaki-hmkc.hatenablog.com

Data Sourcesの場合

データソースを使って「別で作成済みのVPCのデフォルトのルートテーブルを参照したい」場合、データソースのaws_vpcにはdefault_route_table_id属性が無いため、同じ要領では実装できない。

※ ダメな実装

data "aws_vpc" "example_dev_vpc" {
  filter {
    name = "..."
    values = [...]
  }
}

resource "aws_vpc_endpoint" "example_dev_endpoint_to_s3" {
  vpc_id            = data.aws_vpc.example_dev_vpc.id
  service_name      = "com.amazonaws.${var.region_name}.s3"
  vpc_endpoint_type = "Gateway"

  # オフラインのサブネットはデフォルトのルートテーブルを使用
  route_table_ids = [data.aws_vpc.example_dev_vpc.default_route_table_id]  ### NG

  tags = {
    Name = "example-endpoint-s3"
  }
}

デフォルトのルートテーブルが欲しい場合はvpcからたどるのでなく、aws_route_tableのデータソースを使って対象のルートテーブルを探す。

data "aws_vpc" "example_dev_vpc" {
  filter {
    name = "..."
    values = [...]
  }
}

# ルートテーブルのデータソースで対象を定義
data "aws_route_table" "default_route_table" {
  vpc_id = data.aws_vpc.example_dev_vpc.id
  filter {
    name = "association.main"
    values = ["true"]
  }
}

resource "aws_vpc_endpoint" "3s_vpc_endpt" {
  vpc_id            = data.aws_vpc.example_dev_vpc.id
  service_name      = "com.amazonaws.${var.region_name}.s3"
  vpc_endpoint_type = "Gateway"

  # オフラインのサブネットはデフォルトのルートテーブルを使用
  route_table_ids = [data.aws_route_table.default_route_table.id]

  tags = {
    Name = "example-endpoint-s3"
  }
}

解決策は以下で見つけた。

github.com

association.main

このassociation.mainが何かというと、メインのルートテーブルを表すキーワード。

docs.aws.amazon.com

dev.classmethod.jp

association.main - Indicates whether the route table is the main route table for the VPC (true | false ). Route tables that do not have an association ID are not returned in the response.

https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-route-tables.html#options

環境

$ terraform --version
Terraform v1.9.2
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v5.43.0

Your version of Terraform is out of date! The latest version
is 1.9.7. You can update by downloading from https://www.terraform.io/downloads.html

もしかすると「デフォルトのルートテーブル」と「メインのルートテーブル」は実は別でごちゃまぜにしてるかもしれないけど、とりあえず期待する動作はしたよというメモです。

リファレンス