Check out a free preview of the full Enterprise DevOps & Cloud Infrastructure course:
The "Iterating Through Locals" Lesson is part of the full, Enterprise DevOps & Cloud Infrastructure course featured in this preview video. Here's what you'd learn in this lesson:

Erik uses a for loop to iterate over local variables to generate the dynamic configurations. Values are accessed through the "each" property. Accessing project-specific variables are also demonstrated in this lesson.

Get Unlimited Access Now

Transcript from the "Iterating Through Locals" Lesson

[00:00:00]
>> Now, do we have to have those description and project ID in the main.tf anymore?
>> We're gonna get to that in a second, yeah. We're gonna get to that in a second. Because the first thing we need to do is we need to set up our locals to know which values we care about and which ones we don't.

[00:00:18] I always try and start with that then going to the first part and then being like, boy, what do we rip up? Because there is a couple of caveats here that we haven't talked about yet. The first one is, do you guys think that, are these actually connected yet?

[00:00:34] No, yeah, they're not. We just made some variables and put them over here, right? So what we wanna do is, we wanna actually make our modules use these variables, right? So I'm gonna swap this really quickly. The first thing we want to use is actually a concept in Terraform called for each.

[00:00:53] Now for each, maybe you can guess it. Can anyone tell me what for each might do?
>> Iterates over locals.
>> Exactly, yeah. And so you can see here in my example for_each local_project, right, we're now iterating. We are now using a for loop, essentially, on this module, right?

[00:01:13] That's the first thing we wanna do.
>> Is local, is that a magic variable, or how does it know what local is?
>> So yeah, it's this, again, they're called meta-arguments. And it's this argument right here, this locals is a specific in the same way that we have module and module here.

[00:01:33] We can also have locals, so I could have more than one locals if I wanted, like I could have 10 of them 20 of them it doesn't matter the code. The TerraForm will then merge all the locals together so that you can use them. But it's singular on the left because syntax.

[00:01:49]
>> Wait, sorry. What do you mean?
>> Singular, it's local.projects.
>> That's because that's the actual value I'm using. I'm actually using the locals.project. So you see locals here. And then the dot would be the child you want to select. In that case, then it would be project.

[00:02:06] So, like,
>> So, let's take a list on the locals is the list, and local is the,
>> So, locals is more of, like, the map. And then we have lists inside of that map. Yeah, so locals is like how TerraForm allows us to create variables. And then we create our own variables inside of those locals.

[00:02:27] And we use those. There's no other way like you can either do it as var right or you can do it as locals. Can anyone tell me potentially what might be the difference between var and locals?
>> You usually use vars when you need user input.
>> Exactly.

[00:02:45] Yeah. Whereas locals, it's local. [LAUGH] Yeah, it's just local, right? And so this is where we start leaning on the declarative configuration where I say like, well, this isn't something I actually wanna make configurable as a variable pass to the whole automation repo. This is a part of the automation repo.

[00:03:07] If I wanna make another workspace, I should be able to go into this repo, as we said yesterday, and just make a new workspace, right? So that's the real goal of using locals versus var, is var helps it so that if you're reusing the whole project somewhere else, then you could change variables from that perspective.

[00:03:26] But if inside of that project you have, again, variables and things like that you don't wanna change, then you can use locals.
>> I think the slight hiccup was just that like locals in the local.tf file is a plural word. And on the left, we're using the singular and it's like kind of.

[00:03:43]
>> Its tying what's actually telling this that locals is the local.
>> I see. So Terraform follows basically folder structure. So anything in this folder that's named TF is gonna get joined together. Does that make sense?
>> Yeah.
>> There's no imports. There is imports, but those are three modules.

[00:04:11]
>> And it's just a convention of TerraForm that exactly when you say the word local it will look for everything that has been concatenated together from the locals key word.
>> Exactly yeah.
>> So magic.
>> [LAUGH] sure it's a bit of magic yeah but it's really the scope is within the directory that you're in, so any TF file in that directory Terraform is just gonna go .tf, .tf, .tf, .tf okay, cool.

[00:04:37] Here you go. Right and if you got five locals definitions inside of that, hey go like it just, it's gonna squish them and then give it to you. But if I'm iterating with this my values aren't actually being injected, are they? If I iterate over this, I'm just gonna get one project with the exact same thing.

[00:04:59] Now again, it's one project, but if I add more, it's going to get more projects with the same stuff. So what I wanna do is I actually want to delete this. Again, co-pilot thank you. It's gonna actually populate what I need, and because we're using a four each, we can then use an more magic.

[00:05:17] [LAUGH] We can use a another keyword called Each, which will make it so that Anything in the four that we're currently iterating over we can access that value for it. So in this case we say each.value.description right and then here we actually say each. Nope, each.key, right because it's key value, right?

[00:05:48] Outside of that, that's pretty much it. We've now wired up our project so that it's interatible and that it has dynamic values. So then we do the exact same thing to the work space. So we're gonna do for_each =, thank you, copilot. All right and then again, I'm sure you guys know what we're gonna do next.

[00:06:09] Can you let copilot write code for us? [LAUGH] Each.key, right? Now I'm not gonna, actually let's do this as well, right Now it's actually wanted to do something different but we're gonna do this instead. Here we go, okay. Yeah, each.value.project_id, cool. OK, so do you guys think we're good here?

[00:06:39] Or do you think we might? And again, if you don't get it, it's totally OK, because you'd have to know Terraform to kind of understand this. But there is actually a problem in my code right now. There's something in here that's not fully ready for these four loops yet.

[00:06:53]
>> It doesn't know which project belongs to which workspace.
>> You've clearly used Terraform before, yeah. So the problem here is is that we have module.project ID right, but what do you think terraform is gonna do with this for loop when we have it named project? What TerraForm actually ends up doing is something kind of cool.

[00:07:19] Project goes from this to this. The reason why we can do this is because we're leaning on that key value approach, right. We know that the name of the project we're gonna create is ECI Project. Now a little bit more magic here. If we go back to our main, whenever you iterate over a module or any type of resource, it keeps the main base name.

[00:07:59] Right it'll keep the main base name, but it's got to have uniqueness for any of the other values. So, again, it leans on that map key value approach and then it says, all right, well, I'll tell you what, in this case, we'll just nest it so that you can target which project you want.

[00:08:15] And because we have this naming convention in place that we know, that the key is gonna be the resource name, then we can dynamically tell TerraForm, hey, when you load in the fem-eci-project and you have that populated, give me that ID, right? This is why in the future when we have more projects, we can actually assign them to different workspaces, and we don't have to be worried about dependencies or anything like that, right?

[00:08:46] So this is the last little bit. And again, if we open up both sides, just make sure you've got your code looking like that.
>> So if you were to add a second project in Workspace, you would change both fem-eci project up there and in the workspace?
>> Exactly, yeah.

[00:09:05] So let me give a little bit of a further example. So say if I wanted another project, I'd go like this, right, and say this is example, right? And say if I wanted another workspace, Geez. I'm fat fingering here. I'd grab this, paste this in, right? And then call this example right now.

[00:09:33] Right now, if I just do that, both workspaces are gonna go into the same project, right. But if I go here and I say example, now that project will go into the example workspace, right? This is the configuration domain that we're trying to create for ourselves. Yes.
>> I was thinking, so if we had three projects and two workspaces it wouldn't It would only make two workspaces.

[00:10:02] It wouldn't make two workspaces for each project.
>> No, it wouldn't do that unless you then went into here, right? Because here's where we're iterating, right? And you can't actually do four and fours, right? And we're gonna do that later towards the end of the class. But yeah, you can't actually do four and fours.

[00:10:19] So 5,000 foot it real quick. If you had an array of environments, an array of services, then you could technically deploy all of your services to all of your environments by just iterating over those two arrays. And again, that is a bit of a spoiler for something we're gonna do later.