Hello, I’ve created a route table, and I would like to use mapping, however some of values inside of map is list of strings, and couldn’t find a solution to manage it.
Here is how I’m defining the values
Notice that, if value contains string only, no issue
The issue with nat gateway id, as I have multiple nat gateways
locals {
ipv4 = {
public = {
target = "0.0.0.0/0"
igw = module.internet_gateway.igw_ids # No Issue
}
private = {
target = "0.0.0.0/0"
nat = module.translate_gateway.nat_ids # << Here is the list of strings
}
}
ipv6 = {
public = {
target = "::/0"
igw = module.internet_gateway.igw_ids # No Issue
}
private = {
target = "::/0"
nat = compact(module.private_subnets.ipv6_cidrblock) != [] ? null : module.internet_gateway.egw_ids # No Issue
}
}
}
I think I need to somehow make count.index on that lookup block, but I don’t know how
Your code lacks few details Maybe terraform plan output would be beneficial, too.
As far as I understand you’d have to iterate on length(aws_route_table.route) (where is it?) and the number of nat gateways (rather use for each).
I assume your other might work as those are not lists.
Hello @tbugfinder I’m glad to see you
Here is the output, it fails
The given value is not suitable for child module variable "route_rules_ipvf"
defined at ../Resources/Network/Routings/variables.tf:93,1-28: element "nat":
string required.
@tbugfinder As you already said the others are working as expected, as they are not list of string
So I don’t know how to make something like count.index for lookup() function, believe me I’ve tried many options.
The other option is make a variable, like var.nat_gateway and count it with element like element(var.nat_gateway, count.index) which will work for sure, but in my case I would like to do with lookup
Wouldn’t you have to create more route table entries than just the ones you’re looking for with count and your lookup?
Actually element(lookup(var.ipv4, "nat", []),count.index) should work technically.
@tbugfinder Nope it did not worked
Here is the plan output:
58: nat_gateway_id = element(lookup(var.ipv4, "nat", []), count.index)
Invalid value for "default" parameter: the default value must have the same
type as the map elements.
@tbugfinder So as you can see, I’ve defined my routing rules inside of locals and it can only work with map(string) I’ve also tried with map(list(string)) but it did not work eventually.
So why in my case map(list(string)) does not work
I’m accessing to locals like:
You have defined the variable to be a map of strings, so it isn’t allowed to pass in a list (as that would be a map of lists of strings).
So you have a few options.
You could keep everything as map(string), in which case anything that returns a list needs to be converted to a string (e.g. using join()). Equally anything which expects a list within the module would need the string converting to a list (e.g. using split()). While this would work it is fairly clunky and you don’t get any real type checking (nothing will validate the string can be split into a list).
The option I’d suggest would be to change from using map(string) to an object.
With this option you can individually define the datatypes for each of the different fields (target, nat, igw), with target and igw being string and nat being list(string). Ideally you’d defined both nat & igw as optional so that you don’t have to pass in null values.