🛡️
[Terraform] aws_networkfirewall_firewall リソースから VPC エンドポイント ID を取り出す
はじめに
Terraform を使って AWS Network Firewall のファイアウォールを作るとき,生成された VPC エンドポイントの ID をサブネットのルートテーブルのルートに追加するのは自然な流れですが,VPC エンドポイント ID を取り出すのが大変だったので,やり方を記録しておきます。
例えば以下のように aws_networkfirewall_firewall リソースを定義したとします。
(特に説明のない変数やリソースは,なんとなくの理解で構いません。)
resource "aws_networkfirewall_firewall" "firewall" {
name = "example"
firewall_policy_arn = aws_networkfirewall_firewall_policy.example.arn
vpc_id = module.vpc.vpc_id
dynamic "subnet_mapping" {
for_each = module.vpc.private_subnets
content {
subnet_id = subnet_mapping.value
}
}
}
TL;DR
VPC エンドポイント ID は以下で取り出せます。
[for ss in tolist(aws_networkfirewall_firewall.firewall.firewall_status[0].sync_states) : ss.attachment[0].endpoint_id if ss.availability_zone == "VPC エンドポイントが存在する AZ"][0]
方法
ファイアウォールのリソースの firewall_status
属性の構造は以下のようになっています。
{
firewall_status = tolist([
{
sync_states = toset([
{
attachment = tolist([
{
endpoint_id = "vpce-???" # VPC エンドポイント ID
subnet_id = "subnet-???" # VPC エンドポイントが存在する VPC サブネット ID
},
])
availability_zone = "ap-northeast-1a" # AZ 名
},
# {VPC エンドポイントの個数だけ同じ形式が続く…},
])
},
])
}
かなり深い階層に存在します。生成された VPC エンドポイントの情報は firewall_status[0].sync_states
の set の中に一つずつ入っています。
object 型ならわかりやすいキーを使って絞り込めますが,今回は残念ながら set 型なので,中身を見て絞り込まないといけません。
絞り込むには VPC サブネット ID または AZ が使えます。for
文で sync_states
のループを回し,所望の VPC サブネット ID または AZ と一致するものを絞り込むようにすれば,目的の VPC エンドポイント ID が得られます。
結論
AZ で指定する場合をルートテーブルで使用した例を以下に示します。
resource "aws_route_table" "to_public" {
for_each = toset(local.azs)
vpc_id = module.vpc.vpc_id
route {
cidr_block = "0.0.0.0/0"
vpc_endpoint_id = [for ss in tolist(aws_networkfirewall_firewall.firewall.firewall_status[0].sync_states) : ss.attachment[0].endpoint_id if ss.availability_zone == each.value][0]
}
}
VPC サブネット ID で絞り込むなら if
文を以下に置き換えます。
if ss.attachment[0].subnet_id == "subnet-???"
参考
同じことを思っている人がたくさんいました。
Discussion