Getting into Terraform, Part 5: Modules
1:58:31

Getting into Terraform, Part 5: Modules

HashiCorp, an IBM Company 15.04.2026 760 просмотров 30 лайков

Machine-readable: Markdown · JSON API · Site index

Поделиться Telegram VK Бот
Транскрипт Скачать .md
Анализ с AI
Описание видео
Richard Boyd and Rosemary Wang (Community Team at HashiCorp, an IBM Company) learn Terraform the hard way by diving into the codebase and questioning all their assumptions. In this episode, they learn how to use and write modules. To learn more, check out… Playlist: hashi.co/getting-into-terraform Modules: https://developer.hashicorp.com/terraform/language/modules Developing Modules: https://developer.hashicorp.com/terraform/language/modules/develop Meet the experts - Terraform Module Design: https://www.youtube.com/watch?v=BKtvWiggY7Q #Terraform #HashiCorp #InfrastructureAsCode #AWS #Cloud #Golang #DevOps

Оглавление (24 сегментов)

Segment 1 (00:00 - 05:00)

Welcome to getting into Terraform part five. Hello, hello everyone. Uh if you have not joined the series before, I'm Rosemary, this is Richard. We're going to learn Terraform the most inefficient detailed way possible. So, if you're looking for a 101 course that will get you through like let's say a Terraform associate certification, I mean, might kind of help you. I think Yeah, this will get you there like eventually, just not like in time for like the the next certification to expire. Right. Yeah, we we're just taking our time on this one. Um but, you know, if you haven't joined us for a getting into series before, uh this is a series in which we are going to show the not-so-happy path to learning a tool, in this case Terraform. Uh and so, you're going to expect us to make mistakes. You're going to see us uh you know, sometimes spin our wheels a little bit, meaning we'll get stuck somewhere and we'll have to sit there and think about it. Um you'll probably see us making quite a few mistakes. You might actually know something more than we do about it. So, we want to hear from you. — Yeah, very likely. It happens a lot. Uh we want to hear from you in chat. So, as you are watching us, if you have a trick, suggestion, if you have a path you want us to go down and try, please put it in the chat. But, be welcoming, respectful, and professional as you do. Please follow our community guidelines. Uh that means everybody can participate. As a side note, if you are on LinkedIn, we do see your comments, they just don't come in immediately sometimes. So, if you do have questions, comments after the fact, we will see them after the stream concludes. They just don't always come in real time. Okay. Uh and oh, I got LinkedIn open on my other screen over here, so I will um anything you post, I'll post over there like we did last time. Yeah, exactly. Okay. Um and on top of that, uh folks always ask us, do we have previous episodes somewhere? Yes, we have a playlist. So, check out the HashiCorp YouTube channel, uh and there is a playlist with the previous episodes. So, if you missed us talking uh about you know, who knows what, or you missed seeing us make mistakes and you know, just generally get into trouble, you know, that's fine. You wanted to watch us delete more lock files, you know, we could also do that, too. But, if you missed it, go back to the playlist. Um and if you want to follow along, you have a repository or something that you want to uh check out, we do have one. Uh it's divided into the various parts. So, as we go along, you'll see some of the code that we're configuring and things like that. All right. With that, let's talk about what we did last time. Last time, what did we do last time? Do you remember? Internals. Internals, that's right. We played around a lot with the um backends, dependency graph. We did a little bit of debugging, we played with some of the outputs, things like that. Uh and so, we are doing um Today, we're doing something a little different because we've kind of put this off for a while now. We briefly touched on this idea of modules earlier in the series, and I sort of told Richard we're shelving it. Because the minute we try to talk about modules, it dedicates itself to probably a whole episode, maybe two. We'll see if we'll even get through it, cuz I don't know if we will get through it. Uh and so, the modules um today, we are talking all about modules. Like, you know, so uh be prepared, everyone. We're going to be talking about using them first, and then we'll talk about writing them. I don't know if we'll cover testing today. We can probably cover module testing, but it's probably better to cover that separately. I don't know. We'll figure out something out. Um and in terms of other logistics, because today's a very long logistics discussion, but we are actually not streaming the next 2 weeks for a couple reasons. Richard is at conference. Yes. I'll be at the last Friday and Seattle next Tuesday. So, if you're seeing this before next Tuesday and you're in the Seattle area, feel free to stop by. Yes, yes. So, he is in conference and I am preparing for Bob Dev Day. So, if you uh want to know about IBM Bob, uh probably you know, you can go ahead and uh sign up. There's like a Dev Day on April 30th. I'm preparing it, and you know, it's a little bit busy the next few weeks. So, we we're not going to stream the next few weeks, but we will pick up in May. With that, let's get started. Richard. Let's do it. When I say a module, not Terraform-related, but what do you think of? Um I think of like I'm sure it's probably like the Gang of Four book, but it's like this abstract uh computer science term of like modularizing your code to make it more like reusable of defining an interface, writing an API for it that people can kind of poke it, let it do whatever it needs to do, and then gives you an expected result back um without having

Segment 2 (05:00 - 10:00)

to like deeply [clears throat] understand how it does the various things inside of it. Uh to me, it brings imagery of like uh uh packaging things up in the little boxes that have like very clear kind of ports on them. Yeah, yeah. Uh also, uh for those who are not software engineers in the chat, and you're like, "What's Gang of Four? " there are some folks who are real big thought leaders in software engineering and design space. Lots of thoughts and concepts that describe how we should be writing code, right? So, uh and one such large book, I don't know if you actually have read through the whole thing. I had to like skim through it. It was hard. — It's hard. Anyway, so check it out. Software design patterns. Um anyway, so yeah, that's the thing about modules. The funny thing about modules that I would say people don't really recognize from a code perspective is it just makes it easier for someone else to use, right? It's easier for someone to just pick it up and use it uh without necessarily caring about what's in it, right? They're assuming There's sort of a trust in that if someone is using a module, they are trusting that the person who wrote the module knows what they are doing. Um and knows exactly what defaults go into it, how things are going to be configured. So, as someone who's the consumer of a module, you think it might be easier, right? It might be easier for you to just get what you need without necessarily diving into the Terraform configuration or diving into whatever code configuration the module you know, captures, encapsulates. So, yeah, it's uh yeah, someone was saying like, "When I hear module, I think of shutting down HAL 9000 by ripping out hardware modules. " Yes, that is actually the case. Uh probably came from hardware modules. Uh so, the interesting thing about Terraform modules is that they are just pretty much written using the Terraform configuration that we've been playing around with. So, if you watch episode one, episode two, anything about the configuration language, a module is pretty much written the same way in Terraform. The biggest difference is how you package the module and give it to someone else to use. So, a very good example of this is let's say I am uh not very familiar with infrastructure, Terraform. Don't really care about AWS, I don't really care, right? But, I ask Richard, "Richard, you know a lot about deploying AWS infrastructure, I need a database. Give me something that deploys a database. " And Richard would lovingly craft the module and say, "Here, Rosemary, go to this link, add this Terraform configuration, use this module. " And it creates me you a database on a private network with all of the right security group rules, everything is secure by default. Right? And I can be like, "But, Richard, I want maybe like Postgres 16, and I don't want Postgres, you know, whatever version. " Is that what I'm doing? Yeah, 15 or something. 16. So, I want Postgres 16, and Richard will tell me, "Don't worry, Rosemary, you can pass in a variable that says Postgres 16 as your engine, right? " So, in this process, there's this again, this assumption that you have a module producer, someone who writes the module, and a module consumer, someone who uses the module, and the module consumer ideally doesn't really care or shouldn't really know or doesn't really mind whatever's in the module itself, right? Um and again, there are a couple reasons that you do this if even if you it's not just for the sake of I don't abstraction. I don't like using the word, but it's not for the sake just for the sake of abstraction. The I find myself using modules a lot because I want to be efficient, because I don't feel like writing a hundred million times how to deploy a VPC with like three subnets. It's just too much trouble. So, just use a module. Uh because I don't want to regenerate it myself. I don't know how often you use modules, Richard. Uh fairly frequently. I would say like every template I'm trying to think of like every like thing I deploy probably includes at least one module. I'd say at least two. I think at least two. For anything larger than like a hello world, like the stuff that we're doing, anything larger than something like that, I usually include at least one or two. Yeah. So, first thing we're going to do is um we're going to use a module because why not? That's how we're going to do this. Uh and so, we're not going to write a module to start because we're going to assume that you are Richard, you are a consumer of a module. And like as you pointed out, you use two module about two different modules like, you know, regularly. So, what are those two modules that you typically find yourself using? Um there's Let me get the exact name so I give them credit. Uh I use one from uh Cloud Posse called label that like automatically puts like the tags and naming stuff on uh the um resources that are created. And then it's I put like all of the Terraform AWS

Segment 3 (10:00 - 15:00)

modules into like a big bucket of like the module for AWS because it like it does a really good job of like wrapping up the AWS provider, but like Lambda and API Gateway are the most common modules I use for AWS. Okay. Um and so I will I'm going to ask you, what would you like to deploy? Like what are you comfortable configuring right now? Do you want to uh do the tag module? do the Lambda one? Yeah, let's do like a um like a very simple like uh serverless app on AWS with like API Gateway, DynamoDB, Lambda function. Okay. All right, let's try that. Um in the order of operations of what gets deployed first, let me think. Is it DynamoDB gets deployed first? Uh yes. Yes, okay. So let's just do DynamoDB first. We're not going to write the module, we're just going to use a module out of the box, right? Uh okay, so I you're using have your screen, right? Or actually I'll share my screen cuz I'll show folks what we're going to be using. Um Okay. I'm going to go registry. Yeah, so share screen. Clearly I was prepared to share the screen. Okay. So if folks uh if you are looking for modules uh publicly, there is a registry. Um this registry has a number of modules. So you'll notice a lot going on here. Um most of these are most of the ones that are kind of like listed under provider, these are approved or uh I would say blessed by our partners or blessed by HashiCorp. Um and so you'll see there's Az- Azure, there's um Google, there's also AWS. Uh you'll see a number of folks using the AWS modules. The Terraform AWS modules is probably the most popular one. Shout out to Anton for maintaining those um and facilitating a community around that. Um there's also the You'll also notice AWS uh also publishes modules as well. Those are from their infrastructure architecture team uh architecture team, I think, IATs. Um and they're ones that uh kind of have additional patterns that I would say are like vetted from a security perspective, right? So it's up to you which modules you choose to use, uh but big disclaimer that I'm going to put on this. These are public modules. Like any public code that's out there that you're leveraging for yourself, do your due diligence. Make sure you do um static analysis. Make sure you're um checking the configurations that they're offering secure configurations and secure options, right? That you can configure. Um there are often times, you know, you just want to be a little bit more cautious if you're using a community module that's kind of publicly out there, maybe not uh vetted by a partner, maybe not vetted through the public registry, right? Not all modules in the registry are uh are analyzed or scanned, so use at your own risk. Just be aware that if you do decide to do uh use a public module, please do your due diligence. I'm putting that disclaimer on there. — Uh okay, so we're going to do DynamoDB. So let's see, maybe we can find DynamoDB module. Oh, there is. DynamoDB table, yeah? Is that the one? Yeah, that's it. — Okay. So I think this is the one that we're going to use. Um and then Richard, I'm going to switch over to your screen cuz we're probably just going to jump right in, right? And — Sounds good. we're going to talk about how we use this. Remove and add that. Okay. So you've got your Terraform configuration already prepared, great. Um we're going to start by uh using this DynamoDB module. Can So let me see if I can pull the uh you know what we'll have to do is spice scratch, but um you'll do module sp- uh and then uh quotes Terraform AWS modules. No, sorry. Mod, sorry. Module DynamoDB. We're going to do module DynamoDB, sorry. No need for module prefix cuz we already that's already going to be So that's this is what they call the module block. All right, and then you'll put little squiggly bracket and enter source equals and then in double quotes Terraform -aws -modules /dynamodb table. /aws. Is that it's underbar, yeah? — Yeah, it's underbar. Or no, it's a dash. Not underbar. Not underscored. And then uh ver- hit enter and then version equals double quote 5. 5. 0. Okay. So we're going to talk a little bit about this. First thing is that the module uh top also has an I uh an identifier, right? So mod- line 11, module semi-identifier. Could be anything. Usually it's more descriptive

Segment 4 (15:00 - 20:00)

to talk about the exact set of resources you're deploying, right? Um and then you have source equals Terraform AWS modules/dynamodb /aws. This is very important. So any module that you find will have generally the form of uh Terraform-provider-module name. Uh and this is how you have to name it in GitHub in order for it to be uploaded to the public registry. So um when Terraform is pulling it down, this source uh the source string is using what is called the remote uh what we talked about last time in internals, which is the remote server repository, right? Where it's looking for the specific uh is it Yeah, remote service discovery. It's using remote service discovery. Um and so what it's doing is it's looking for this module in by default the Terraform public registry. Now there are other ways that you can change the source to other sources, which we can do later, but for now we're just going to do this, right? This is probably your most of the time the default configuration you'll use unless you're in an enterprise where you might point it to your own private registry. So that's why we'll talk about it later, but when you're just sort of doing initial development work, this might be where you're pointing to. Um and so you'll notice most of the modules have this kind of string structure of this is the namespace, so Terraform AWS modules, that's the namespace for the owner or the maintainer. Uh and so that's the owner namespace. Then you have the type, which is DynamoDB table, so that's the name of the module, and then AWS is the provider. So you'll see most of the time this follow the same kind of format, and that's how you declare the usage of a module from the public registry. But it's not the case it's not always the case where you're going to use a module from a public registry. Um source can change to GitHub. It could also change to, you know, a number of different places. Um it could be any Git repository. It could be I think even like any artifact repository as well. Um as long as you package it correctly. Yeah, you can even do like a local file I did that when I was uh building a provider. Yeah. Um we're uh it's actually um it's actually a very important thing that uh you use locals sometimes just for the sake of um being able to test when you create a module, right? Um and so there there's some interesting things here that, you know, you want to make sure you keep in mind when you do source. Some things are signed, some things are not. So in this case it is checking the signed um binary the signed binary signed packaging when it comes down from the module registry, but not all uh sources will do that for you. Okay, and version is also very important. You do want to pin versions because sometimes things are not backwards compatible in modules. So for example, if someone uh removes an attribute, right? And like let's say someone says, "No, you're not allowed to change the size of the database anymore," right? And so they'll take away that variable, then it's no longer backwards compatible. So version pinning the version is very important, so that's why we always put module version. All right. So that's modules. Um and so the next thing we're going to do is use the module, which I have to pull up the exact reference. Okay. So most modules have a kind of like a basic example, and they have inputs and outputs. So we need to keep in mind what those inputs and outputs are. Uh I Is there a way that you could pull up the Terraform registry browser on your side? I could pull it up on my end, but maybe Yeah, yeah, I have my side. Yeah. So if you go to DynamoDB table, if you search for that one. Meanwhile, uh while you open that up a little bit more, I'm going to check for questions. Oh, yes. So someone asked uh long living pain point of a Terraform module is you cannot customize life cycle inside a module by variables. So fun fact, there is I think a beta out a beta out of Terrif- of the next version of Terraform. I think 1. 15. There's a beta out where you can do this. So it has been a long pain point, but there I believe in 1. 15 it's dynamic there is a support for or is it release candidate? It's not a beta, it's a release candidate. There is support for a uh dynamic configuration of variables in modules. So I believe that is the case, but I Let me see if I can pull it up. Yeah, there it is. Here. Let me put that in the

Segment 5 (20:00 - 25:00)

chat. So, let me the so folks can see it. And I'll put it on Yeah, so check out 1. 15 release candidate one. Um there is a new feature. It is Terraform now supports variables and locals and module sourcing and version attributes. So, for those who are crying over that pain point, uh check out 1. 15 when it's uh when it's out. Yeah. Very excited. Okay. — [clears throat] — So, let's do a very basic version of this. Uh a lot of the modules that you'll find have some kind of basic example. It's just as a module producer, they're very nice. They will make examples for you so you know how to use it. Uh and so um the one thing that I will say is that we'll probably copy this and then make some changes. So, you at the Dynamo at the very least you should create a name, a hash key, which I guess is ID cuz I don't have any other reason any other attribute to hash on. Um and then attribute, which is type number. I don't know if there's anything else on a table that you put for a lambda function or if you have one, but Uh no, I mean for this we'll just do like a super basic like CRUD type app. We won't write the actual like lambda function code. Okay. Yeah, we don't even have to deploy the lambda. The point is that we're just doing this sake of example, but All right. Um and so this is a very basic example, uh but if you go back to the Terraform registry page and you scroll up, it has a lovely little tab that says inputs. Yeah, so you can actually look at these and it will describe to you what are the required inputs as well as the optional inputs. Um and so apparently there are no required inputs. So, that means that there are some defaults set. We don't know what those defaults are, but neither do we care. Maybe. — [clears throat] — That seems wild to me cuz I don't like so Dynamo requires a hash key and an attribute a hash key that has to point to an existing attribute and an attribute. So, Mhm. I assume that I mean they have to be setting some like standard It's probably this uh as like the default if you provide nothing, but — Yeah, exactly. Well, you can check actually. So, if you open or if you scroll down, it will tell you the defaults. So, if you scroll down and you look for a hash key, it's all alphabetical. So, if Huh, oh, null. Very interesting. So, there is a null value in Terraform, by the way, which means that someone can check for the null value and then map a default. So, we could actually check in the module what is what it's doing. So, if you go up scroll up, there's a GitHub link to the module, to the source code. This is really helpful, right? If you don't know what the default is, it's not clear from documentation, you want to understand what it's doing, go into the GitHub uh URL. That's usually or the Yeah, usually GitHub, but GitHub URL that's linked for it. Um and then if you scroll down and we'll look at the Terraform code, main is probably the place we want to look first, right? Because that's where the DynamoDB table is going to be created. So, — [clears throat] — interestingly enough, it has a the hash key is also just going to be passed null, which means I have a sneaking suspicion AWS is going to be setting the default. Because if it's null, because the hash key goes in as null, right? It's um So, you know, we only we won't know what DynamoDB will do. So, maybe you know, if you again, if you don't know, you have to look do this checking. Yeah, so let's see. Hash it would be hash key, right? Mhm. Oh, yeah. They only require table name. — WHOA, SEE? The more you know. Uh That is interesting. What does it say? That's a new table. Yeah. That is I thought it I thought that was for the partition key was required. — you know, the more you know. — Well, now we know, But yeah, now I'm super interested to see what it does for um like as a default if you provide nothing. Well, you could just take that. So, just do nothing. I think it Yeah, you could just put nothing there, right? So, take out all the attributes. Right? We'll just keep it super simple. I don't know if you need the tags or not either, but um and then I guess the name is also default, right? So, let's see what it defaults to. Oh, the name is required, but Oh, the name's required? Well, the name is not required, but Uh okay, so I guess here's the other thing that's kind of um you have to be aware of, right? So, modules themselves also have version constraints. The modules themselves will

Segment 6 (25:00 - 30:00)

tell will actually constrain what provider version they're using. Because again, backwards compatibility. Let's say there's a new provider that's out and somehow you are using a really old provider on your main configuration and not on the module, your module's going to be like, "Hey, I'm using some newer stuff that doesn't use the current version of Terraform you have. " So, for us what we're going to do Oh, yeah, you could do versions and you can check out what they're constraining it to. Um you'll notice it must be greater than or equal to 6. 28, which means that's the one they've been tested against, right? So, you can do uh 6. 0 or you could do 6. 28 is fine, too, if you want to be really specific. But we're just going to do a soft constraint. There you go. So, you're going to run a Terraform init and modules are going to be doing the same thing as providers in that it gets downloaded into the dot Terraform directory. So, you'll find modules also get downloaded. Um which is kind of irritating to a certain degree because uh if you open that drop-down and you open modules, the whole module gets pulled down, right? It's almost a sub-module Git sub-module. Um and so — Yeah, I was just about to ask, is that the entire GitHub repo? Yes. So, that's a Git sub-module effectively. Um and so it's great in some ways because, you know, if you ever go offline, you can always run against the Terraform module run the Terraform module anyway, but the downside to this is if you do a if you try to find things, you might accidentally overlap with the module. So, whatever that is pulled down in the module. So, just FYI, if you are um pulling them down and stuff, you might accidentally search for things in them. Um — [clears throat] — Yes, that is something to keep in mind. So, now we can do a Terraform apply and see what happens. Oh, so name is null. So, interesting, null can't be formatted, which means that name is required. So, I think there has to be something we update in the module itself. Um maybe a PR for the module. But that's fine. Okay. I don't remember how long it takes for a DynamoDB table to create. I don't think it takes long. Really quick, yeah. Member must not be null. Aha, so there are some test constraints. There are some constraints. Yeah, key schema, yeah. — Yeah, so we do need to actually I This is I'm not blaming Anton for this. I'm blaming AWS. They've got like the most confusing API, yeah. — or it's cuz like DynamoDB is like one of like their I would say it's one of their old It's a very old service, relatively speaking. And what they'll do is they'll like add new features, but in order to like add it in a way that's like backwards compatible cuz they have a such like an obsession on backwards compatibility that they'll make things that used to be required become optional, but it's like conditionally optional. It's like optional if you do this other thing, which I suspect it's like there's some kind of like table replication or creates a replica of a table and you don't have to provide a key if you have a table replica because it's going to copy it. So, it's like it's not required, but like it is required as we're seeing here. Yeah. That's my assumption. I don't know exactly what why it's like that, but that's if somebody held a gun to my head and said, "Guess why it's doing this? " that would be my guess. Well, there you go. The more we know. See, it's like now I we I probably a matter of also documentation, too. Like I said, it's not um you know, it it's a community. This is community maintained, right? So, um some things might be a little bit outdated and there are just so many AWS resources, too. It's really hard to keep track of all these modules. So, um I would say that if you know, you know, eh, you know, if you are maybe only creating one resource at a time, you might not care. You might not need a module at all, right? I mean, in all likelihood, someone who's creating a DynamoDB table, if it's really only one resource, just the DynamoDB table, you probably will just create the DynamoDB table. Um the module sort of like takes away some of the complexity if it's really rather opinionated, but that's this is a whole other discussion when we get to the writing module section. Yeah. Yeah, so even if they are just like just creating like any EC2 instance, um I would argue that they probably are going to use a module and like things like that because like AWS is notorious for this. Like there's so much other configuration, like you have to put it in a VPC, you have to have public subnets, private subnets. Like the my like for creating even just a single resource, there's like a bunch of other stuff. And uh what's that called? Instance profile like the IAM role that's to be attached to it that the modules help uh remove a lot of that stuff that AWS requires you to set but isn't needed for most of the use cases. Yeah. All right, let's try running this again. Try it one more time.

Segment 7 (30:00 - 35:00)

I'm trying there like Oh, yeah, there's some questions in chat. Okay. Has there been any discussion about render template versus modules? Right. So, that's a good point. There are some folks who choose to do like a render template and that renders out the variables and everything else into Terraform. Versus package code like which is kind of what modules are approached approaching. Uh We haven't discussed it yet, but it's a good point. I have seen people do both. And in my experience, anybody who's a software engineer prefers to prefers or understands the render templating approach. And it is fairly I would say more dynamic, right? A render template approach can be a little bit more dynamic. But a lot of the people that I talked to who are platform engineers or folks who are very infrastructure focused, they prefer the modules and they prefer distributing things as modules. Um And I think it's for a couple different reasons. Render templates take a lot of testing for you to know whether or not that template has been rendered correctly. Not to say modules themselves don't need testing. They should be tested. But in my experience, I spend more time writing tests to figure out if the render template is correct, I'm parsing through it, than I do testing the functionality of the module. But that's just, you know, sort of I think maybe difference in skill and preference as to how to capture that logic. Okay, so we have a database. Can you zoom in on that cuz it's small? Oh, no, no, sorry. I was trying to use the shortcut key. I zoomed a different window. Oh, huh. Okay, so now we have it. There you go. There is an active table and yeah, that's good. We have a partition key. A lot of defaults. And so there we go. We used a module. There are a lot of things that kind of got passed in as a default and we didn't override, right? So, if we did want to override some things, we would change those attributes as we see fit. But for the most part, we just only created the partition key as ID, which is a number. And that's pretty much it. Yeah. That's how you would use a module. Now to set two modules together, what's our next module? Is API Gateway or Lambda? Oh, we'll do Lambda. We could be very clever and have like API Gateway that directly interacts with the DynamoDB thing, but that would anger a lot of people just because you have we'd have to write a bunch of ETL code to like stitch the two together and uh that would not be fun. — Okay. Lambda it is. All right, so Lambda is a little bit of a trickier exception, I think. Lambda is trickier. That is what I will say because Lambda doesn't You have more experience with Lambda, I think, but Lambda doesn't really follow the same pattern as some of the other Terraform resources. It's like you have to package things and then you push them up and then deploy them. So, it's a little different. Yeah. Yeah, so Lambda has this ability where you can like I would say there's like three main approaches. So, one is for some languages, you can directly write the code in the definition itself. It's what like CloudFormation supports this, what they call the zip file. There's and then there's also packaging it and putting it in the S3. So, you zip it all up in a very specific file format, put it in S3 and then you reference it. That used to be what I do the most often. Now lately, I've been like everything is container images just cuz it makes uh reusing it or like updating the architecture. So, I'll start with oh, I want to use Lambda and then realize there's some constraint in Lambda where I can't use it and it's easier to take a thing that's already a container file and just move it onto Fargate or ECS Fargate or something else than it is to take a thing that's this weird complex like Python setup wheels thing to like okay, now how do I like take this thing and then containerize it and also migrate it. Yeah. I I do favor the container just cuz I'm really not great with stuffing. I don't know. I like the way that Lambda packaged, it was just very challenging to deal with, so I'm you know, I'm also just I also like containers. It's just easier. Okay, so which one do you want to do? I think the store package locally. I don't know if we have a Lambda package or we have one off the, you know, Uh You have a hello It was Python. I can I

Segment 8 (35:00 - 40:00)

You have a hello It was Python. I can write one. We'll see if I can write one from memory. That should be a — Oh, challenging yourself. You can you should teach people how to write a Lambda function. Short tutorial on Yeah, that should work. Okay, yeah. Let's write the module and then I'll write the code for it cuz then we can test to see if I did it right. Yeah. I don't think we needed to put the API Gateway, but I think it's efficient cuz it would be nice to show the dependencies between handled between modules, right? So, let's aim for that. Okay, so we'll copy this and then we'll version constrain it because again, version constrain your modules, please everyone. Check the module. Yeah, normally I would assume that like because it's all in the versions are the same, but oh, see yeah, this is a latest. 870. I think something is funky with this. — 870 is the late Oh, yeah, there you go. I don't know what happened there. Oh, yeah, I was so confused. I was like, wait a minute, what happened? Yeah, version 870. — [clears throat] — I thought I like forgot how to go. Oh, no, that's fine. 870 and then — [clears throat] — Yeah, this is why I know I'm going to end up in some trouble because I think I have 43. 14 on my machine. But I think it's okay cuz nothing's compiled. I'm not going to pull in any dependencies or anything wild like that, so that should work. I mean, you could change the as the run does it not support it? I think it does, but it'll be fine cuz it's all interpreted, so it'll it should work. Okay. Famous last words. — Yeah, we'll call this source. And then new folder and I'll call this Richard. Um Yeah. And — And that means you have to change the source path, right? Cuz that's — Yep. Yeah, that's why I specified different ones so I could point that out. And then in the handler, it has like index as the file name, so I'm just going to reuse that one. Oh, okay... py Okay. And then yep. Def, what was it? And then this is the actual function that gets called. And then it's event and then context, I believe is the two. Running it. — While Richard sits and you know, writes this drafts this initially, folks, you're probably wondering, why are you not using an AI coding agent to do this? Well, I said we were doing this the most detailed inefficiently possible. And it's not that we are not going to use an AI coding agent, which we probably actually do later on in this series. Again, we're showing this is the most detailed inefficient way possible, so if you are doing this on your own and you have a coding agent generated, you're able to critically review and understand what the coding agent is doing, right? The key here is that we don't, you know, it's not that we're completely averse to using it. We're using Bob as the IDE right now, but we are trying to avoid generating code with the AI coding agent just so that at least as part of this series, you're able to understand what is worth reviewing and what's not worth reviewing. — [clears throat] — Yeah, I'll just set something up for later. Okay, so Cool. We changed this to this um for the source path. I think this is like relative to where like my main TF, like the root of it is, so that I think this worked. — Right. So, then I changed this to Richard function. I think that should work. Okay. — work. Yeah, so this will create a Lambda function and there's already DynamoDB table. They are [clears throat] not connected in either way. Mhm. And we already see some of the benefits of the module here because typically a Lambda function, I mean, a Lambda function needs a role to run and we didn't have to specify it, which I'm assuming is because either the module is creating some generic executioner for us or AWS API is supporting that. But the good news is I don't have to care about either one of those. Like I just know that someone is doing it. Oh, I did not install it. All I have to do is Terraform it. Yeah, it is helpful. Like I said, if you don't know anything about Lambda or you

Segment 9 (40:00 - 45:00)

just don't want to write in a whole bunch of resources and things like that, it's just easier to use the module. But I think part of this is you understanding also what the module's doing. So you might need to do a little bit of checking. So you'll notice that it does break out the module into exactly what is being created, right? So there's a local file that's being planned and archived. There's a Lambda function. Yeah, the role. Policy and the role. Mhm. Nice. Uh so Terraform fortunately work will break out what resources are going to be created as part of the module and every resource is prefixed with module dot. Oh, interesting. Yeah, I was doing some work with Sentinel last week and the thing I was working on kept like looking for the name to be prefixed with like module dot or like I was like why is it I wasn't quite sure why it was doing that and then now it makes a lot more sense. Yeah, cuz it's thinking it's a module. Yeah. So it's a remember part of the Terraform addressing approach in that anything that's just a plain old resource is just Lambda whatever the resource name you know dot whatever versus there's the mod if it's in a module it'll be created in a module. Oh, look. There you are. Wow, awesome. — moment of truth. Uh — Let's this should Yeah, we got it. — it. All right, you did for memory. Okay, so we did that. Uh now what we are going to do is we have to show some dependencies between modules. So we have a module that is doing the DynamoDB table, but our Lambda needs the DynamoDB table name for yeah, table name, right? Yeah. Or ARN, we can pass the ARN even. I don't really care. Uh it's the table name. The API yeah, the boto3 API uses that table name. — Yeah, uses table name. Yeah. Uh so yeah, so I don't in the Lambda function it's set as an environment variable. Is like the You can print out the environment variable. That's fine. At least it shows the dependency. We don't actually have to have the Lambda. Like call it? Yeah, we don't have to have the Lambda like call it. It's fine. You could just do that. Yeah. Okay, so we're using an environment variable called table name and then we'll print out the DynamoDB table name. Uh and so the thing that we're going to do here is we're going to pass in um an environment I think an environment variable, right? We're going to set an environment variable. Yeah. So environment variable. I think this is must be a map structure. How about since yeah. — Yeah. Okay, so be table name. So Yeah. And then we're going to well, pass the table name from the module. So this is what's really nice about modules. We are going to reference the previous module. So module dot DynamoDB Yeah, it's DynamoDB. Yeah, DynamoDB dot I think outputs. Do I need to put outputs? Yeah, outputs I think. So Yeah. Or no, you don't need outputs. I'm sorry. That's because that's I'm thinking Terraform remote state. You don't need outputs. You just need the DynamoDB table ID. Where's the name? I think the ID is the name. Okay, yeah. You just need that. Yeah. And so what this will do is it will do the lovely Terraform interpolation where it will take the output from that module and put it into the other module, right? So Um yeah, there you go. And so I guess you could change you could check the change the plan or whatever, but We're very we're so confident Yeah, just do YOLO. Yeah, I know. I should be able to see configuration. Environment variables. Give it the old refresh. There we go. That's the name of our DynamoDB table. And then just to And that's where [clears throat] you put in that table name. Yeah, there you go. So that's this is very short, but this is basically one way in which you would use a module, right? So passing the outputs between them, setting inputs, you know, we didn't really dive too far down into the module itself, but we did look a little bit

Segment 10 (45:00 - 50:00)

just to understand what it's trying to do and what defaults would you need, right? So overall I think it reduced a lot of our coding like in terms of like it reduced the number of lines of code at least. So we have maybe less Terraform configuration to review overall. You know, and so ideally you would want to be really opinionated with a module or you want to find a module who's a little bit more opinionated. Uh if you know what you're doing, maybe you want a more flexible module. But ideally a module has some opinion uh for you so that you don't have to worry about all of the complexities of stringing everything together. Yeah. Okay. So we're going to do one thing and that is change this uh source. Because I do want to show some of the pitfalls, right? Um so one thing that you might find is that you might decide that you're going to use a module that's not on the Terraform public registry. Module sources have a number of um places number of places that you can use including GitHub, including any kind of Git repository, things like that. So I'm going to post a Hold on. Okay. All right, here we go. So that's um sort of the configuration for modules. Uh we're going to use GitHub, right? Because I think there's a little bit of a difference in using GitHub or any Git server or Git repository. Uh one thing you're going to do — [clears throat] — is copy that GitHub um the GitHub URL for the Lambda uh module. So if you Or you could do Dynamo. Either one. Whichever one you decide. — Oh, oh I forgot I was I didn't move back to that one to see what its output was. — I don't mind. Okay, so you're going to copy this. You can do the code the drop-down code HTBS. So it doesn't need to be the Git. Or actually Git. Well, GitHub could do both. So GitHub has both opportunities. You could do the Git um or you could just use the URL. So either one will work. Um if you're doing it just a Git repository, you would have to do the dot Git with the HTBS Git URL. In the case of GitHub, you can just use the URL which is github. com/whatever without doing the dot Git part. So you could do organization module folder. Um either one works, right? Yeah. Uh we just uh yeah, do it on main and then I'll show the kind of the — Yeah, yeah. I was going to show yeah, looking at the tags. Yeah. Okay, so you could do it with dot Git. With GitHub, you can just do github. com/terraform-aws-modules/terraform-aws-lambda. Right? You don't need the HTBS if it is GitHub. If you're using a Git repository, then you would need the whole thing. But in the case of GitHub, you don't even need the dot Git the file suffix at the end. Yeah. So that's all you need for GitHub. Um one important thing is that there's no version. So when you do something over Git, it has no version. Yeah. So the way you would version it is by a reference, right? So you could do question mark ref equals. Yeah, on the — Yeah, on the end. Question mark ref equals and this is where I highly recommend you put the tag or you put some you know, you put whatever reference. It could be branched. It could be whatever you decide. Um but in this case it would be V870. And this allows you to pin the version, right? So then you don't have to mess with it. Um and if you do have some modules have let's say sub modules or like folders in the modules too, in which case you would do at the end of this you would have to put the exact repository. So it'd be like slash path slash whatever it is, you know. Uh That's if you publish like all of your modules to like a single repo and you use like folders for each module. — Right. If you did a mono repo, basically. repo and you had sub folder sub directories and you needed to go and navigate through it, then you know, you could do like slash whatever it is, right? At the end of it. But I don't think we need to do that here. Can you also do Can you specify by like so I can do Yes, you can do it by commit I believe as well. Cool. Yeah, so it is a very I mean overall, right? It's pretty helpful. If you Ideally, if you do apply, it shouldn't change anything because it's pinned to the same version. Right. The only difference is that the module source changed, but when you cloned it down, for the most part, it was like about the same. So, you know, not you know, it nothing really changes. The resource themselves shouldn't change. The logic didn't change, so the resource didn't change. Um so, you could

Segment 11 (50:00 - 55:00)

like let's say if you decide you were like testing around a module or something, it was on a GitHub repository or local, and then you do end up migrating it to a public registry module, then, you know, and they're the same thing, then it shouldn't change any under resource. That is module. We are coming up at the top of the hour. We're good on time. Okay, everyone. Um all right. So, this is how I would use modules. Now, let's look at the others in this area. Creating module. This is difficult for a lot of us. — Your Wi-Fi's cutting out, Rose Berry. Why does it always do this time of Okay, we're going to camera off again. It always does at this time of day. I don't know why. I think the All right. Uh the rest of your town just woke up and started working. I know what it must be. I This is a mystery to me. I don't figure it out. Anyway, okay, so what we're going to do is we're going to write modules now. Uh writing modules is a little bit of a different situation in that um you do have to have some discipline around it. I don't think we ever again, this is one of those situations is that in that over the years, I don't think we ever established any explicit guidelines, but as a community we came towards some specific guidelines for ourselves. Um and as a result, you know, there are some things that are actually quite standard. Uh if in the link that I put in there, it's the overview for developing modules, but there's actually a standard module structure link as well. So, I'll paste that so folks have it. Uh but the standard module structure is a sort of the suggested or highly recommended approach. There are some things that are absolutely recommended in order for you to register to the Terraform public registry. So, for example, it must follow the form Terraform-provider name-name of module, right? So, it should provide it should follow that form. Um and so, you know, here we are. There's a lovely list of things that we recommend you put. Um So, the structure itself is mostly the same. You have main, variables, outputs. Um and then the examples directory is sort of a subdirectory that you would want to create. They're also nested modules you know, examples for nested modules, things like that, right? All right. So, for the most part, this is pretty decent guidance, but there's also more information on the sidebar to talk about providers within modules, how to use it, version constraints, all sorts of things. Best practices for composing modules. There's even like composition and all sorts of things and very intriguing um discu- discussion of that. Uh there's even hilariously you know, discussion on dependency inversion and things that we should consider in order to decouple. Oh, we're getting back to that gang of four book again. I know. — dependency injection. I know. I think I mean, this is like the one So, dependency injection is inversion of control and dependency inversion, right? So, uh you know, I don't know. It's dependency injection is the both is both. But, anyway, let's go back to this. So, you know, there are a lot of suggestions. These are just documents for you to follow. It's up to you if you want to follow it or not. That's fine. Um a lot of these things are generally best practices that I've learned over many years of producing modules that a lot of people use. So, we'll Yeah, let's let's just leave it at that. Okay, so let's write our own module. The question is what module shall we write? What would you like to write? — We could do a simple one like we could go back to EC2 again if you want. Uh yeah, I think like there's like I don't there's like a GitHub Terraform provider and we could create a module that like creates a registry repository, but all like has I was getting a little too meta and I like it has the structure already set as a repository, but that's I don't want to do that. What we could do is we could do these two modules and squish them into one module. I mean, they're technically nested modules. So, now you could do two modules and squish them into one module. Yeah, we Yeah, that works. Yeah, we'll take like the the thing we just built and make that a module. Yeah, yeah, exactly. Yeah, we could do that. Um you know, I think it most of the time you would use if you use resources, for example, too, like we could throw in a resource. It would be fine. It's not that big of a deal. Um but we'll take what we already have, which is those two modules, and we'll

Segment 12 (55:00 - 60:00)

just squish it into one module. So, the terminology is uh this is what we're creating right now is a root module. So, this is what they This is what I would say is the main. This is what is like the entry point. So, we are creating a root module. The root module has roughly three Terraform files, main, variables, and outputs. And so, main, I'm going to turn the camera back on. Main describes any resource or any child modules you want to call. So, for example, we're going to create two child modules, one for Lambda, one for DynamoDB. Great. Now, if you had a lot of resources in your module, there you might not have You might break it up into different ones, right? But, the important thing to know about main is actually you do need it the Terraform block. It is highly recommended. So, we're going to start with the Terraform block. And we're going to put required providers in. Okay, and then we're going to do AWS equals Yeah. Equals squiggly squiggly and then source is HashiCorp/AWS. And then version equals So, the question here is what do I put in for constraints for a module? Um what I recommend is to put in the exact version constraint of greater than or equal to the version you've tested with, right? So, that's the important thing. Um we are on 6. 40. Yeah, 6. 40. So, 6. 40, right? Um there are reasons where you would not necessarily put it on the latest you've tested on at the time of writing this module, right? Maybe you want to do an upper constraint that it should be less than seven, right? Something like that as well, just in case there's some backwards compatible there's not a there's a lack of backwards compatibility from a provider perspective um when you get up to sort of the next major version of the AWS provider. There are reasons maybe you do want the upper constraint. But, for the most part, you could probably get away with just doing their greater than or equal to 6. 40 or like 6. whatever current version you've tested with at the time of writing the module or time of refactoring the module. So, that's really all you're going to need for the most part um in the main. tf uh and then you'll add your resources or child modules that you're going to reference. So, we're going to reference the DynamoDB um table and the uh Lambda function. We just copy and paste it from the thing. — Yeah, copy paste it. Yeah. And uh So, I noticed the structure doesn't tell us like if there's like other called ancillary resources or assets um like where do those go? Do they go like in the root or is there like a Yeah, so if let's say you wanted to add the API Gateway, but you're not using a child module for the API Gateway, you would add it in the main. tf. Personally, I have a general rule that if it's like if there are groupings of resources and there's like two to three different resources that belong in certain like one unit or one group um I put them in a separate file because, you know, when you start to like parse through like I would say more than 300 lines of Terraform in a file, that's when things start to get a little bit more challenging to search through. So, I tend to split resources across multiple files, you know, if there's like more than two of them that belong together. They're not modules, but they're sort of resources that logically belong together. So, in this case, we're putting all the stuff together in one place, but, you know, it's kind of And I think that is actually we have to change the source the way the source calls it. One second. Mhm. Yeah. And how do [clears throat] we What do we change this to of us when we use — So that one's fine, but the lambda one is Terraform AWS modules, I think lambda or something. — Lambda Oh, that's what you mean. Oh, okay. Lambda/AWS or something. I think that's what it is. Let me do a little check.

Segment 13 (60:00 - 65:00)

I think it's lambda. Yeah. — Yeah, lambda/AWS. Yeah. So, this is um, you know, for the most part, this is how you would declare a set of child modules in a root module. Um, we could create a resource, too. I don't know if you want to add the API Gateway in here. You know, I don't know if there's something else we have to deploy as part of the API Gateway. I'm not sure. Uh, I think Let me check. I would assume that the um the module has a uh I don't want to pick — API Gateway deployment. No, that's uh that's only — REST API. Yeah, it's the REST one. I was trying to figure out why is this I don't want the I want the one from I think you just want the resource, though, cuz if you wanted to mix and match, right? Or you could again do something like an EC2 instance or something is fine, too. Whatever you feel like. Is there a way to Hm? Uh, I was hoping there'd be a way to filter by like this group because I want the non-V2 version of this. — Oh, uh do partner like partner. Tier partner. Oh, no, never And then um maybe not. Hey. I mean, you just got to search. Oh, there uh no. Are you sure there's one that's not a V2? Yeah, cuz V2 is like the um uh the HTTP WebSocket and I was looking for the WebSocket. Here's what I was looking for. I want that. Go this way. I don't think there is one. There aren't there — It looks like it's not in existence. That is what Okay. I'm going to — I think maybe just use the resource. Don't Yeah, we don't have to make it complete, but just using the resource is probably fine. Now I'm angry. Why isn't there one? That makes no sense. I don't know. What's the difference between the two? Uh so, AWS made um their original API Gateway, which just supported like REST, and that one was like the V1. And then they later created WebSockets uh when WebSockets were all the rage, and they made that as like V2 um and then later added HTTP, which is supposed to was supposed to be a much faster and cheaper version of REST, but then they stopped adding features to it and they wanted people to go back to using the REST one. Uh I am uh Okay. — I'm very surprised that there is no Okay. Yeah. Well, I dropped the link just to the REST API Gateway resource. So, it's not the module, but it's the resource. It's in uh our studio chat. Oh, studio chat. Yeah, it's in studio chat. Might be easier for you to reference it there. Yeah, sorry. Yeah. So, that's just for the We can just use the resource. We don't have to do anything else. We can just use the resource. Uh okay. This is uh Oh, I do not like this. Uh is there See if this is a open API parameter point. So, see if this is the um integration with — a name example, and that's it. There's a um integration with API Gateways REST APIs integration with lambda that's like super simple that cuz it like um shortcuts a bunch of stuff. Let's see if it uh — Oh, there you are. Execution ARN. Source uh yeah. Um Is there You know what? Ask Bob. — Uh — Why are we doing that right now? Okay, I Let me uh Let me stop sharing my screen real quick cuz I have to like sign in with Bob. — Oh, okay. Let me pull Hold on. Hold on. Let me Give me a minute. I need to find my mouse. Okay, I removed you. Uh okay. So, you know when we said we were going to be judicious with our use, this is one of those times in which we're just going to expedite this process because we've been through this. We've already written a bunch of Terraform in the past like four streams. So, we're going to go and uh use a helping hand so we don't have to look through like a million documents and waste our time right now. Um as much as we want to show you us struggling through this, which we are at this rate, uh you know

Segment 14 (65:00 - 70:00)

we've uh we've we're trying to get to the fast to the more effective part or the faster part, which is not the faster part, the more uh valuable part of this, which is like changing the module attributes and things like that uh as you write it. So, if we're spending more time trying to find the resource and the right documentation for putting this together, uh we might as well just expedite this process a little bit. So, we're going to ask for help. Yes. I'm dealing with like internal IBM stuff right now. I'm trying to Oh, sign in. Okay. Yeah, trying to sign in. Uh yes. Okay. Done. Signed in. — Okay. So, we're going to ask Bob. If you could full screen, at least then we can see all the text. There we go. Okay. Uh we, you know, we're going to Yeah, that API Gateway. Are you connected to the MCP server? Uh no. — It's okay. It should be fine. Yeah. Uh Te function Yeah. Uh Bob can't handle uh typo we have here problems. Yeah, it's fine. The function You could tell it to uh generate the code uh under 05B module or something, but Oh, yeah, I knew. — Never mind, then. Uh Oh, it's actually Oh, so polite. So, for those who are not keeping track of what's going on, it's saying, "Do you want an explanation only, or should I modify it? " And uh Richard is saying, "Please modify it. " So. All right. We'll see how it goes. It's not It's actually pretty good, and especially if you connect it to the MC Terraform MCP server, there's a Terraform MCP server available, so it will actually read all the module details and things like that and provide our details for you. Oh, I might actually be connected to that. I might still be connected from the uh dev day. Oh, yeah. Uh what's going on? Let's see. What did it will pop up with that. It didn't finish yet. Still working on it. Still working. Uh Oh, now it didn't tell us what it added, but All right, well, it added a lot of resources. Which is simple plan. All right, so this is the lambda resource. Um Okay. So, then — I use Oh, I think this is where like I'm always For me, this is like my rule of thumb about like how good these modules are is where the term resource is overloaded between there's Terraform resources and then the R in a REST is Oh, actually, it's representation. Never mind. But like API Gateways REST API has what it calls resources. So, there's two different things that are both called resources that are completely wildly different concepts, and a good LLM coding agent will keep those separate, and a bad one will not. Um and it looks like this little Yeah, lambda integration. Yeah, AWS proxy. Yeah, this should work. Should work? Famous last words. Yeah, it's creating deployment and console lambda integration. Yeah. Yeah, yolo. Well, there you go. I mean, some things are hardcoded. We'll fix that later. Yeah, okay. Uh I so, because this is like a module, can I just do a Terraform deploy? Or Terraform apply, I mean. Yeah, no, you cannot because you it's a module. I mean, there's a couple ways that you could do this, though. So, this is where we're going to talk about like what you want to do, right? Um so, for me, when I iterate on this, I A couple people like to try to do it in the module itself, right? So, you could do a Terraform format, Terraform validate, right? So, Terraform format, Terraform validate at least. We know we hardcoded everything, so uh we'd have to The thing about the init, you have to init, which is, you know, a whole thing. Okay. You'll notice one thing about modules is that they'll also to the lock file. Um I don't as I recall and I'll probably someone will correct me on this. Uh, you don't need to commit the lock file for a module. It'll create a lock file. You don't need to commit the lock file for the module. Um, you know, it might tell you like it might have to you information about what someone tested with but really what you should be doing is that if you're offering a module to someone else, you're not going to lock those dependencies, lock the versioning, right? Instead that should be something that's constrained within the module itself. So — How did that work with like on the first one I made where it was just two

Segment 15 (70:00 - 75:00)

modules? Mhm. Um, it Uh, when I did like an the init it went really quick cuz it like it looked like it didn't pull in the AWS provider. Mhm. Uh, how does it do that without the provider? Or does it just do it behind the scenes I didn't notice? So it did it behind the scenes for the first time. The first time around because you're using a root configuration, then it's pulling it I think you already did an init. So you did the init and then again with the module. Uh, and so it already pulls the provider and the first time you pulled the module, the first module which is DynamoDB. This is the second this is Now that you've done both child modules and the resource, it might take a little bit longer. So the providers are already there. Yeah, okay. Got it. Yeah, so it might take a little bit longer. Um, okay. So the next thing that we're going to do is test it, right? So some folks do test it in the module itself. Um, you've hardcoded a lot of things so it you know it as a result you could test it locally. But we'll do it I would say the ideal way just because most of the time when you're writing a module you'll be passing variables. And so there's no guarantee that you'll have defaults for these variables. Um, so what you would do is you would create a root Terraform configuration main. tf referencing your local module. So this is where we're going to go next. Um, Richard I guess you can move all of these files into uh, you could say a module under 05B module you could say like a module subdirectory or something and then move all of this in there. That's probably the best way to do this. So we can get So we can do that. Yeah. Modules You can do module I don't modules and then you could do technically you would do another subdirectory naming the module saying like lambda I don't know what you want to name it. Modules. Yeah. So your nested module I don't know. Okay. Yes, so while those files get moved, uh, I will address some things in chat. The first is um, please use dark mode. We are not going to use dark mode. We've had a lot of feedback from folks who cannot see in dark mode. So that's why we are in light mode and high contrast. Um as much as we don't enjoy it uh, for the sake of recording and for other folks who have trouble seeing um, we don't use dark mode better for worse. Um, but like I said we do like using dark mode when we're not developing on the stream. — Uh, if you could move source in there too because that's part of the directory. Oh, yeah, yeah. But yeah, I usually use dark mode in my development. Um, so I change like when I go on stream I'll change to light mode and then I go off stream and then I'm back in dark mode again. — Yeah, after the stream I turn the lights out here after I close my eyes for like 10 minutes because it's just so bright for 2 hours. Yeah, this is like where we're getting like this is where I have to wear sunscreen cuz we're in light mode. Um, yeah, that's how it goes. Uh, and then there's some folks are saying like okay, what about replacement Terraform replacement? Okay. Um, I believe they're one to one for the most part so you know, you can choose which one you want to use at the end of the day. And I believe their providers themselves will also be pretty much the same. Writers and for most of the modules as well will probably be the same. So you could probably use most things the same way. No. Somebody said to use Vim. Somebody use Vim. — Yeah, I you know, we used to use Vim. Now we use an IDE so uh, makes it a little bit easier for folks to see too. You did promise hot takes. I Well, I used to have to do Terraform development in Vim before there were all these plugins and then I got I got convinced, you know, it was just so much easier. Like I had a lot of Vim plugins don't get me wrong but like the ecosystem around it was just not very great unless I wrote it myself so I just I was like you know what? I'm just going to go to an IDE with a language server. All right. Uh, so now we've got modules and we have nested A and so we're going to create a root configuration. So under 05B module we'll create a main. tf. Okay. Uh, yeah, do the Terraform thing again. Now this is going to be a soft constraint. Okay, and then we don't really care about the greater than or equal to. You could just do squiggle the yeah, the tilde. Yeah, so at this point you know, we're just going to do a soft constraint. So basically if you're a root configuration and you have which we saw before, right?

Segment 16 (75:00 - 80:00)

When you try to use an older version of the provider and then the module itself was not tested against the older version it's not backwards compatible with the older version. So it came up with an error. So similar thing we just want to make sure our soft constraint is about equal to the um, the constraint that's set in the module. And then if you hit enter we're going to reference the module now. And so now you can call it nested A cuz that's what we're calling it. Nested A. And then this is where you're going to put the source. — This could be anything, right? Like this could be like It's an identifier. You could say Richard's first module. I don't know if this is the first module you've written. Is this It is the first module I I've constructed myself. I've like copy pasted whole modules for like demo stuff but this is the first like Richard original. Okay, so Richard and Bob wrote Richard That's true. I don't know. You can call it whatever. I So the source is a directory, right? So dot module/nested A. Uh, the downside by the way if anybody's doing local modules and always referencing these local modules is that there's not great versioning. So you don't have versioning so you pretty much just go off latest or whatever's in that current directory. And then the version yeah, nothing. Yeah, no version. And then if we had inputs we would put inputs but we don't have any inputs. So let's just hope it runs and then we'll add the variables and the outputs and just for the sake of example. There you go. So you'll notice something kind of entertaining about this if you look at the dot Terraform uh, directory you'll notice there's a bunch of like child modules that were all these are previous but we should probably do Terraform init uh, init upgrade. That would probably be the best thing. Terraform init upgrade so it clean it all up. There you go. So hopefully that cleans it up. I think. Yeah. There you go. Well, it didn't. That's fine. Uh, but it does reference that this is the module and then Yeah. So that should Yeah, there you go. So it should have the child module name and then the Sorry, the name of the module and then the child module that it's referencing. So DynamoDB and lambda function. But there is not one for the API gateway because we wrote the API gateway ourselves, right? And then uh, do a apply. It can apply. Yeah. No, one second. I want to Uh, we needed to hardcode the name for the lambda function. Yeah. And I think that's going to fail so I'm just going to destroy. Oh, because we created it before. Okay. Right. Fair enough. Yeah, I try to remember that the DynamoDB table we let auto name which Oh, no. It requires a table name. Yes, that would fail too. Yeah, so we should probably just destroy everything. Yeah. Recreate it. Oh, man. IAM roles. These roles take forever. Okay. Yeah. Actually it didn't take as long as I thought it would take. But No. And then uh, apply. Let's see what happens. And da da. Okay, so the archive Ah, so path to relative our path to relative where the Terraform plan is being run. Okay, so important thing is that when you have a path in defined in a module, your root configuration has to know where it's relative to the module not relative to itself, right? So if you go over to the lambda the source. source/ whatever. Yeah, source/Richard function. Um, when you're doing it relative to the module, the module is like, "Okay, things are fine. I understand. " If we're doing it relative to the root configuration, which is a directory up, the directory up is saying, "Okay, I don't know where source Richard function is. " So, the way you would approach this is to do a um you would interpolate on a preset uh attribute called path module, right? And so, what this means is it will tell your root configuration, look for the module path /richard Richard's function. So. And this will tell it the specific I would say a more relative path than it would be uh absolute not absolute. It'll be relative

Segment 17 (80:00 - 85:00)

to the module and not relative to the root configuration. Yeah. So, a little confusing, but just keep that in mind. As you're developing modules, you might have to use this path. module. Uh the best approach to this, in my opinion, is that if you are trying if you are really opinionated about the lambda function you were deploying, then yes, you would bundle the lambda function with the modules maybe. But in all likelihood, you'd probably pull down the lambda function from somewhere else and then it as a variable passed to the module, put in an absolute path to where you've pulled down the lambda function. But yeah, that's I guess a matter of opinion and a matter of your own choice. Okay. So, we should have an API gateway. I don't know if it actually work. Probably doesn't, but Well, it has something. I don't know. Oh, off. That's okay. Uh I don't know that should be okay. We're Oh, it's just above was that 100% accurate. Mhm. This is why we probably should have verified it beforehand. Uh we the lambda function is not my lambda, right? Or the path. So, the lambda is not my lambda. Well, so what it did is it hard coded that is like the path to like um probably easier to see it in here. So, it said yeah, so the resources so it made this thing and then uh get my lambda one and I think it's the name of the function. But um there should be an integration. Lambda proxy. Yeah, and then it yeah, links to this which does exist. Mhm. Oh, I know. Um I can fix this. So, it's working. It did invoke this. If we look at like the monitoring, we'll see like it was invoked a second ago. Um Oh, there you go. It aired, but it did get invoked. There's an error in the gate. Um It's because when you do this like direct invocation like this, it's expecting a response to um it has to be uh um uh status Oh, you have to do that. Okay. Uh 200 and then uh body is uh well, actually I'll just return the Yeah, that works, too. Yeah. Show. Oh, oh. — A comment. We have a comment from Anton. Good job with lambda. If you want to get scared and get laugh in front of rest API gateway. There's a bunch of that. — Oh, Anton's in the chat. I can ask him now. Um Anton, where is the like rest API gateways? I see the API V2 um and I couldn't find ask uh all the people who are watching. I spent like 10 minutes looking for uh the the module for like the non HTTP/websocket uh API gateways. That putting that out there, you know. It's I'm throwing it out there. I don't know yeah, if you want to — Putting that out there. On our next episode, I'll do a follow-up of what I found out. What I assume is that it's similar to I think like um cloud formation AWS API gateway. I think they use like the same resources. Oh, yeah. Are they Oh, no, they separate them out. I feel like this is the same one, isn't it? Oh, no, no. Yeah, so they separate them out. Maybe I'm just expecting it to like reflect that. It's entirely possible that Anton put them all into one big one. Don't know. Okay. All right. Well, moving on. So, we have hard coded for better for worse. We've hard coded a lot of things into our module. But at least now we have tested the module and we've said well, somewhat tested. We've run it end to end and we say, "Okay, we can — on my machine. That's all the testing I know. — on your machine. But the reality is if you're going to distribute this to me who doesn't usually always create DynamoDB tables and lambdas and API gateways, there are some things that I would personally want to change, right? Uh so, we'll make some variables. So, let's go to nested A and then we'll go to the variables. tf for nested A. Oh, there you go. You got an answer. Yes. Uh

Segment 18 (85:00 - 90:00)

Uh understandable. I mean, that's uh a common I want to say common. That's as a friend you see in open source community and stuff like unless there's a very compelling reason to make something or a sponsor willing to pay for it. Things don't get made. It's just capitalism, I guess. Is the rest API gateway that much more complicated for you like or Uh yes, it is uh Okay. So, then why do you prefer using it? It's what I know. Uh it's like Okay. There's features in there that I know will be there that what I don't want to end up in a situations where I start on like HTTP um on the HTTP version, realize, "Oh, I need to do this thing. " And then I have to like completely rewrite it in like essentially a whole new module for new resources for like the non-V2 ones. So, I just start with this one because it is a super set of like the HTTP one. So, I know if I ever need a feature, I'll have it. Ah, got it. Okay. Cool. Good to know. For my own edification. Okay. So, let's add some variables. Uh what I can you open if you could pull up in this full screen cuz I think it's better we just put these two side by side cuz the nested the main. tf and variables side by side so at least we can see both. Uh which ones we're going to add uh Okay, so we're going to want Where is it? In the deployment stage. So, you're saying Stage name? Not the stage. There's like a URL. There's the equivalent to uh you know, in stages uh the invoke URL. Oh, okay. Like this is like the thing you want out of making an API gateway. So, that's an output. So, let's since that we're going to start there, let's make an the module output uh for the invoke URL. So, in outputs. tf, you can do output Oh, you're talking about Oh, for Oh, I'm sorry. I was I completely misunderstood that. Yes, stage name we would want as a variable. Well, let's just do outputs cuz we're already here. Uh Yeah, there we go. Okay, so output you could say uh gateway invoke URL. I When it comes to module outputs, I try to be descriptive because you could have any number of URLs that you want to output and saying URL is not usually a sufficient descriptor of which URL. So, uh you know, I think that anything if you know about clean code software clean code uh or writing clean code for software, similar approach applies. It the intent should be very clear. Um so, yeah. If you try to be uh very clear with which invoke URL, it would be very helpful. Um I think it's AWS API gateway rest API or whatever. Which one? I think it would be rest API that has the invoke URL, right? Or is it gateway stage? — There's no I think it's the deployment. Which one has the invoke? Oh. Fun fact, none of them do. Why? It's because uh I'll show you a cloud formation example to explain AWS cloud formation API gateway lambda. Where is this? It's none of them? Yeah, it's like it has to be reconstructed from like the pattern that this follows of like it's like the API ID execute API the region the stage uh that was a ter I There should be a data source but hold on. I'm going to look at this a data source for this cuz there's got to be a data source for this, right? Oh, yeah. Mhm. Maybe not, but Mhm. Nope, there's just stuff for gateway V2. The answer doesn't live in a single AWS resource. You have to like construct it from outputs from multiple of those like 15 resources he created. Great. That's great. All right. I guess they don't have it. So, we're just going to have to reconstruct it. Oh. Oh, wait. Here we go. Someone did it. It's on the uh stage. It's on stage. Okay. There we go. So, we need to output it from stage. Okay, we'll say uh Terraform one confirmation zero. Stage. Uh dev dot Yeah. Yeah. Good. Okay. So, are there any other outputs that you would like to include in this module? Or is this just the most important one? Yeah, I think that's most important one. Cool. Uh and then variables. So, this one I

Segment 19 (90:00 - 95:00)

guess we'll put stage as a variable. Uh and stage name. Uh value is No, wait. It's not value. So, remember uh variable is type. So, we'll start with type. — [clears throat] — Is string. And then description. I had I would say four modules. Please, please put your descriptions so people know exactly what you're passing in. Um Yeah. Be descriptive. Sometimes it's even helpful to put uh documentation link in there if you really want to. But, um to deploy the API Gateway. You could just do It's okay. Yeah, I don't want to end a sentence on a preposition, so I just left it trailing off. — Yeah. And then uh deep I don't know. Do you want to put a default? Default could be dev. Yeah, dev. Yeah. Uh it's not sensitive, so we don't have to do anything, right? So, just leave it as is. All right. And then var. stage name. Now, some people are meticulous, in which you will validate and you will uh for you will validate to make sure that this is correct after you make the changes, right? So, part of refactoring 101, um the refac approach to refactoring Terraform is going to be very similar to refactoring software in that you just test to make sure that these things, you know, don't change after you change something, right? Um just good discipline on that front. The other thing, if you scroll up, let's see. What else What else What else? Uh oh, my path part. The path part. Oh, yeah, that's a good one. Yeah. Uh Path part. Type string. Description. Is path part. Yeah, path part. Sure. Uh I guess now. Default is my lambda one. Uh I think default should just be nothing. Oh, really? Okay. That's possible. — yeah, because it's just like um I think it What's that? Oh, cuz it's the root. Well, yeah, you could just have it as like the root. — Okay. All right. So, let's put that in there, I guess. Where did I Yeah, so it should be var. path part. Oh, wait a minute. Actually, I'm going to make a change. This is where it gets complicated. So, you I think it Oh, so the parent So, it's putting this path thing on the like — And the root. Yeah. — the root I I think this is where this is why we cast, right? — var. path part. Yeah, I would just say var. path part. We could always change it later and then And I don't Yeah, I we'll see. Could it just be an empty string? Is that what it is? I don't know. As far as I can There's like an One of these will work, the other one won't work. It's like Uh path part only allowed variable names. Um Oh, yeah, that's like a common thing it does with this specific lambda integration is that they do like um And then they set its variable name of like uh Oh. path Oh. — Uh and then when the lambda function is invoked in the event, there'll be like a path variable that's set equal to like whatever the person who invoked this put there. Um uh let's see. Okay. So, if I uh yes There [snorts] you go. So, if I were to like invoke this with um Mhm. like And then I know it's hard to see, but I can't zoom in on this part, but like Mhm. Bob here, then like there'd be path equals Bob. So, you it gives you some flexibility. — Uh okay. Yeah. Okay. Got it. Oh, yeah. Oh, actually yeah, so this should work. Uh I broke something. It's okay. That's part of uh uh uh — Oh, I think Okay, what? Uh stages This is how you update the dev. Yeah, that's — Yeah. Okay. So, right. — Oh, wait. Oh, no, wait. Okay. So, what happened was This is why I love lambda or API Gateway.

Segment 20 (95:00 - 100:00)

Um I can tell this is uh but this ties back to like a previous thing we did where um what we need is a deployment. And then we need a life cycle to like We need this to always happen. Yeah. Oh, there you go. Yeah. So, it's um What was it? Uh why is my brain Yeah, so recapping. We learned I want to say in two or three. I think it was three. Two or three. In episode two or three, um about action trigger uh not action triggers. Uh what is it? Triggers? Something like that. Hold on. Replace triggered by. Um by. Um — [clears throat] — So, we had life cycle meta arguments no equals. So, no equals. It was just life cycle. I guess. Uh we learned about life cycle meta arguments where there are certain arguments that you can add in order to orchestrate or sort of re-automate certain resources. So, we have uh replace triggered by, which we talked about before. Uh and it will replace the instance entirely if one of those if a dependency changes, for example. So, we could do replace — uh — but this is one of like the common idiom is like they do I forget the syntax, but it's like basically like time. Now. Like something that always changes every So, every time you do this, it will do a new deployment because the dependencies aren't there. I'm trying to remember what that — Oh. Uh there's a Terraform data resource. You could do a Terraform data. Uh Yeah. Yeah, I think they usually do um a hash of the lambda function in case you change it or a hash of the bodies. Typically, what people do is like they'll instead of specifying these as like separate resources, um Okay. uh these methods, they'll specify an open API specification, and then you can just hand that directly to API Gateway, and they'll do a hash of that. So, it's like if this changes, you have to do another uh — Yeah. Okay. I thought I saw one with like uh one of those like some like time function. And I'm hoping that the AI overview helps me. Uh I mean There's a time provider. Do you want the time provider? Yeah, I hold it up. Okay. So, it's uh time stat You want the static? Right? Terraform Yep. Uh yes. Yeah, yeah. Yeah, time static. — [cough and clears throat] — Yep. The triggers I don't Triggers are optional, so you don't need to use it. You could just It'll re-trigger every time. Put it back to my modules. Yeah, triggers is optional. Uh so, what we're doing is we're using the time provider, the Terraform time provider, to basically give us the current time stamp. And so, the resource will change this time static resource will change every time the time stamp comes out current or something. I don't know. That's fine. Uh and so then what Richard's going to do is he's going to pass this to replace every time we do a new run. So, anytime run, the time stamp. Uh time stamp. It would be time stamp. RFC 3339. C3339. Yeah, there you go. dot net — And then — Okay. Do I have to do another init since I brought in a new resource? Or — Yes. You do need to init. Yeah, you need to init cuz it's a time provider. I mean I don't think that changes that often, so should be fine. Apply. Okay, one that what's going That's not right. — Yeah. That's fine. But oh. It didn't Well, probably cuz it didn't exist before, right? So, try it again. No.

Segment 21 (100:00 - 105:00)

No. Hold on. You know, there's a timestamp function. I think the timestamp function is probably better. Yeah. Actually, remove this resource and do the timestamp function. Yeah, timestamp function. So, instead you place trigger by timestamp. And then — By flag. Yeah, let's just yeah, timestamp that. That's it. Mhm. I don't know if this will work. Oh, no. It has to be a resource. Never mind then. I don't get this. Uh I mean, you could also do time offset, but I don't know not it won't be time offset. Is this one thing we ask Bob again? Technically, oh oh, okay, got it. Terraform data. That was what we're missing on the timestamp. So, it's resource terraform underscore data. So, there is a resource called terraform data. So, it will just kind of generate some data. I'll put it in the chat so folks can see. I'll put it in LinkedIn, too, while you do the typing. Terraform data, and then you would say like timestamp, do input equals timestamp. Yeah, so you would do you would say you have to put an identifier. So, it'd be resource terraform data. Oh, and then timestamp — or current, you could say timestamp, right? Current. And that and then input equals timestamp function. I was like, I knew we were missing something. — [clears throat] — I think that will do it. Yay! There we go. Uh destroy current — Okay, terraform data is basically uh creating like to terraform effectively like some storing of terraform data right in state. And so, it will store the current timestamp. And so, because terraform data changes every time there's a timestamp there's a new timestamp every time you run it, thus now anytime you run, it will now — Okay. — You should go back to my lambda one for now. — Yeah. Yeah, okay. But there's another there's a bigger point to this where the path part is also the same as the lambda function name. So, my lambda one happens to be a lot in this configuration. So, I would say during our refactor we could call it like lambda name, and then we'll just pass it explicitly to lambda to path part, right? I know it's not perfect, but at least, you know, for our contrived example. Okay. Um All right. Take this out. We'll fix this later. Okay, and then for path part, we're going to have this just be — Lambda name. Yeah, just call lambda name, so it's my lambda one or whatever it's called. Or you could say Richard's lambda cuz I guess it's new. You technically could say Richard function. Oh, you So, we're going to Oh, we're going to pass like the the actual — Yeah, you see like you see the name 49? Yeah, you're going to interpolate it. There's a lot of tags, and well, also we should fix the tags. Like there's a lot going on here that, you know, we could refactor. Oh, yeah. Okay. Yeah, so it's my lambda one, and then this will be this will be I would call every change path part to like function name or something, lambda function name, just to be clear. Yeah. And then the description also changes because that's how these things work. Uh name of the lambda function, and then I also, just for everybody else's reference whenever they use this module, I also say gets passed to path part for gateway, right? So, I'm just clear on the description. If it's not just the name of the lambda function, and I'm passing it to something else as well. It could be any number of things, but I if it's like maybe one or two things that are just important to know, I'll just make a note that gets passed to path part for API Gateway. Just so folks know like, oh, it is actually something outside of lambda function, right? From a usage perspective, it's helpful for someone to know.

Segment 22 (105:00 - 110:00)

No, you that's Python. You don't need the F in front of it. — Yeah, yeah. — Right after I did that, I was like, oh, no, it's uh A lot of Python going on here. I'm trying to remember if it's I think the slash is on the end. Uh what? You don't need a slash, I think. You don't need the slash at all. Yeah. Apparently, you could just do it just without any slashes. But There you go. Yeah. Okay. Well, without any slashes at all. There you go. Okay. — Uh yeah, just for cleaning it up, I would take away the string interpolation with the dollar sign, and yeah, so. Uh there's all a lot of my lambda ones as well. So, if you go through this, there's if you do a search, there's my lambda ones everywhere in this. Yeah. So, we could take the tags out because I think we will propagate some default tags, so I'll show that on the provider side. Might be a little bit easier. Uh and then Yeah. So, I would say like if it kind of depends on how you want to approach this. Um you could write a module with tags, right? With the tags, you explicitly pass them in. With the AWS provider, there is a default tags capability now, so you could specify them on your root configurations provider default tags. And it will propagate them to where it can. There are some exceptions. So, if you're doing something like an EKS cluster, some things just don't get tagged automatically or cascade, you know, the tags don't cascade, right? To EBS volumes, for example. So, it's not always the case in those default tags working all the time. So, you might find that it's easier in some modules to explicitly ask someone to define a set of tags and pass them in, or you know, you set the default tags somewhere. So, it sort of depends on your own approach for how you develop a module. Some things are maybe worth overriding, some things you want to include by default, right? Okay. Are there any other my lambdas in there or no? Uh no, there was none. Okay. All right. No, those other ones are just like in the strings for like the description Mhm. Yeah. Okay. So, I think that's pretty much the only two variables we need to put in. You can say Is there anything else? No, I'm trying to remember. This should be fine. All right, so CloudFormation templates don't let you have underbars in DynamoDB table or one of them like doesn't let you have underbars, and the other one hyphens. So, if you take the name of one and pass it to the name of another with like the appending, like sometimes that will fail, but I think we're good here. I think this lambda and API Gateway share the same restriction, so that should be fine. Okay. All right. Well, I think then we can I we'll just leave it here. I mean, if you have sensitive variables you want to pass to a module, too, just keep in mind there's the sensitive true, right? You want to redact them if you can. So, effectively the same principles apply from writing Terraform configuration to writing Terraform modules. The really big difference here is just to be more disciplined about output description, which we I don't think we put an output description, which you probably should anyway. I highly recommend you put an output description um because that can get generated into documentation. So, if you do onboard this into the Terraform registry, we're not going to show that today. That's a whole separate discussion on HTTP in general, but if you do add this to the public module registry, the documentation auto generates with the descriptions coming out from this, right? Uh okay. So, I think that's important I think we're pretty much good on this one. We developed a very basic module with two child modules and a resource or the API Gateway resources. So, that means that we could use this module some more. We could um Yeah, we could use this module. We could offer it to someone else to output it. In terms of what's the last step, um we're going to generate a readme. I think you should just always generate a readme for your modules because it describes the usage, you know, how someone's going to use it, right? Um there is a handy-dandy tool for you to do this. I guess the first you could ask Bob to do it. So, why not? I mean, we'll just ask Bob, see what it does. Um I don't think it's going to do anything good. Uh document a readme. [clears throat] — so many emojis in it. Yeah, for module/nested_a. Module. Yeah, we don't want it for the root module, but we want it for nested_a. Yeah. Uh there Alternatively, if you're not using a coding agent to do this for you, you could use something a tool called

Segment 23 (110:00 - 115:00)

terraform-docs. So, there is a tool called terraform-docs, and it is a command-line tool that you can use to generate documentation in a very clean way. Definitely check that out. That is what I typically use, although now we have coding agent, perhaps makes it a little easier. Um you can tell the coding agent to run it for it, right? Hopefully, since, you know, just very long descriptions and things like that, maybe it'll be fine. I don't know. We'll see how it goes. Uh your audio's cutting out. I heard let's see how it goes, but it was like trailing off there. — Oh, again. I think it's because running a million on my machine. Running like way too many streams. Okay, hold on. Let me close things. I ran a hardline. It's not bad. I mean, you know, it does the job, I guess. So, cool, I guess. Yeah, so it will tell you it has a Yeah, so you know, something it's not terrible. It does have some, you know, some uh it has the inputs and the outputs. So, that's the most important thing. If you wanted to create an example, right, you would copy that main. tf under modules nested_a, you would do nested_a's example/ and then you copy that main. tf in there. Um and so, that's technically the way you would actually test it. Um we moved it up to the top level, so anybody who's using this GitHub repository will be able to find like how we approached it, but ideally, Richard, if you create nested_a/examples subdirectory, Yeah, so a subdirectory that's examples, and then you can copy the main. tf that we're playing around with, and you can create you can say like basic example, right? Not the one from the the module, the one Yeah, new file main. tf. Or new folder basic. Yeah. So, it's kind of helpful. I, you know, I do whenever I do this in its own GitHub repository, I will tend to do this approach where I will say, "Okay, I'm going to use an examples directory and then reference the local module like that. " So, you would do dot slash, you know, you would go up a directory instead. Um — All right. Yeah, so you would do dot dot dot. Yeah. There you go. Oh, it's going from, yeah. So, then dot is basic, dot is example. Dot is Yeah, you just need to get to the nested_a. Yeah. And then I would copy terraform. tfstate into — Oh, wait. I'm sorry. I put this in the wrong spot. No, no, that's fine. No, you've got it in the right. It's right. So, so what happens is that most folks typic- typically do a remote like sort of a repository hosting the module, right? — But I think this I think I would take this out then, right? — Oh, yeah, you would just take that. Okay, yeah, I was confused. I was like, "Okay, cool, yeah. " Correct, yes. Uh and I would move the tfstate into it as well so cuz otherwise, you're going to leave things like hanging out, so. Yeah. And then I would say I would go back into the examples basic and reapply just to make sure you have everything. Yeah, so this is if you were just in a module directory, a module repository, and you just wanted to develop on the module itself, right, you would run this and you would put it under the examples directory. Huh. Directory could not evaluate some Hold on. One moment, please. I think we have we forgot to reference something somewhere. Uh might be just dot dot dot. You don't Oh, you don't need nested_a. Sorry. It's just dot dot slash. That's it. Dot slash dot slash. Right, cuz you don't need nested_a because I'm already in it. Yeah, we already moved up. Okay. There you go. All right. So, then we initialize, and theoretically, nothing should change cuz we moved the state file over, too. Oh. Terraform minute again. Okay. Yeah, so this is a very basic module. I would say there's a lot more complexities to developing modules that we didn't cover, right? There are things that maybe you won't consider doing like um you know, as part of like the module guide, you know, structuring a little bit more logic around whether or not values do get passed in, not get passed in. Sometimes people are really opinionated, they only want a certain subset of, let's say, Postgres engines

Segment 24 (115:00 - 118:00)

or, you know, only a certain subset of valid configurations get passed in. You could use variable validation blocks to double-check. Um these are things that we'll probably cover separately in a testing in a testing stream because those are all just testing related, in my opinion. Um but we at least got sort of the basics of developing a module, how you like sort of the workflow works, right? Um you typically create the module in a directory somewhere, and then you would create a basic Terraform configuration to test it out to test um some of the initial configuration. Again, there are more complexities to this. You might say like you have more examples with more complicated logic that has a lot of configuration, in which case you might have more examples. Um and there's even a lot of arguments around whether or not you should test it, how much you should test, right, or how much you don't test these things. Uh but ultimately, it's up to you to decide how you want to provide ample coverage for all of the conditional logic that you might put in a Terraform module cuz sometimes it can get really complicated like, do I create a role? Do I not create a role? If the role exists, pass it in, then, you know, there's a lot of logic you might want to test, but we're not going to cover uh cover that at least in this sort of initial module stream. All right. All right, coming up on time. I had to check the clock. Uh wrap up. Richard, what did we learn today? Uh I learned uh this Oh, sorry. I took you out. Uh yeah, let me uh stop sharing real quick. It's here somewhere. This is okay. Um uh this like being able to like develop them locally and keep them in like the roughly like that same directory. Like previously, when I had done I assume I could do something similar with like a provider, I had it in like a completely separate like I was basically uploading it to GitHub and then pulling it back down every time I was making a change to it. Uh that being able to test things locally during that iteration loop, I think would have been a huge accelerator for me at the time. So, I think that was the my biggest takeaway from today as well as the um with I directly specify a Git repo for the uh the module, being able to specify a specific tag or branch or uh commit. Mhm. Nice. Yeah, I think that this is very basic, right? So, anybody who's watching this is like Anybody who is really good at developing modules probably like, "This was very simple. " It is very simple. There's a lot of nuance to developing modules. We'll probably continue on with the separate stream. Um we're off for the next 2 weeks due to travel and various restrictions, but um we will be back in early May. Um I think we'll probably hold off on the module testing and more complicated module parts, although we'll re-plan. So, we might come back to modules and do more complicated, more complex um demonstration of how you would use modules and things like that and actually put it on the Terraform registry. Today, we didn't. We just did local development just to show you how to use modules and then how to um write a basic one so that you can start distributing it to anybody you need. With that, I'm going to close out this stream. Thank you so much, folks, for joining us today. Thanks for all of our awesome guests who came who joined here today. Um thank you for your input and advice. That was much appreciated. With that, uh we'll see you in early May. So, come join us then. Have a good one.

Другие видео автора — HashiCorp, an IBM Company

Ctrl+V

Экстракт Знаний в Telegram

Экстракты и дистилляты из лучших YouTube-каналов — сразу после публикации.

Подписаться

Дайджест Экстрактов

Лучшие методички за неделю — каждый понедельник