2 minutes
Looking up remote AWS NAT Gateway IPs (in Terraform)
The other day I needed to lookup the public IPs of a NAT gateway, in another AWS account, in Terraform.
There’s three ways you could achieve this:
- You can look it up dynamically, as I have. This assumes you have access to credentials which are able to query that AWS account.
- If the other VPC is also managed by Terraform, you could query the state file for this information. You’d need access to the state file, obviously.
- You could look up (or be given) the IPs and just hardcode them or add them as a variable. NAT gateways are unlikely to change frequently unless the infrastructure is frequently being torn up/down so while manual, it would work.
Each of the steps below corresponds to a block of Terraform code.
- Lookup the other VPC, in this came filtering on name
vpc
. - Lookup all the elastic network interfaces in the other account that are;
- In the above VPC,
- Have source destination checking disabled (required by NAT Gateways and NAT instances),
- Requester-managed, which means it’s a network interface that was created by an AWS service.
- Collect data on each of the IPs that we got in the previous step. You’re not ready to use these wherever you need.
- As an example, you could use them in an AWS WAF IP set.
# 1
data "aws_vpc" "other_account" {
provider = aws.other_account
tags = {
Name = "vpc"
}
}
# 2
data "aws_network_interfaces" "other_account_vpc_ngw_enis" {
provider = aws.other_account
filter {
name = "vpc-id"
values = [data.aws_vpc.other_account.id]
}
filter {
name = "source-dest-check"
values = ["false"]
}
filter {
name = "requester-managed"
values = ["true"]
}
}
# 3
data "aws_network_interface" "eni_ids" {
provider = aws.other_account
for_each = data.aws_network_interfaces.other_account_vpc_ngw_enis.ids
id = each.value
}
# 4
resource "aws_wafv2_ip_set" "allowlist" {
name = "allowlist"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = [for eni in data.aws_network_interface.eni_ids : "${eni.association[0].public_ip}/32"]
}
It feels a little bit clunky to me at the moment, but it works. 👌