We have a long(ish) list of ip addresses to trust, for services published by CloudFlare, and rather than asking each team that publishes a service from an account in aws to implement this in their security groups / acls etc. I thought a prefix list would be perfect. I would like to set this up in a central account, that is then shared to all the child accounts across the aws Organisation. Ideally, I would like to avoid declaring more resources than necessary, so I am using for_each loops and a dynamic entry. So far so good. However, prefix lists are not a global object, meaning they need to be created per region, and Terraform requires that this is set on the Provider level. Is there a way to have a single resource declaration work with a single local map to dynamically manage all these moving parts? It seems the fewest steps I can do, is to have a resource declaration per region, and then a local map per provider, which is already making 6 "blocks" for only 3 regions, + 2 lists for ipv4 and ipv6...
Here's the code example:
locals {
# The two ip lists to add to appropriate prefix lists
cloudflare-ips = {
prefixlist_cloudflare_ipv4 = {
ips = [
"10.0.0.0/32",
"173.245.48.0/20",
...
],
type = "IPv4",
},
prefixlist_cloudflare_ipv6 = {
ips = [
"2400:cb00::/32",
"2606:4700::/32",
...
],
type = "IPv6",
}
}
}
# Generate multipel predix lists from the map of ipv4 and ipv6 addresses
resource "aws_ec2_managed_prefix_list" "cloudflare-ipv4" {
for_each = local.cloudflare-ips
name = "cloudflare_${each.value.type}"
# Here is where I have to add a provider for the region, and this cannot be done within any type of loop ?
provider = aws.ap-southeast-1
address_family = each.value.type
max_entries = 50
dynamic "entry" {
for_each = tolist( each.value.ips )
content {
cidr = entry.value
description = "CloudFlare ${entry.key}"
}
}
}
I've tried including a list of strings with region / provider names and calling these directly from inside the loop, but even though it can evaluate a string (e.g. provider = "aws.ap-southeast-1") it does not accept reading from the local map like so:
provider = each.value.region
with error: ā The provider argument requires a provider type name, optionally followed by a period and then a configuration alias.
I guess the next step would be to make this into a module ? Any other suggestions... ?