for_each the RIGHT way!

rw-book-cover

[Music] [Applause] hello in the first video I posted on this channel I I talked about using count as the wrong way to create multiple resources in terraform and I demonstrated that whilst it might appear good in the first instance as soon as you change uh the indices then um you basically have to destroy and recreate resources so the right way of doing it is for each as we all probably know but there's a right and a wrong way of using

for each I've been bitten by this in the modules that I write I had a problem in the landing Zone vending module with it's exact pattern I'm going to show you now and it's really easy to stumble into it and actually quite difficult to get out of it without breaking changes so let's have a look at this really simple example to get us going we have a map of objects so map key Fu uh the map value is an object with an attribute with a string and we've got

the same with bar so we've got Fu with an attribute Fu one bar with an attribute bar one if we look at this resource it's a map this a terraform data resource it's a really good one for running demos and we're for eaching over that map of objects now in reality this will probably be an input variable instead of a local but for the purposes of this I'm just making it a local because it's easier so we've got the input to the terraform data the name is set to the map key Fu and Bar in this case and the attribute is set to the attribute value

so let's see what happens let's just go straight from apply it says up right I'm going to create two resources uh terraform data map of objects bar and terraform data map of objects F and let the name is going to be the key and the attribute the value yeah perfect let's do that done no problem in the real world however this name here might be coming from data

which is outside of this module it might indeed be not known until we've applied it this is typical for um lots of scenarios where you might want to create a dependent resource first and then use its name in something else so for the purposes of this demo I'm going to create a random pet name to simulate something which isn't known until after apply so I've got a quick random pet name and I've got a quick for each on that and I've just called it f and bar so if we apply that you'll see it's

going to create the pet names cool so we've got harmless swine and mint terrain cool so what we'd do now is we'd go random pet. name and then fu. ID now because this is a reference we have to put it in Brackets so if I just copy that and put that here this is

simulating something where we want the name of the object so in this case the map key uh and we don't know that till after apply because uh it's based on something that is generated by this resource so let's run terraform apply cool okay so that's going to delete our original ones which is fine because we changed the map keys and it's going to create two new terraform data resources we got harmless swine and mint terapin names cool so actually what's the

problem doing that that worked let me show you the problem and this is something that you must always do when you're developing terraform modules let's destroy it now let's apply it bang right this is a problem the for each map includes Keys derived from resource attributes that cannot be determined until apply and so terraform cannot determine the full set of keys that'll identify the resources it's going to correct so basically it doesn't know what resources it's going to going to have to

create now this is the bit this is the bit that should be in neon lights on the terapon documentation website when working with unknown values in for each it is better to define the map keys statically in your configuration and place apply time results only in the map values so how do we do that we realize that this is wrong and now we've broken it the only way we can do it is by changing the input schema here not here here

name uh is well let's put that in there actually name is that but I'm going to have to Define this statically okay so what that's done is I've used a static set of map keys that I already know about and I'm putting the stuff that isn't known until after apply

into the attributes now this is fine as long as I change this to each do value. name so let's run that let's clear it cool that's going to work exactly right done so when you create your modules always always always use a map key that is is statically defined as

part of the input don't place any data uh inside those map keys don't generate the map keys from anything that isn't going to be known to terraform it may seem more cumbersome and and it is more cumbersome because this map key sounds like the ideal thing to use for the name of the resource but don't do it you'll fall into this trap eventually and you will be sad because you'll have to make changes to your modules which may be breaking so I hope that makes sense the link to the module repo uh

will be in the description and uh yeah I also link to the other first video I created as well so yeah hope you enjoyed that see you next time