I love that. All right. So, how about now, audience? Can we hear you? Audience member, can you hear us now? Can anyone hear me out there? Now in radio land, now they can. Now we can. All right. Thank you. Awesome. So, in conclusion, that was Ansible Operators. Yeah, now that we're done, I appreciate you being here. Thank you very much. No, that was a mistake on my part. There was something I had to unmute that I didn't see. And I forgot to scroll down. My bad. Sorry. Still figuring this piece out. So hi, everyone. Welcome to our second stream ever of the Red Hat OpenShift team. Clearly. Which channel? Yes. Clearly. We do things live here. We're very happy that we have this outlet and we have the capability to, you know, learn in public. So we greatly appreciate that. Today, there'll be some learning in public for y'all, hopefully. Two of my friends here, Jason Dobies from our developer evangelist team, is here. And also my fellow Red Hatter and technical marketer teammate, Christian Hernandez is here. And today they will be talking about building Ansible Operators from scratch, which is something I am definitely familiar with and definitely love. So when they said, hey, we're going to do this on the air live real quick, I was like, yes, let's do it. We can do this as much as we want. Let's go. So without further ado, Jay, Christian, take it away. Christian, I'm going to let you start because we didn't really plan in the other way, some of us are here in the bus. Now, I'm seeing this actually, I've already seen a question about this CouchDB demo. I mean, we could get to at some point where we throw that up. That's a fairly easy thing to run. But let's start with what you had planned. Yeah, yeah. So, well, I mean, you know, what I had planned is we'll do it live, right? How about let's take kind of the things that I have a operations background and there's a lot of uncertainty from the operations folks, especially the ones I've talked to, you know, when we were able to go out, right, at Summit and at meetups of, like, what's like this whole Kubernetes cloud-native thing? How does it affect me? Right. And I think one of the cool things that we got is in terms of technology at Red Hat is the operator framework and how that plugs into cloud-native approaches and things like that. It just fits perfectly. And I think Ansible is just like a natural fit for operators, right? When I say operators for the off folks and how they can continue using whatever it is that they're using, but then plug that in a cloud-native way. So I just thought, hey, let's just build one from scratch. Let's just try to deploy something. And I know I got your help here, right? So you being from the Dev background could help me along the way. So cool. Cool. So what do we have for a sample application? What are we actually going to write an operator for? Yeah. So I have a few things, right? So I have a couple of apps. So I have just a standard welcome PHP application, right? So if, oops, I'm on the wrong window. Welcome PHP, right? So I have a welcome PHP app that is just basically a dumb splash page, right? Just to kind of test OpenShift, right? Any time I deploy OpenShift, I have a smoke test app, and this is the smoke test app when I deploy it. All right. Yeah. Yeah. Right. I come from a web background. So a PHP is always the easiest path to least resistance. And then I have something called PHP Priceless, which I think would be maybe even more interesting to set up because it has a database backend, right? So I have an application. I have a workflow, right, where I can deploy a backend database. I have front-end web. It's a simple CRUD application. This may be a little bit more complex, but actually maybe a little bit more fun to try to have Ansible deploy for us. I think so. I think we got to go at something at least like this because the single apps, the problem with, and I don't know how much your plan was to talk about what operators are. I'm going to circle back on some concepts. Yeah. Oh, no. I think that's where we should start first. But yeah. And the problem, this is probably a good context setting because the problem with understanding kind of where they're useful is any application that's going to really kind of flex them and show the coolness is, by definition, kind of a pain in the ass to describe. So the single hello world app ones don't really do justice because the entire time everyone's sitting there going, I can do this with a manifest. I've literally just did this with a manifest while you were talking. What are we doing here? I like this one. I like this one. I think the first thing we do is we submit a pull request to correct the spelling of price list in your read maybe. Yeah. Yeah. I actually just saw that as you. Because that's going to peg my OCD something fierce. Yeah. Yeah. Whoa. I just saw that. Okay. That'd be a good PR. All right. Cool. Okay. Yeah. Yeah. Let's actually let's talk about, let's talk about operators. What is an operator, right? Like where do we, how do we define that, right? What's an operator? So let's take a step back further than that. Let's go. Why are we talking about these? Because it's going to sound like airing dirty laundry, but at Red Hat we tend to. Yes. Let's do it. That's what this channel's for. And it's just air the dirty laundry. All right. Let's run with it. Internally, we tend to talk about them quite a bit and really, like they're this amazing answer to everything. And you know, they're a tool with a specific, very wide range, but at the end of the day, they have a purpose to trying to get it and they have problems that they're best suited for. So let's start with the why. And I had just seen something today, I can't pull up the slide itself because it has this nice confidential thing on it, which I don't think that's a really good start for the channel if 10 minutes in, I'm pulling up confidential Red Hat slides. But conceptually, what this slide was talking about was, there was two specific breakdowns I really liked in there. One was update versus upgrade, and then one was unmanaged versus managed services. So I'm already a little further in the weeds than I want to be though. So getting a simple application out, as I was just kind of half joking about with the Hello Worlds and our PHP webs and our Python webs and whatever the language people use. I think it really is funny though, it goes to show the person like, what is your sample app? What language do you use? Yeah, exactly. So Christian and I, let's just go back even further, we got three hours on this. Christian and I are on related teams in the Cloud Platforms business unit at Red Hat.  And that was much better definition and I could actually go someplace instead of being stuck in this room, but it still kind of applies.  So our teams tend to work together in a lot of ways and this is not the last time that we're going to have these crossovers. I know Josh on our end is on Wednesdays. Is it you again, Christian? On Wednesday? No. No. Okay. That's fine. Josh and Eric are doing their own thing on Wednesday. Eric, that's it. Okay. There we go. By the way, Eric's sample application is Ruby on Rails. So that tells you a lot about people, right? So I think it's a good indication of the person, right? Some people are Python people. I do PHP. I'm a web background and then all of a sudden Rails, I'm like, I haven't heard that. That's a, what was that mean? Like I haven't heard that name. Yeah. Oh God. This, all right. Let's see how many like up to Star Wars references we can play. Yeah, exactly. I haven't heard that name in quite some time. That's one. Start the ticker. I also like the fact that he's not on video and Chris Short jumps in with and just jumps in. He's like ominous voice. Yeah. He's like casually talking to me. He's like, Eric and Josh are going to meet up. Yeah. And Eric, what are we trying to say? I mean, seeing as we have, you know, the first three hours of you not being able to respond to us quite a bit. Yeah.  Sample applications. Okay. So those sample up. No, our teams. So, yes, Christian and I are on the separate teams. We haven't actually, this is kind of cool because this is our first real time presenting together and that whole PHP thing. It's kind of interesting to get to know the people and like we said about Eric, I tend to gravitate more toward the Python, although I will do Java if I have to.  We're all one big family now. Exactly. Yeah. Spectacular family. We actually got cobalt running on OpenShift last week or two weeks ago, which says all sorts of things about our good friends over at IBM, because he was so happy, like literal gray beard. It's amazing. He's so much. Yeah. I'd love to get him on this channel at some point because he's a blast. Okay. Going all the way back to operators circling back, we'll get there eventually. We'll get there eventually. Yes. This is why people like you really stream for three hours, I was like, don't underestimate my ability to go. Yeah. We can, we can chat. Yeah. Exactly. So, uh, sample applications are pretty simple to get out there. Um, you know, deploying these hello world applications, um, even in cobalt, uh, not that difficult to get out there. But what happens when you have interactions, what happens when you have something like this, uh, purse list until he renames it, um, as a database. Um, the other samples I have our front end, back end database types of things. Um, what happens when they get bigger than that? And the typical example is usually a database. Uh, and actually I'm, I'm curious about whoever asked about the couch base demo because, um, okay, uh, I just caught up on that. But, um, the couch base demo itself is actually pretty badass for this because it shows that, um, to get a couch base cluster out there looks like it's three pots. And then you want to scale it up to four and you would think, okay, I know how to scale things in open shift. I'm going to say replicas is for life goes on. And it's actually not that simple because all of the actual couch base magic happens in the rebalancing and their cluster logic and all of that good stuff. So we can't just tell coob. We can't just tell open shift. Give me another pot. Um, it's got to do something. And that is at the most fundamental level where operators come in the fact that you can't just use basic coob constructs like that to gain the specific application level knowledge. Yeah, the most, the most common use case that I like to like to do, uh, because I get asked a lot. Um, like, well, you know, how is this different than helm? And I'm like, you're, you're, you're asking whether or and it's, and it's, it's, it's, um, yes, and right. So it's, it's really, um, it's really more than just like you said, deploying an app. Uh, the example that I give is like, what if you have a schema change? How do you automate that? How do you automate? You have a schema change and you need to automate that distribution of, you know, that, that deployment of that application along with the database, along with the schema, along with all of that, there needs to be operational knowledge in that automation. So that's, that's, that's really, I guess the, the first and foremost, the example I like to give is like, what if you have just a database schema change? How do you, how do you roll that out? Using constructs, right? I'm glad you mentioned helm too. Cause that was the context of the slide that I'm hinting at, but not showing is that update versus upgrade. Like I can use a helm chart to update, um, the image that the cluster is running. Sure. Um, but that's not an upgrade operation. That's not doing the schema updates. Like you just mentioned, that's not doing any of these more complicated things. And like coming from the Dev side of thing, upgrade is always a problem. Like it's across the board, every project I've ever worked on, and it doesn't help that, you know, I tend to associate with like the, the more like, Oh, cool. We're just going to get stuff done.  We have to be in heat. We can't just throw away the version one and use version two. Uh, so I've been in that position where I've been told, no, dumbass, you got to go back and actually find a way to upgrade this. Yeah. Two months later, I was kicking myself. Um, so all of that actual logic, um, should live somewhere. Um, when we do this slide for, um, I'm sorry, but I do this presentation. There's a slide deck. I've used that has, um, the phrasing, anything that's not automated is wasting your time. So, um, if I have to do this manually, uh, get yelled at the other day for setting is when we do it again. Anyway, users are dumb. And if I have to do it, they may screw it up. Um, so there's no, what to say, there's no patch for human error or human error or human error or human error or human error or human error. Yeah. Yeah. Yeah. So how do we, how do we automate that? How do we get that stuff out of the user's hands and, and how do we get it across in code? So these are the kind of problems that operators are trying to solve. Yeah. And also it's, it goes just beyond the, I mean, the operators leverage the, uh, the control loop, the Kubernetes, right? So the, um, the, the reconciled loop, the, um, the whole CRD, right? Cause some resource definition and, um, um, it leverages those technologies, but it goes, I think goes a little bit beyond that as well, because it's more than just like you said, give me a pod, right? It's more than, um, you know, I want to scale is more than just adding a pod to that, right? So there's this, how do you, um, how do you automate operations and how do you, and how do you manage that at scale? And I think of that's, that's the, that's, that's the, the, the main focus of what operators is supposed to do. So. And you're also starting to dip into what they are because we keep talking about them as if there's some kind of weird black magic thing. And I think that box. Yeah. And times it can be. Yeah. Yeah. Well, and that's fair. Um, but it also comes down to like, you know, people don't realize that tangibly it's just the stuff you're used to seeing it's a pot at the end of the day. It's not something you've done where you're hacking code directly into Kubernetes. It's not like you're breaking the schedule or anything weird like that. It's a pod running in your cluster and start there. And then you build from that. This is the third time now. I've clicked away that cookies, uh, message and not realizing this is your screen and not mine. Okay. Okay. There you go. I'm like, dammit, that's really dragging out. Yeah. Yeah. Yeah. Well, do I, do I trust red hat? I don't know. Close this. I stopped clicking it. Yeah. Yeah. You didn't just leave it open to mess with me. Exactly. That would have been a precedent for a long three hours. Uh, yeah. So, uh, it's a pot. And then you mentioned custom resource definitions. So these are built into Kubernetes. They were very recently taken out of beta, uh, into a full blown. Construct.  So, um, so just, well, we have three hours, right? I can go as, as deep as I want, but, uh, so in, um, in, in, uh, in Kubernetes, right? So in Kubernetes, we have things like, um, like pods, right? Like we have these, uh, these objects, right? So we have pods, we have things like deployments. We have things that are built into the API, uh, that are used, um, uh, to, uh, to control certain aspects, right? I'm trying to simplify this as much as, as much as I can. Um, and so, um, what if you have other things you would like to control, right? So what if you have, like right now you can do cube CTL, cube cuddle, cube, whatever you want to call it. I heard someone call it kubectl the other day. I'm not sure. Um, what? Yeah. Yeah. There's, there's, I don't know that. I think that's, that's another whole, uh, so do, so do whatever, um, topic. But anyway, um, cube CTL, you can do cube CTL, get pods. What if you want to do, what if you have something else that you want to control, um, using the Kubernetes API or using that control loop, using that, that watch of, of, um, uh, inside of, what if you want to leverage that inside of Kubernetes? What if I want to do OC get my DB, um, custom research, the way you were originally supposed to do it is supposed to do entry, right? You're supposed to actually do an entry in Kubernetes code. You have to submit. You have to like write that in, um, um, now they, they took that out and saying, okay, well, you can custom define those now. So CRD is custom resource definition. Now you can define, um, what, when you say, oh, uh, cube CTL get my DB, now it'll return whatever you define that as it'll return, you know, either your DB instances or, um, it'll say no resource not found, which is different than API not found, right? So it's, um, it's a way to define, um, some of these objects inside of Kubernetes that you were, that you were normally found, right? As in pods or deployments or things like that. So, um, it's a way to add that in functionality into Kubernetes. Yeah. You just hit on, this will be cool when we actually see it live because I've, I've usually show this too. I do an OC get or a cube cut will get, um, something.  Um, and then you get one that, um, where you have the CRD deployed and you're suddenly getting a different message. It's not quite an error. It just says no resources. Um, so we'll actually see that once we get started.  This is usually how it ends up going to like how far back old school is going to get like XML. And that kind of scares me that XML is considered old school now. Yeah, right. Yeah. Exactly. Like I, I was around before XML.  They're still there. They're, they're writing that horse. They're going to die on that hill. A lot of text you're going to write, but yeah, good for you guys. I don't think gradle uses that. I haven't actually learned gradle yet, but every time I like, cause you can't open it up. And you just kind of stick back.  It's like one of those. I think like a picture is going to come out. Have you ever seen like those stare at it long enough? Yeah. Exactly. A picture comes out. That's awesome. God, I can only imagine the kind of stuff we would get to on like, what the picture would be, but we'll let chat have fun with that. Yeah. Yeah. We'll have chat phone with. But yeah, 32 characters to express version 1.0. Yeah. All right. How do you want to do this? Do you have the PHP priceless running someplace that you can quickly show us? You know what, let's do it this way. How about you just deploy that first without an operator and we see what it looks like. Cool. I guess first I need, where's, where's God? I need his, I need the credentials for that cluster he has up and running. I emailed him to you. Oh, it should be in your inbox. Right there. It should be in my inbox. Yes. So when you do Chris for three incidents, I guess. I did a four three. If you want a four four, I have one that I spun up kind of off the side. Let me see if I can load up my email. If not, I can pass the details to you. That's fine. I'll just open my email here. That's exactly what we want. This is good. Bring up top so we can all get completely. Yeah. Yeah. Yeah. If you want to find a resource consuming zoom. Yeah. That's right. So you did, you did email me the, the, the credentials. So I'll do that. Okay. So while he pulls that up very quickly, we have an internal system we use to set up our clusters. It's not terribly interesting to hear about, but this is going to be an open shift for that three. Yeah. Everything we're going to do will run on Kubernetes. At the end of the day. And I'm the guy that always kind of beats this drum because I'm tired of seeing it kind of used against us. Is that open shift is built on top of Kubernetes. Open ship is Kubernetes. So we didn't fork it and add in any of this stuff. These are all built in native constructs. We could do this on mini cube if we want. And I've done similar things on mini cube.  But at the end of the day, just be very clear, like this is all built on top of Kubernetes constructs. This is stuff that we could do outside of open shift. And I want to mention that because I don't want it to seem like, you know, we're adding this stuff outside of the tree and we're not contributing it back or anything like that. Yeah.  And I don't want to expand to this channel while you would want to use open shift. But it's important to realize before this kind of gets thrown in our face from, you know, shady. Okay. Don't call that. Don't call. I didn't say that. Yeah. And I'll actually use Kubernetes open shift interchangeably. And, and I actually don't do it on purpose. That actually just happens naturally. That happens to me too. Yeah. Yeah.  Yeah. I use Ctl. I use that a lot just because.  I have Kubernetes bear Kubernetes clusters running and I have open shift cluster. I have like all kinds of clusters running. So. So I will say one thing real quick with the operator framework is in the process of being donated to the cloud native computing foundation. So nice. That is a big piece of like what we're trying to get back to the community here. That's what I'll be using later as the operator framework. So that's right. So yeah, it's a good segue into that. But yeah, like CRDs that came out, went GA and 116 operator framework uses a lot of that. So now's a good time to use operator framework and donated to CNCF. Yep. Cool. So I should know the answer to this. You said you have a four, four cluster available.  Was that today? Today. Yup. Today it is in the fast channel. If you want it right now, switch to your fast channel in your open shift clusters and off you go. Okay. The voice of God with the quick. The voice. That's right. Yeah. By the way. I got a booming voice. You have the voice for it. I really think you should lean into this and just randomly just own it. Just do all the stuff that we, we don't really want to be saying here. And you're just like, by the way, a group and shift is a red hat product. Yeah. Yeah. Yeah. And Sebastian that's the definition stuff I'm going to do is going to run just the Kubernetes as well. And just you. Poop cuddle. Just lighter weight for print on my system, but I also have code ready containers in my basement. If I needed it. Anyway, so four. Three, four. Yeah. Yeah. I think it's a three. As we speak. Yeah. I'm looking at the left side. I just pointed to my screen. Okay. Cool. Yeah. Cool. All right. So yeah, we got a cluster here. So that's just like, like you said, Jason, well, I'm just going to deploy this how I would normally, I guess I could do the developer view here. So we'll do that. Actually, I need to. I need to add a project first. So I have to do the administrator view. Projects. This is one of the, the feedbacks I gave to the UI, the UI teams is like, I need, I need, I need to be able to not have to go back and forth. So, wait, if you use the dropdown, it wasn't available in there like a create. Let's see here. Yeah. You see how often I use the UI here. So the top left for project defaults. Add. Oh, you mean here. Gotcha. Pointing again. Oh yeah. I know. I should see where you're pointing. Yeah. Like 30, I learned something. So we're, you know, you know, not even that long in, I'm already learning something here. So let's take that step back though, because you're, you're right about the concept. So the developer console, the developer, I don't think we're calling it that anymore. Developer view. The view, I think. Yeah. Yeah. Yeah. Is new in four.  Three, two, three. Yeah. Um, Come on. God. He's, we're about to go. I heard a siren in the background, right as I was about to say four, two. So I thought for a second, I was like, Oh, maybe, maybe it was four, two. I forget. Um, so a new spin on the same types of concepts. I feel familiar with open shift three. Um, the, the previous series where this was much more of baked in. Uh, a lot of the stuff is starting to come back now in this developer view. So this may look for more familiar to you. If you come from a very long, um, Opus of perspective, that's the word. Um, I, so earlier I tweeted about this and I said the debut, uh, session and about an hour and a half later, I was on a bike ride and I'm like inaugural. That's the word inaugural. I was like this close to like pulling my bike over and just retweeting. She'd be like, no, you're out. Damn it. That was going to bother me. Developer perspective that we're in right now. This looks a little more similar to what they did in open shift three. Um, you know, it does feel a little awkward to be drawing these lines between developer and admin in my opinion. And this actually comes from one of my teammates who's pretty solid about beating the drum for, Hey, we always talk about DevOps and then we're actually drawing this giant line in this giant line. Yes, exactly.  You go over there. Um, but that said, this has some different things to it. So, uh, as Christian was alluding to not everything is available here. I'm pretty sure routes are not quite here yet. Um, they're working very diligently. It's actually really cool team. Um, they do public, uh, Jen, I think you're in chat. You can mention, um, the open office. Hi Jen. Uh, the open office hours. Um, that the UX team does let you talk a little more about that, but, um, So they're working really hard on four, four, four, five, four, six and the kind of different things are going to add to it. Uh, so, you know, your, your point was not wrong that, Hey, there's certain things that aren't available over here yet and that they're coming across. It's not that we just kind of gave up and gave developers this kind of small view on it. Also, I think we, we changed framework. Right. And so it essentially, it's not like we could just run it on, on four to four. Like we changed the framework on how the UI, I forgot what we're using on the back end now, but for it was, I think it was Ajax or something like that. Some, some really. I forgot what it was. And I'm confused into with other projects too. Um, yeah. Yeah. So the routes. So that's a great point by Jen. So we're going to see that in a minute. Um, well, yeah. So we, I mentioned the routes as the example, you'll see there's no menu item for it, no creating it, but when we get into that topology view, which you can see on the left side that I'm going to refrain from pointing to, um, you'll see that once we get into that, there's actually a way to find her out from there.  Yeah. Well, I'm actually, I have a question. So, uh, Chris short, when, when he was doing, uh, when you were doing a stream, you, uh, you named all your stuff after baseball characters. So I don't know what to name my project here. I don't know. I don't, I don't know what we should choose. Um, or for my day have a suggestion. Maybe, uh, people from the rebel alliance, you know, that's right. That's right. Yeah. Yeah. I did the Flintstones when I did, uh, my stream with Eric. It's our, our duty too. Okay. So Eric says our duty too. So I'll say our two D two. There you go. So, um, display name. So it's the human readable name. Um, I like that we pause on that. Let's just acknowledge the fact that we actually had that discussion because this is something that. It's a serious discussion. Yeah. Naming things is important. It 100% is. I have a buddy of mine that I always go to for this kind of stuff. I'm like, all right, I'm setting up a new demo application. I'm like, what am I going to call it? He's like, all right, well, let's think about this. What does it do? Do we want to go like mythology? Do we want to go sci-fi? And you know, way more time is spent on that than I probably should. But you probably should. Oh, I do like the plan X, right?  I mean, I can seize after ships from various shows, especially. Yeah. My naming convention is Looney Tunes characters. Okay. I had, uh, I had a Warcraft realms for a while. I had ships. So I had Star Wars ships. You guys doing cool things. I didn't mind after birds. So I had like, so I like Falcon Eagle. Um, what was the other Robin? And I need to get more. There's, uh, there's, uh, a grackle. That's the kind of bird that's around here. It's really cool looking. It's grackle with a G, not crackle. Grackle. So it's actually, it has gold eyes, a black head and like a purple body is wild looking. And like, that would be a cool name for some. Spaceballs. Yeah, that's right. Yeah. It also makes me a little bit scared to ever go to Michigan because what you just described is kind of horrifying. And it's actually a rather beautiful bird. Once you get past the gold, like, if it looks at you, you're like, whoa. Yeah. Things to get past. Yeah. Yeah. Cool. So I'm going to do a source image, right?  Um, I think Chris, give a source to image stream once. I don't know how it went. Various ways. Sorry. Various ways. Okay. Yeah. I've always used source image. Um, just because, uh, again, operations background, I don't want to get in the habit of maintaining Docker files everywhere. So, um, So I'll just use the source to image here and use PHP framework. PHP version. I actually wrote this on six. I forget what, but we'll see if it works for seven. Yeah. Do life. Do a live. Yeah. Name PHP price list. So we're going to go with either. So here either you can do a deployment deployment config. Um, So if, if you're going to submit. Uh, PRs, Jason, I think I'll do a deployment config. So that way I can maybe do some, um, some automation around this maybe live create route. So here's, here's the check mark. Create the route. So you can actually do it. Um, the source to image now instead of doing it afterwards. Um, so here we go. So we got the amoeba. The amoeba view is I like to call it. Which gives us a, uh, build, right? So let's go here and. So this is straight. That, uh, that was the topology and I like amoeba. Um, it's interesting when you listen to how the, uh, UI team talks about it because there's a kebab menu. And what, uh, there's something hamburgers. And I don't remember if they call the hamburger. The hamburger menu. And I was just about to say, and they call the circles donuts, but now that I think about it, I'm the only one who does that because of all the references. So that's not canon. And perhaps we shouldn't kind of keep pushing that. Yeah. Yeah. So here, uh, you're going to see kind of a little, there's a little bit of dirty laundry with, with this, this, uh, get. So, um, so I'm kind of a little, a little nervous for Jason to see this was actual real developer. Versus just a php script kitty. Um, I'm not. Is there such a thing as a real developer or Jason? Yeah. Yeah. There we go. That's, that's. Uh, God, there's so, so many places I can go. And yeah, the biggest place I want to go is to take a shot on Eric for no good reason, but. Well, while you're going to say at least you didn't use rails. So I didn't actually use any framework. So I just, this is just straight php. You notice there was no, like, if you use like, um, like compose or something like that, they would have, it would have done its, um, download of its modules, but, um, I'm just doing everything straight php.  So let's go back to the topology here. Um, so cool. So I have this amoeba. Um, if I open the amoeba, um, right. I have this little, um, right. Bootstrap ish looking thing on Java. If I, if I try to connect to database, obviously database is not there. I feel this is a source to image demo. All of a sudden it's turned into, but, um, so yeah, so I need to add a database. Okay. We got time. So, um, so I got this. So joking aside though, this is actually valuable because you see what it would kind of sort of take an end user to do. I mean, yeah, some of this, we could put away in a single manifest with multiple, um, I don't even know what you call it. You stick multiple amophiles into a single one, but, um, you know, we could do, I used to call it a poor man's template. There we go.  I mean, it's, it's a poor man's helm chart. I don't know what you want to call it. Um, so I need a database, right? So how do I add a database? So this is at here. This is where we go to the catalog. This is what I have always done and just type in, um, my sequel. I wrote this with my sequel. I guess we can, we can try Mariah DB. Is it Mariah or Maria? Maria. Maria. Maria would have an H in it. Thank you. Okay. Cool. All right. At least I'm not, I've heard people call it Mariah. And I was like, am I, am I the crazy one? All right.  True. But it would have an H in it, right? An H. Does this have storage? Does this, I assume it does have storage some sort of storage? I guess we'll see. Something that had, I mean, I can't, provision without nothing, right? Um, I'll just, I'll just go down the line and call it the price of this. Eric, I like that one. Mariah DB at Christmas time. I think it comes a lot. That's funny. It becomes Mariah DB. All right. Cool. Let's see. Let's see here. If this, if it's, uh, environment, let's go events. Successfully. Uh, volume successfully attached. So I guess we do have volumes. Yeah. You send it entirely to surprise there. And then we gotta be like, no, we knew this was going to work. Well, so, so we're doing this. I see. This is a Twitch stream, which is why, I totally applies, but like, yeah, yeah, it cracks me up in, in like more formal demos when they actually sound surprised or when I accidentally slipped my own voice in a demo. I'm like, I should have made it sound like I knew this was going to work. Yeah. I knew this. I had, I should have made it sound like, of course it's going to work. Mm-hmm. That's why you do the long umbs and C just like that. And just like magic. My magic, it's up. How long can you make that pause last while I'm being weird? Do I, can I add this to the, to the Amoeba? Should I?  It kind of depends on how you've written that PHP. Okay. It probably won't do anything. All right. Okay. So database is up and running. Cool. So the way you get this app running, you can either inject environment variables as I do it in my, in my purse list here, you can either inject them directly or what I've done is you can actually set a config map, right? Like in my code here. Depending on what you need to, you could just attach a secret from that my SQL created to it. Yeah. Yeah. That, that as well. You can do all kinds of things. Usually I just give it up. That's what everyone is gonna see me do in the Odo Twitch stream when we actually schedule that one. Am I the only one that says Odo? Well, you know what's funny? When we were talking about pronouncing things earlier, that's another one that it sucks either way. There's really no good ways. You're like the third. Well, I think everyone in the evangelist team says it that way because you're like the third person that I've heard say that way. Yeah. The problem is I'm doing the talk coming up. Langdon on our team says it that way. Does he? I want to do a talk coming up called Odo or Odo not there is no try. There is. Yes. So written that's fine. It just doesn't really translate out loud. Or Odo. You could just spell it out. Odo, yeah. Odo. Cool. So I need to, I need to connect to this database. So that's how do we do that? You can tell I spend a ton of time on this. Compute? No. Monitoring? No. Someone help me out here. What are you trying to do anyway? Config map. I'm sorry. Config map. Workloads. Sweet. Config map. All right. So let's create a config map. On R2D2.  Like I don't have to know how to formulate this. And just give me an example here that I just use here. That's something else to go into more OpenShift 4. Trivia is not the right word, but new features. This has decent amount of autocomplete on it if I'm remembering correctly. Not seeing it pop up, but I know I've definitely seen it happen before. I guess for data it's not really gonna have anything, but... Yeah. So let's go here and this is just a... If anyone knows how I code my PHP applications, it would, okay. Make sure that you'll be able to hack it easily. It's about to say, speaking of hacking. So we're injecting direct code into... Awesome. Awesome. That's right.  There's no... I mean, there's a few, but there's not... We can acknowledge that this is a bad practice. Yes, you're correct. Yes. And that's honest. I mean, we all do presentations and stuff. And I'm sure every single one of us has been on stage showing something and be like, look, no one would do this. No, please don't do it this way, guys. Yeah. Don't do it this way. I'm just doing this for the sake of time. Yeah, all right. It's how I did an operator's demo. And if I had to do it today, I had like username and password like hard coded in. I'm like, don't do that. But for simplicity, we're going to do that right now. Yeah. Anyone remember what I called my service? No one remembered what I called that. I don't remember what I called my service. So let's look it up here. Call the namespace R2D2. I don't remember the service. Let me see here. Where's networking services? I called the service. The service is called MariahDB. Maria. MariaDB, sorry. Sorry. That's not her design. That's right. So let's change the, let's change this here. So I have to change this word to say, there we go. In case any of you are wondering, the whole string, how you connect to a database, I'm just using the service name. But I just, that's always the service name, namespacename.svc. I don't even think the namespace and the SVC are required. Not that I'm saying take them out and chance it, but I'm 99% positive I've just used the service name. You could just use the service name, yeah. So let's just do it that. Let's do it live. Yeah. All right. So- So if it looks bad, then I just kind of sit back. Yeah, exactly. You shouldn't have listened to me. You say it's your fault for listening to me. The ultimate is Eric. He was texting me instead to try that if it breaks. Yeah. So here, now how do I, oh wait, I have to go back to administrator view to attach it. Let's go to deployment, which would be on configs, price list, oh, my phone's going off. Here, there's a way to do this that is not in the command line. What are you doing, attaching the config map? Yeah. I think last time I had to do this in the command line. Hold on. Nope, nope, right there. Add all from config map for secret. Middle of the page. Oh, no, wait. Now down at the bottom when you had it right the first time. This one down here, right? Going down, down. Yeah. Let me remove this here. So add all from config map for secret, right? I think it's just going to end here, yeah. Yeah, so I should just be able to fig prefix. That's the, is that the, do I do it like that? That's a good question actually. That's not a prefix, isn't it? Yeah, no, I don't think you need one. No, it says optional. Well, I'm trying to mount it as a file. I remember I had trouble doing this. Okay. So. So I'm going to take this off screen because what I'm going to do is I think I'm going to have to drop down to the. I see a chance that if anyone wants to type in that token, let them, they deserve to part around on the answer. Yeah. Yeah. If they got it. If they have, if they have a photographic memory, right? If they got it that fast, I can shut it down that fast. Yeah. Okay. So I'm going to do OC project R2D tubes. Okay, cool. And then I could do OC get C. So I already volume. I already don't know how to do this. So it's set volume. To put it to refresh your things. We got to do this on Ansible in a second. Yeah. Yeah. So, yeah, exactly. So okay, set volume add name V1. No, I want a source should be removed. I think it's like, okay. So it's OC set volume on my deployment config. What do I call this? I think it's HP Priceless. Okay. HP Priceless add, right? Cause we want to add it. So let's do that. Type is config map. Oops. They need the map, right? Yeah. I think I want to mount it on slash data. Let's see here. We're doing this live. Where are the configs? Yes. Slash data. So I'm expecting, oops, slash data, where'd I go? Yeah, okay. And then, so PVC, okay. So, and do I have to do, is it claim name or config map name config? You're a bit on your own here. I usually choose environment variables. Yeah. Name, maybe we should have just done that. Config map name, but this is crisis config price list config. And then I want to do it on slash data. That should work. Give it a shot. I'm doing this live. So, all right. Oh, okay. All right, so then it took it. So now it's going back here to the developer view. It took it. Restarting. And it is restarting. It should do this rolling deployment thingy, terminating, cool. So then now if I go into my terminal and I do cat data db.php, it's not there. Nice. What's in slash data? Yeah. So if you don't, if you don't see the typo, I won't tell you. Oh, we all saw it. Yes. So I need to change this here. This is why, there we go. Although to be fair, you did set with the screen up here for a while and we didn't notice it. We didn't notice it at all. No, we were sticking you for it too. Yeah. So the only way to do this is you'll see delete, pause. Let's just do that. I probably shouldn't have done the database one. Oh, well. You gotta have state somewhere, right? Like in all the stateless stuff, state has to live somewhere, so. Well, luckily I didn't write anything, so.  Right. Yeah. Now. Okay. He didn't lose a bunch of production data. That's good. There it is. All right, so there's my config. Yay. All right. So this is kind of where I air my dirty laundry a little bit. You need to access the night. Okay, this is fun. Um, okay. It shouldn't have done that. Access denied. So that means is that I probably have the settings wrong. So let's go back to, Did we, I forgot at this point, we need to deploy Maria. You actually created a priceless user, right? User, yeah, yeah. So let's go to the environment. Okay. How do I, how do I see it? There used to be the eyeball. There is no eyeballs. Um, I could drop to the command line and view it, right? So I can get OC get a OC in V, I think. No. OC get, get off and see what I want here. Yeah. Okay, cool. So then it's a deployment config. Okay. So OC get DC, Maria, DB, oh yeah. And it should be one of these. So it's in a secret. Okay. OC gets secrets. And I bet you it's encoded. Yeah. It's what, base 64. Yeah. So let's, let's echo base 64. Database name is price list. Nope. Type of purse list again. Porse list, argh. And I bet you anything, I did that with a, I did that with, oh yeah, because look, it's exactly the same thing. The whole thing. Yeah. And now we know why it all breaks. That's why it didn't work. Okay, cool. So let's, let's, let's roll with the typo. Yeah. Run with it. Let's go to where's workloads. There it is. Deployment config maps. And then YAML, purse list. Let's just do, let's do it that way. Okay. This is particularly funny since I called you out on it in the, the read me too. Yeah, that's right. Yeah. You know what? In my head, I, I, I probably did it as a, as a joke. And then now I'm paying the price for it. At least that's what I'm telling myself. Let's go back.  All right. Refresh this. All right. So no records found. So that's what you want to see, right? Um, and then some of my dirty laundry, create database.hp. I need to create the actual tables and stuff. There it is. Okay, cool. All right. Oh man. We can have Ansible call into that and automatically do that. And automatically do that. That's exactly right. So let's create a record. Um, so price is supposed to be like, this is what we do this here. What are we selling here, guys? Bananas. Bananas. All right. B-A-N-A-N-A-S. Oh gosh. Should I pick an easier word to spell? Yeah. I mean at this point, we're kind of running out of words. Can you spell orange? Description. Tasty fruit. Oh wait. Okay. We're getting some on chat here. Oh yeah. You need to name it X-Wing or A-T-A-T or A-Wing or something like that. So we're doing lightsabers. Yeah, we're selling lightsabers. Gently used. Okay, cool. Price. Gently used lightsaber. Gently used lightsaber. May or may not have bodies on it. Yeah, it may or may not have dried blood on. All right. I'm at sports, B-V-A-T, I hear it. So, and I guess it's electronics. Motors, actually. I guess electronics. There we go. If I angle it up, you can see my B-V-A leg up there. Oh yeah, a B-V-A. Nice. Yeah, but probably you only see like my forehead if I have it up like that. Now I gotta fix all this. All right, cool. So now we have, all right. So this is the app, right? Simple app. It took us a while to get it deployed, but it's boring any typos. We got it deployed. Two Red Hat experts deploy a single two-container application in 45 minutes. Thank you for attending our Twitch chat today. Yeah, thank you for tuning in next week as we attempt to exit VI. Yeah, exactly. Yeah. Exactly. Fun story, I've never, I don't know how to exit E-Max. So. Control X, Control C, naturally. Yeah, exactly. So, B-V-A-T, cool. All right, now that we have that context set, oh my God, first and last session on Twitch. All right, this is where we have fun with this. This is good. Actually, honestly, all kidding aside, it was kind of interesting to see this play out because there's obviously multiple ways of doing it in terms of the config map or attaching the secret directly, we got to see messing with UI. We got to see messing with the command line. And more importantly, he had to individually do each of those pieces watching you fight with this arrow right now. Yeah. So where does the operator come into this? I think we will probably take a break, actually, given the, yeah, it's almost four o'clock. So it's probably a good, quick five-minute break time. But to kind of put things in contact, and I'm watching this E-Max chat go on, and you just want to save. I always start, I'm the first one to start a VI, E-Max work, because I'm like a VI guy, like hardcore VI guy. I mean, it wouldn't be a good solid Twitch stream if we didn't have some kind of. If you didn't have some sort of. We've already had some language arguments we've had. We're now getting into the editor's arguments.  Yes. What are we talking about? Operators. So all of this was done using these very fine level Legos included within OpenShift. So what operators are going to give us, we talked about the custom resource definitions earlier, we're going to be able to define a resource that talks in terms of just a priceless. And instead of us having to, us being the end users. So we threw Chris short at this and said, hey, go deploy this thing once we're done. All he's going to have to do is type in, try to create a resource named priceless and going to hide away a fair amount of this stuff. I think it's a good time for a break. I can use a quick five minutes to walk around. We can let chat continue on how they plan on going down the editor route here. Should we do that? You guys want to go walk around for like five minutes before we actually start the operator stuff? Sure. I'm fine. Well, yeah, if you need a break, let's take a break. And I'll maintain the chat and let everybody know we'll be right back. OK, like five minutes just over, everyone. All right. Now we should be back. Or not. Yeah, I don't. There we go. All right. Little technical difficulty. Yes. Everything moved around the second I added that BRB thing. So, yeah. So the break was nice because I actually got an Amazon delivery. So it was perfectly timed. So that's nice. Well, there you go. Cool, cool. All right. So welcome back, everyone. Thank you for coming back after the break with us. We're going to get back started into what, Christian? So actually, Jason just asked me if I have the SDK installed. I actually do have the SDK installed. I don't know if it's the proper version. I have 16 Dirty. I don't know if that's the latest. I'm on 17. I don't know what Dirty means. Yeah, I don't know how much. It says 16 Dirty. So I'm not sure. I'm very curious where you might have gotten that from. While you download that, let me kind of vamp a little bit on the operator. Yeah, yeah, go ahead. I'll go to the GitHub page and just download the binary. Earlier, we talked about how the whole operator framework, we're donating this to CNCF. Now, operator framework means that term. And you can see it in the URL here, the GitHub word, refers to three projects. Operator metering, which is focused around usage and resource allocation for operators. Operator lifecycle manager, operator lifecycle manager, or OLM for short, which I don't think we're going to spend a ton of time with today. And in fact, if that's not on the list of possible Twitch topics, we can add it. That is basically yum for operators. That's kind of trivializing it a bit, but it handles dependency management, lifecycle management in terms of installing and upgrading operators and making subscriptions to different channels that support them. And so we're going to spend the rest of today on barring any other tangents, which we know we're going to have. We're going to, by the way, I just downloaded the wrong architecture, right? So a period. So today, I think I'm on arm tomorrow. Actually, I do have some raspberry pies laying around here. So no, I do too. So I totally, I totally actually, that'd be, that'd be just a fun, like, off topic. Get Brian Tannis on here and just talk about the weird kind of stuff everyone is going like Chris Denny as a nuke. I know Brian got me set up where my raspberry pies running a pie hole right now. Just been pretty awesome. Yeah, I've run that for a while and it's amazing. It's kind of like, you know, yeah, it's, it's, it's great if you're capable of making everybody in the house happy. But when my wife's on her Facebook ad and like suddenly features stop working, like certain features in the Facebook app were like messing with my wife's Facebook, like piehole was messing with my wife's Facebook app experience, not the website, just the app. So I don't know what was going on. No, Brian said the same thing. He's got it set up where you can just get to a very easy API interaction to turn things off and enable certain things. I've yet to see an issue and maybe that's because if my kids complain something's not working, I'm like, you probably shouldn't see it anyway. If the piehole caught it, digital babysitter. So we're in there. No, I definitely, I just switched. I got Max, I switched around a bunch of PCs here at home and Max, my son now has his own, but I switched his DNS over to one of those that filters the adult content. So Cloudflare has one. I just switched it over to that. And I'm hoping that, we've been using the one for malware since they released it a few weeks ago. And I'm hoping the abuse one does just as good, but there's also a thousand one other ways to protect your kids' internet usage in the house. But most of them rely on DNS. So yeah. As many of you know, I really love DNS. Question is the knower of DNS. Not really loves DNS. He knows DNS. Oh, I see Brian. Okay, nice. I know. Yeah. I'm getting stuff on the chat about it. That's why that's why he's the best. So I no longer have the dirty version. So that's good. Yay. Yeah, where did dirty come from? Do we figure that out? I actually, I actually compiled the operator SDK. Oh, there you go. So all right. Source, so now we know. As one can do with open source software. So the SDK, the third piece of the operator framework. To be very clear, this is not the only way to write an operator. There's a Python library called KOPF that is for writing Python based operators. So, but it, this isn't the only thing.  That said, it's going to make your life a lot easier. If you're going to be sticking with one of the supported run times for it, just to say helm, Ansible or go. We've been pushing internally for them to add support for other languages as well. I don't know the roadmap. Just speaking completely personally, I'd be surprised if Java didn't find its way in here soon, given how much of a Java influence we have. But SDK we're going to spend the rest of the day with is going to generate a lot of the scaffolding for us. And particularly in the case of the Ansible operator, which we've been saying, but that's not really the accurate term. It's going to be an operator that uses Ansible Ansible. So all of the play, the plumbing for running Ansible for wiring it in. So the custom resource values get mapped to the Ansible playbooks, running those playbooks, setting up the watches in OpenShift to understand, hey, this resource got created. I should tell this operator about it. All of that stuff is going to be scaffolded out for us and handled. We're not going to have to rate any of that. We're just going to have to provide Ansible to it and then go from there. Kristen, I was asking you over the break. I'm just going to save this from when we get to it, but I'm kind of curious to see how you test this thing because there's two options. And I'm curious to see which route you go, but let's- Okay, interesting, all right. Yeah, we'll get to- We'll do that when we get there. Cool. Yeah, exactly. We'll get there in a second. So yeah, so this is the SDK itself available from the releases. If you were watching in the background as Kristen was clicking around, you can build it yourself if you want to be like Kristen. Yeah. And get dirty. So that's when you get dirty. We get dirty. You get dirty. It's when you build it yourself. All right, so let's get started. Filthy, nasty dirt. Yeah, so I'm doing a little, you asked me in the beginning, I don't know if you asked me on or off the air if I've written an operator report. Yes, I have. So it's a little cheating because I kind of know the steps a little bit. It's been a while since I've done it and the reason I use Ansible is because I come from an operations background and it's just the language that's easiest for me, right? Right now, I think you mentioned it that right now I think it's just Ansible, Helm, and Go, right? And so... But again, that's just in the SDK. Yes, it's just in the... There is a job library out there. There is a Python library. Correct, correct. So when the framework came out, it's like, well, my choices are either Go, which I don't know, right? And I don't know any statically typed language. So I'm like, is the learning curve, how steep is that learning curve? That's why I went with Ansible just because I've already been using it. Yeah, I'll get Holy War for a second.  So the question? More of a personal thing. Yeah, the question I always ask myself when creating an operator, and it's a question, it's really... It's an easy question, but it'll fundamentally shape how this operator will run and how your users will interact with the operator, is that are you going to create a namespace-scoped operator or a globally cluster-wide operator, right? And that's the first question I ask. Even before I type any commands, I ask like, how is this operator, how are people gonna interact with this operator, right? So, Jason, do you wanna go over what the difference between a namespace-scoped versus cluster-scoped? Yeah, so by name, everyone probably has an idea of what to expect here. It's a fairly safe bet to say it should be namespace-scoped unless you have a reason for it not to be. So I'm sorry, I just saw something in chat. Are we starting or ending? This is actually good timing because we are just starting the operator part of it. Spent the first hour kind of messing around with the application itself, showing how to deploy an OpenShift note. I didn't say showing the right way to deploy an OpenShift, showing what happens when you put two guys on screen and attempt to deploy it on OpenShift when people are watching. So now we're just digging into the operator pieces itself. Okay, so you should probably put it namespace-scoped unless you have another reason. That means that you'll deploy the operator into a specific namespace. It will take care of any custom resources deployed within that namespace. So for something obvious like priceless, you probably don't need that cluster-wide. Cluster-wide things are a little bit better when you think of how OpenShift itself runs. And I don't wanna get into a tremendous amount of details, but all of OpenShift 4 is pretty much driven to run on operators. So when you scale up your cluster notes and you're handling your networking, there's a variety of things you do that are all fielded by operators and those function at the cluster. I mean, they're affecting the cluster itself. So they're going to really function at the cluster level. They should be installed that way. For the most part, things you're writing on your own, I would try to keep it namespace-scoped unless you have a reason why you're gonna wanna throw it across the entire cluster. Yep, there you go. Pontificating from Jason, nice. I like it. I like it. So we're gonna do this, oops, I am on the wrong window, okay. So operator SDK, I guess new is the sub-command. Do we do help? Let's do help. Yeah, so new is the keyword here. So we're gonna do a new, and then we have to name this something, right? We'll call this price list, how about this? So, and then let's just hit the help menu. So what does this give me? Type, you're gonna want type. Yep, so by default, so we mentioned that the SDK has three different technologies that uses Helm, Ansible, or Go. The default is gonna be Go. So if we just hit enter at that point, it's going to produce the Go scaffolding for an operator that you would manipulate and go. Here we're gonna do dash, dash type and put Ansible, and it's going to stub out Ansible project, which means the Go code to run the controller itself and hook into Kubernetes. I mentioned that, but we're not gonna edit that at all, but that's that kind of glue piece. And then it's gonna generate for us an empty role that we're gonna watch Christian edit live. It also has the option of pointing it at an archive and having it pre-populate that role for us, but that's no fun. While he's typing that in, I'm gonna talk about API version and the kind name. Kind is a little bit easier, but that's basin. Thank you. So it's effectively the type name. If you think in Kubernetes, when you've created a new pod, it's been in the template in the manifest, I've said kind equals pod or deployment, kind equals deployment. Here we are creating a new custom resource type, which is created, nevermind. We're creating a custom resource type and the name of it is gonna be priceless. That's the easiest way to think about it if you're not familiar with this stuff. API version is, I got yelled at for saying this before, but I'm gonna do it again. A combination namespacing and versioning construct. So the priceless.example.com is going to help identify priceless itself and then the V1, alpha one is gonna be the version of this particular custom resource. Why did you get yelled at for that? So this, I mean, that actually, yeah, that sounds like a pretty reasonable explanation for it. Yeah, like that doesn't sound wrong at all. I forget exactly, maybe it was the phrasing. So this is back when I was writing the book and I had perhaps leaned too heavily into calling it a namespace and not enforcing the version part of it enough. Oh, okay. But maybe it was just my phrasing and I kind of just dropped it on the paging correctly, but at least one person, if not two reviewers both were like, ehh, you're a little off there. But you guys helped verify. Now that I've explained it a thousand times, maybe it's a little more clear. Yeah, I mean, if you're not wrong, I don't feel like in that explanation, it is a way to assign a specific thing. You're creating something out of thin air when you're doing this. So you have to name it something, you have to give it a proper version and that's what you're doing here. Right. And then you, yeah, exactly. And then the namespacing stuff, you're avoiding potential conflicts. So as a operations background, for me, that's, this is what I have to type when I create my custom resource. Bingo. Exactly. Right? Yeah. It literally becomes part of the YAML manifest that you have to write, right? So, cool. Scaffolding done. Look at that. So here it should have created, there we go. Crisis director. Crisis, that's right. So, oops, not print. Let's do tree. Right. And just see what we got here. So we got, Let's start at the top. Because remember, operators deployed as pods. So in some capacity, bad way of saying it, at some point we're going to build this as an image and run it inside of our cluster. That deploy directory, those four files in the middle, the operator role, role and service, those are going to be used to deploy it. They don't have to be, but the scaffolding stubs out that stuff for us. So that operator.yaml is the deployment for the operator image we're going to build. And we'll actually see in there, it's got this giant replace image where we have to put the image name in of what we build. And then the service account and role, the operator has to do things inside the cluster. So it's going to need a service account to do that. It's going to need permission to do that stuff. So it's going to have to have a role. And if we take a look at that, which we can dig into in a second, that role is really permissive because by default we just generate it with access to just about everything. At some point when you're writing an operator, you want to review that and trim it down to what is necessary. For instance, it talks about secrets and config maps and it has full crud access to all of them. Now this is obviously going to end up being namespace scoped, but at the end of the day, being a good citizen that's going to be deployed on a cluster, you'll want to trim that down and customize it kind of as necessary. The two things in the CRDs directory, so the CRD file itself, the top one is a stub for the cluster, I'm sorry, the custom resource definition. So once we dig into that, you'll see those terms that we just use with the API version and the kind. And then CR is a sample resource. So it'll actually be how do we create a custom resource of price list? And it's going to stub out variables that don't really exist because it doesn't know because we haven't defined them yet, but we'll have to go in there and edit that at some point. Cool. So let's dig in there. And then roles is an Ansible role. If you're familiar with Ansible, a lot of that structure should look familiar to you. Yes. So the easiest way that I've done this, so this is just Ansible. So for those who are watching who are familiar with Ansible, you essentially have the breadth of the entire module catalog for Ansible. So this is just essentially it'll just run an Ansible playbook. So if you have existing playbooks, you could import them and hack them so that way you can tie in your custom resource into the variables. What I like to use is, since I cheated, what is it, Ansible doc, right? And then I think it's called Cates module. Yeah, Cates module, yeah. So what I end up doing do you have examples here? Do they? Do they or do they? There we go. What I end up doing is I create Kubernetes manifest files, right? So like deployment YAML files, service YAML files. This is really the easiest way to deploy an application using Ansible and Kubernetes together, right? So you have the manifest files that you can then leverage the JINJA templates and use that in conjunction with the variables that you're able to pass through, right? So someone can create a custom resource, type those variables, those variables will come through and you can post-process these YAML files with those JINJA templates and we'll go over how that looks like. So you have the whole breath of the whole catalog of any Ansible modules, but I'm gonna cheat and just use the Kubernetes one just because it just fits naturally, right? I wouldn't even call that cheating. I mean, that's gonna be your best, but I thought you were gonna say like cheating in the sense that you're gonna copy them out of here and just modify, which is actually pretty badass if you legitimately used what equates to man pages as a starter. Yeah, yeah, yeah, exactly, really cool. Well, I mean, it really, really all you really need, I'm just gonna highlight it here, really all you really need is this, right? You need the template, lookup, yeah, that's it. Yeah, lookup template, boom, state equals present, right? So you can do a lot of other fancy stuff with it, wait for certain things to roll out before other things roll out and we can try those later. But I think- You might wanna get into that, to get that database load call in there. Yeah, yeah. Well, we'll see how far we get. Yeah, exactly. I was surprised how far Eric and I got with the Alexa one. I kept saying, man, we're a lot further than I thought we're gonna be. So that's what I like to do is I like to create a workspace at the cluster I'm working on. So we'll see a new project, workspace, right, scratch space, whatever you wanna call it, we'll see project workspace. I'm already on workspace. I always do this just because I've been burned by- Cause one day it's not gonna switch you over. Exactly, one day it's, I remember very early on, right, Kubernetes V1, 1.0, alpha, which then OpenShift use, obviously, it didn't switch you over. So I got burned a few times, cool. So then that's, so here, roles, right? So this is just an Ansible playbook. So let's do this. Price list. So here, this should look very familiar if you've ever used Ansible.  This is all normal Ansible things, right? So here, if you're just Ansible, none of this just surprises you. So what I like doing is I like to do OC create a deployment and then we'll call this a price list, right? Because, and then image, since this, I always like to say this, since this is a cooking show, I already pre-made this image. Actually, what did I call it? Let's do this live. Quay.io, Quay, there it is. And then I need to sign in, obviously. None of you emailed me. I won't respond. So then here's where things are gonna get interesting because we could do this entirely without building the image. This is what I was asking about earlier is that I wasn't sure if you were gonna go that route.  Yeah, so I actually took, so I built this beforehand and I just took this image that it built and pushed it up to Quay. And I just have a version of this application running. So you can say, what can you say? Price, yeah. So they hear image, price list, latest, and then... Chris, you look at me that you're watching every time you write types of price at this point. Yes. I'm like, I'm triple checking as well. So I'm like, am I typing that right? I'm like, these guys didn't say anything. I'm like nodding my head as he types it. I'm like, well, I'm looking back at you guys, I go, are they? Yes. Okay, yeah. Price list, confirmation. Okay, good. Yeah, I realized I was aggressively watching that. Yeah. So once I do that, so this dry run or YAML, it basically just gives me a YAML that you can actually feed into the case module, right? So... So this is cool to see, because I don't do this. I go the opposite approach. I take one I've written in the past and then I modify stuff. Modify, yeah. This is neat though. This is a very cool way of doing it, especially with the dry run, because I totally forgot you were gonna do that. I totally forgot that was a thing. I'm like, well, I create it and then you delete it after the fact. What I've been told is that if you wanna pass like the CKA and CKAD exams from Linux Foundation, is that like the dry run OEML thing will bail you out a bajillion times. So you have to get used to using that. Which is what I used when I took that test. Right. So that's why it burned into my head. I always like to do namespace means replace me, right? Because I'll actually write that into the YAML. And I'll remember that to replace that. Because as you see, I've been burned before by not providing the namespace. I don't know that you need that. I thought that the ansible will fill that in for you. Will it? I don't know. It'll fill in the, well, maybe. We can look. I have an example of it. I'll pull it up right now when you keep going. Yeah. There has to be, can we pull the audience? What does the audience say? What does the audience say? No, okay. Alrighty. So this is what I have in my example of it, is that. So we're gonna, yeah. I see what you, it was basically- Namespace is a variable. We need to replace that with a change, yeah. Yeah, yeah. But you, okay, I see what you're saying. I mean, you have to have it. So this is for me to remember, I need to make this a part of the template, right? And this goes back to me. Copy and pasting is that I just take that and I don't look at it again. So that's why I didn't remember it was a specific ginger replacement. So, yeah. So here I'm gonna put it in the templates, right? And we'll just call it this deploy.yml.j2, right? This is gonna be a ginger template. Cool. So now we have that. This burned me in the past. Delete the status. I don't know why it doesn't like it, but it doesn't. So it doesn't like an empty set status. So here- If it's an empty set or if it just doesn't like a, well, no, it doesn't like the fact that you're trying to- You're trying to create with the status. Yeah. I didn't think that's what it is. So here, yeah. So here, what I like to do is, this will be, all right, so we need to know why I'm gonna do it this way. And the way to do that is to go back up a little bit. And then that would be in the build. No, that would be, where is the, let's just do tree. The actual operator. Oh, there it is. Okay. I can't tell you how often I use tree when building an operator of any type. So tree is my friend. Yeah, tree almost like tree because you have like so many directories, like where is that? Short of writing a fine script. So here, this is the deployment for the actual operator that it's gonna build, right? So this is the actual operator deployment. And then this is what you're gonna use to deploy the operator once it gets built. A few things that, wait, Eric Jacobs is on, right? What is that trick you showed me, Eric? Eric Jacobs, I think I had to leave. Eric Jacobs has left the building. Well, because I do control, so for you, I do control V and then to like highlight, but I think there's like a better way to do. Vem, key bindings, and I, nah. I mean, visual block is what you're thinking of. Oh, okay, yeah, yeah, yeah. So it's shift V, I think, yeah. That's just V, isn't it for visual? There we go. Yeah, it is just V. You're right, why am I doing shift V? Well, visual and then visual line, which is a different thing. Okay, okay, cool. Where is that? Okay, so it's here in this little section course, now that everyone's watching me, my VI skills are failing me. Told you we were gonna get to a point where we had to exit. Yeah, yeah, that's right. Here we are. So this operator gives mixed use of the downward API. So basically it'll, you're able to, and that extends to what you're doing and your logic and your operator, right? So you can call things like metadata.namespace and it'll just fill in whatever namespace you happen to be on or metadata name, right? The name of who you are, right? In this case, purse list. So it'll get filled in and you can use that. I'm trying to avoid using leverage. You can use that because we use this so often at work. It's just sometimes you get tired of just saying, you can leverage that. You can use that in the actual operator that you're building itself. So going back to roles, templates. So then when I say namespace, I can actually do metadata.namespace and whatever namespace, oops. Thank you. I happen to be in. I happen to be in. It'll drop it there in place. So I can use some of those, some of those niceties. And I can basically change this to whatever I want. I can do here. I think I could do a dash, you know, price list. Back end, yeah. Whatever, whatever this is right now. Front end's more accurate here. Yeah, front end, yeah. Front end, there we go. And then...  With the namespace, we don't wanna append anything too. It was the name. You're correct at that. So here... This is gonna be the name of the deployment itself. Price list is fine, just leaving it. I mean, that's what you did at the command line anyway. Yeah, as long as you spelled it right, should be fine. The point's... Yeah, yeah, yeah. The point stands that... Yeah. You can do the templates with that kind of dropping it directly in. Okay. And then some of these things that are, and these are the things that get passed through into the CR, right? So I can even do things like make the replicas. Right, I can do like instances. Sure. And then we can have that as a possible option into... Yeah, exactly. And then here's what you get to... I mean, at the end of the day, when you have Ansible, this could also be defaulted in the defaults and there's all sorts of goofy things you can end up doing there to get super creative about it. Yeah, exactly, exactly. So, cool. So I got this, I put int here because again, I've been burned in the past where for whatever reason Ansible... Or whatever the operator converts it into a string. String every time, man. And then it'll drop it in and it's like, wow, what did I do wrong? It's like, you know what, I'm just gonna... Whatever, even if it's an int, I'm gonna change it into an int, mutation is what they call this, right? Worst safety. Yeah. And then, yeah, exactly. And then here, you can change... We won't change this. We can't change this, we can do this. We probably want... So the issue with not changing this, it means we can never deploy more than one priceless in a single namespace using that operator because it's gonna call it priceless by default. So I can do like... Presumably, there's probably, say metadata.name, I think, yeah. Because that will be, metadata.name is gonna be the name of the custom resource itself. So when we go and we create a resource and it's API version is example.com and the kind is priceless, we're gonna pass it a name. That's gonna be the name of the priceless resource. We're gonna then take that and put it in both, the label and the name, which you've bounced over twice now. Did I bounce it over? Right here, namespace name. Oh, okay, there we go. All right, so yeah, you're right. Because if we then, what's gonna happen is this, the operator is going to create this deployment. And if you created this deployment and named it priceless, that's fine until we try to make a second custom resource of type or of kind of priceless in which case it's gonna kind of bump into itself. I'm gonna make sure, okay. All right, cool. Metadata name, metadata name, metadata name space, instances, anything else we wanna, to put it right here. Hey, it's fine for now. Let's just get this working, we can always tweak it. Yeah, you got enough templates. Cool, cool. So that's this guy here. The next thing is, actually, we need to not drive around this. We need to actually run this. And I'll tell you why in a second. This is a Kubernetes thing. So if you wanna do, now it's a service, right? So we need to do an OC expose, so OC get deployment. Oh, what's wrong with this cluster? There we go. I guess, yeah. I mean, once I'm a PDS cluster has disappeared. Yeah, yeah, yeah, okay. Did you run the cleanup script? All right, so we wanna do OC expose, right? So what's this OC expose? You can actually take, you can expose a service, right? So when you expose a service, it'll create a route or an ingress point on OpenShift. You can also expose things like deployments. So what does exploiting a deployment does? It actually creates a service for you. So you can see that by doing OC expose deployments. Price list, yes? Yes, okay. Price list. And then you need to give things like port, right? Port number it's gonna listen on. And I want it to listen on 8080. Target port, which is the port in the container that it's listening on, which is 8080, not 8080 dash dry run dash OEML. And this, there we go, should create a service for you. So now we got this little handy dandy YAML generator. And this will go to roles, prices, templates, service. Right, yaml.ginger. All right, so let's edit this guy here. Service. So I guess it's the same thing, right Jason? You need to just do... Apps definitely gotta be the same. I mean, the service really, it's likely gonna be the same thing too. Is it meta name or meta data? Meta name, meta, meta, Jesus Christ. Data, I completely just brain fired on this. Yeah, I did too. Let's look at the operator, the operator. It says meta data name. Yeah, okay, that's what we used, meta data. And then meta data, yeah. Okay, good. Well, now you got me second guessing myself here. Meta data, meta data, meta data, okay, cool. So meta data name. And then... Ending quote. No, good catch. And then this is the same thing too, right? I just picked you right now, thinking back to about an hour and a half ago when you're like, J, do you want to drive? And I'm like, no, you can drive the demo, that's fine.  Yeah, yeah, exactly.  Yeah, exactly. Well, at least, you know what, because you don't want to drive, it lets you be a backseat driver. And I think that's even more entertaining. Exactly. It's for who though? I mean, it's entertaining for me to watch Jason backseat drive you. Yeah. It just makes me... When I become a backseat driver, it makes me a more conscious backseat driver. Now, don't forget to delete the sass at the bottom now. Status. Do we need the status? No, because this is a creation. Status load mounts, okay, that's good. Do it live. Cool, all right. And then... My sequel. Yeah, sequel. And then the config map and all that stuff to wire it up. Now, I'm curious how you're going to play this, because like I said, I'm making you drive. Are you going to test this part by itself, or are you going to go everything and just, Jesus, take the wheel type of approach? Yeah. I could do... So ideally, it depends what we're doing, right? So ideally, you should be able to just dump it all, right? And Kubernetes should just fix it for you, right? Like, the database should eventually come up, and your front end should eventually come up, and it should all eventually sync.  You should test everything before it comes up. We can do the hacky version, just put a bunch of sleeps in it. I'm game for whatever. Honestly, I think we could just, we don't need the sleeps because you have, unless we decide to deal with your database creation step. So from a development standpoint, the cloud native, no, a cloud native approach to this would be your PHP script has on startup, it's going to try to create the database, and then you'll have a loop in there for X amount of times if it can't find the database, and that's how you resolve some of this timing issue where you throw it all out there, and it eventually lines up. Yeah, so I think what we can do is we can just leverage Ansible, right? There's an Ansible module, probably for MariaDB, to check, right? So there's a... Like a blocking task? Yeah, there's like a block, and it'll just keep checking, and it won't go until the next part is over. So we can do it that way. So let's, I'm just reading a chat to see if... I'm looking for a role right now. Yeah, probes, we can do... There is a way, I've seen us do it in our workshops where you throw everything at it at the same time, and you... No, never mind, I'm thinking about something. It's apples and oranges, never mind. Now, but where I was gonna go with this though, is do we wanna just test the service and deployment now? I mean, we know we'll get the PHP page itself up, even if it doesn't connect to the database. Do we wanna debug any of this and show what this inner loop looks like of iterative development rather than just we solve the entire problem, deploy the operator and go? Okay, I see what you're saying. Also, do we need to create a route? Or am I missing something? Create a service, but not a route yet. Oh, we do need to create a route. You're right about that. So let's do that. How would you do that? Same way have I been doing everything else? Let's see, expose this same service. I'll use a shorthand, since I used a longhand last time. And then service... Let's be getting a shorthand, Brian, and I don't know if he's still on the chat or not, but the first one we discovered that PO is an abbreviation for pod, and I still can't get over how absurd it is that we abbreviate one character away. Yeah, yeah, one character away, yeah. Everything on our other stream is abbreviated pod. But we still can't pronounce kubectl, so yeah. Yeah, yeah, he's out of his mind. Price list, and then... 80, 80. Actually, it's only one port. It's probably gonna be fine. Yeah. OC, get SVC. Oh, I didn't create it. So this is why I have to create it, because it just... You can't dry run a dry run. Okay, yeah, exactly. You can dry run a dry run. Okay, so OC, expose service price list. Dry run-ish, oh yeah, cool. Yeah, you're right. So if I had multiple target ports, I would have to specify a target port. Cool. So here, so I guess I can do this and just write it to roles, templates, routes. All right, so what do we need to change here? Same thing, the data.name, closing quote, and then I can actually just do this. And then everything else, status ingress null, if I just take this guy. I'm going anti-VI here and... I was impressed with your little copy and paste juggle. It's funny, because you can see that kind of stuff. It's always looks super impressive, when all the time you see it fly around the screen like that and stuff up here. And we're still fuzzy on what's gonna happen with the status, but let's just delete it to be safe and remove one. That's right. Yeah, still don't know. Wait and all. Especially in the chat on it too. And I just feel like it's one more variable to kind of screw it over. One more thing to whack. And then, so some of the things I actually forgot to do in some of this, which is actually, the thing I thought about it is, I have name space here, but I don't think I put it on the other ones. Right? Yeah, you're probably right. Uh-oh. Is it here, or is it indented? Indented. It's part of metadata. It is part of metadata. Okay. Cool. Name space, metadata. So I'll look. We all have a minor degree in YAML programming at this point. That's right. I'm minor in YAML. My major was XML, but I'm not in it. Okay, cool. Yeah, in chat, just is what I was thinking too, instead of pasting these days. Yeah. Now, Pacebin's kind of been... But I know, I could say, I mean, at a previous job, it's a different story. At Red Hat, you kind of, you know, you get used to the fact that you can do... I've been here 14 years now. I would be so spectacularly screwed if I went to another job where I couldn't just send stuff wherever I want. Yeah, wherever you want. Yeah, exactly. Yeah, exactly. I have gotten so used to this. Yeah. All right. Cool. So now we have, where is, oh wait, it's Tree for RollsPricelist. So we got deployment, routes, and a service. Yeah, do we need to... I'm super, super rusty with Ansible here. So do we need to put a default in for name and namespace and then just, we're gonna know what's gonna get overridden or... Default in terms of the variables, you mean? The variables. For it to be a quote-unquote valid Ansible role, which I'm not even sure is a concept, as I say that out loud. Does it have to be self-sufficient in the sense that it will entirely be... I mean, you should define defaults, but if you know it, like something's going to be generated automatically for you, it is just a waste of my time. Okay. Okay. I mean, I'm certified in Ansible. I feel like I could say that. You're clearly more... This is why I left that one up to you guys. I stumbled to a question that I didn't know made sense. One thing that would be good to do, actually, is... So if I look at my roles and my templates for the deployment, I do have replicas equals instances. I'm assuming we're gonna pass that in, but we should probably default to something. Yeah, you should default like three or something. Right. So then if you're asking, how to do that, right? It's just an Ansible in the vars, right? The default vars needs to do that. Or three, right? This is three. I mean, if you had a cluster there, if you might as well use a cluster. Make it pretend it actually did it, yeah. So you got three. 30 seconds explaining the difference between vars and defaults. Well, okay. So vars are... You could define anything. Defaults are what is used if a var is not defined. So let's say you're running through Ansible play and you have... You call some variable name, but there's no actual thing behind it. The default is the failsafe there, right? That plugs in something for you so that it can just keep going. Most people use it because they know that they need an exact number of something or they know that by default, you have to have this thing in place and you can overwrite it if necessary based off what environment you're going to kind of thing, right? So a lot of people build a playbook to only work in dev and then have somebody overwrite it if it's going to prod a thing, if that makes sense. Gotcha. So actually, so here, so I just added both these files, right? So whether I have instances three in my vars main or in my defaults main, functionally is the same, right? If I don't, if no one defines it, actually, functionally, it'll give me three instances. But if no one is, but if it's in... So functionally for this... If it is in a sub, if it is in a group var or a host var, it will be overwritten. Yeah, gotcha, gotcha, cool. Right. So best practice, should I move this to the defaults main? It's up to you. Yeah, yeah. Don't over-complicate it. Yeah, yeah, gotcha. Well, functionally it'll just get me, get me where I'm going for this particular, right? But it is a good distinction though that you explained that. Cool. I mean, for this, for this purpose, don't worry about it, but if you have a lot of defaults set, definitely use the defaults, like actually take advantage of that convention. Gotcha. Cool. So do we, do we want to test this? Do we want to boil the ocean? Try to do database or... I was going to say test this. You'd be the deciding vote here. Hell, you're the one typing. So if you want to sit there and try to debug, Yeah. You know, two deployments and most of this. Does the chat have an opinion here? Do we test it? Chat, let's see. The chat's got to catch up to us first, remember? So give them a second. That's right, that's right. So we'll give it a second, have people... If the chat wants to chime in and say, do we live or test it? We'll know here in a minute. Test it. No, default tool. Let's say... Nah. Jafar says default to one. Jafar says let's test it. Jafar says let's test it. Okay. So let's trust Jafar. Jafar has never let me wrong. Jafar has never let me wrong. Okay. Yes, yet to leave me astray. I like how you're saying this, like he's suggesting something wild. He suggests you test it. Like you to test it and you're like, all right. Yeah, yeah.  So I think you brought this up before, Jason. I'll tell you what I do. And you're gonna probably say, this is crazy. But again, remember, operations background. So this is just what I do. What I actually build it, push it and like just run it on a cluster. So I know there's a way in the operator framework, the actual operator SDK to actually run locally, to actually test it locally, before even like building it and pushing it to a cluster. Right? Is that true? Yeah, let's try that. But let me see if I can talk you through it. Now it might, I'm assuming you have everything you would need installed locally, but we'll find out real quick. We'll find out. So the first thing you're gonna wanna do is copywatches.yaml into something called local.yaml. And before you edit local, capture what PWD is. I could have just had correct directory. I don't know why I said it that way. So you're gonna wanna, because we're gonna put that into local. So copy that. Cool, copy buffer, perfect. All right, so edit local.  Your directory slash rolls, that you typed correctly. I'm gonna point out. I think it was rolls and then slash priceless. So before, well, you have priceless there. You only need. Oh, okay, gotcha, gotcha, gotcha. So it's actually, it's actually, oops, like this, right? Yes. Gotcha, gotcha. And then it should have defaulted, I think we call the priceless, was it rolls? Or purseless, yeah, this is directory. So since this is directory, gotcha. So this should be okay. Yes, it is. Cool. So let's keep this up for a second. We've talked about the glue that the SDK is giving us. So I was actually slightly misspoke earlier. I said it's gonna generate the go glue. It doesn't even generate it. That's baked into the base image. But it's going to effectively wire up. This file is the really important part where it wires up our roll on line five with the custom resource that we created, which is gonna be lines two, three, and four. And again, going back to what I said earlier about that API version being a combination namespace and version construct, it's very enumerated here. Group is the first half of that. And then version is literally just called version. So what this is saying is when the operator starts, it's gonna establish in Kubernetes something called a watch. And the watch is gonna be made on this. There's a abbreviation for that stuff. I think it's written out GVK or like as in group version kind, although now that I say that, it sounds awkward to say out loud. So that's even GVK use it. GVK is how I refer to it. Yeah. So it's going to say whenever that particular combination and that particular type is something happens to it. It's created, it's deleted, it's updated. It's going to notify whoever's watching that. And in this case, this operator is gonna be watching it. And then that line five is telling this operator code, run this role. And that role is going to run. And the glue is gonna take pieces out of our priceless object and stick them into the variable names used by Jinja. And it's gonna actually do conversion for us for convention. So the Ansible convention is snake case. That's what the underscores. So my underscore title week. Isn't that called snake? What is snake case? Like my underscore title as compared to camel case, which is lower case and lower case and an uppercase. Okay, okay, okay. We actually had a conversation about this in one of the Twitch. But never, never did the, never did snake case come up. Yeah. Interesting. I couldn't even be wrong on that. But I'm pretty sure this is not called something and I'm gonna Google this. So it does that conversion for us though, where it lets us retain the typical constructs in Kubernetes. Yeah, okay. So the underscores. Yeah, yeah. Lower case, foo underscore bar. Yeah. Lower score, hello world. Ascle. It's a developer-sized thing. And then camel case, yeah. So camel case, snake case, regardless, it keeps the conventions from both. So you don't have to modify your Ansible roles to look awkward to fit into the constructs normally or the conventions normally used in the custom resource. This isn't really the long way of going to that, but yeah, we all learn what snake case is, so victory. So this is important. Now the reason we did this is because the role as it was defaulted will work if we build the image because it's gonna understand the relative path and everything like that. Since we're running outside of the cluster, we have to explicitly say, hey Ansible, this is the directory of the role I want you to execute. So again, 10 minutes to explain something that was effectively a 10 second change, but it's important why we do these things. Yeah, it's like D and D right here. Okay, now let's see how this works. We're gonna try operator SDK, run dash dash local dash dash watches dash file, local.yaml. This sounds- Watch the code base? No, watch is dash file. And then we're gonna point it to local.yaml. Okay. Meanwhile, like my families will be hearing this and they think I'm some kind of like crazy hacker because it sounds like every movie where we're like, run dash dash local, watch is file, and hackers is what I'm thinking of. And hackers, the movie hackers, yeah. That was a great scene by the way. Love you guys. This is why I love working with nerds because you know the exact scene is he's repeating it to Joey and he's typing it in, right on the phone, in the phone booth.  This is how I feel when I sit on airplanes next to people. Yeah, exactly. My wife just, so I've worked from home 14 years now and she's been home since we've had kids. And so she's seen me working before, but a couple of weeks ago I was working on actually operator stuff and I had two terminals side by side. One was a log. So it was just kind of scrolling and one was this type of stuff. And she gives me this look. She goes, does that work? And I was like, yeah, I actually do something.  Yeah, like- Wow. I didn't know what that says. What does that say? Yeah, I know. And like, honestly, out of that log messages I was, you know, looking for one word, but I would never tell her that.  Yeah, I'm like, I'm a genius. All right, hit entry. Let's see how this goes. Oh, it's doing something. I had to become the leader.  This is actually a very good error to hit. We forgot to create the custom resource definition so it can't possibly set up a watch for it. Exit out of here. That's a good reason. It did by itself. It exited by itself. Perfect. It listened to me. It's funny because that was accidental, but I actually do this on purpose when I demo it. So we're trying to talk in terms of this price list and we've created the custom resource definition, but we actually have to get it into the cluster. So before we do that, do an OC get price list. No surprise, this is gonna come back and say error. Server doesn't have resource type. Again, we haven't created it. Let's take a look at what was generated. So open up deploy slash CRD slash, yeah, the CRD ending one. I never type it out. It's have completed. Yeah, exactly. This guy here? Yeah, so it generates a fair basis for us. It always cracks me up when they generate the kind and the plural and stuff like that, the kind we specified. But I said this the last time I did this demo too. I really wanna do a test of like octopus and see how smart its pluralization is. Yeah, I don't think it is very smart. No, I don't think it's very, it just takes whatever you give it, I think. Yeah.  So that way open slash shift slash Kubernetes is going to give us some resource checking. So if we say you can indicate instances and it has to be a number and it's required and we don't do that, then Kub is just gonna initially pitch the resource out and say, hey, I'm asked to fill it out correctly next time. Yep. For now, this is gonna let us put in anything and I'm okay with this for now. That open API schema and then the type object basically means we could put foo equals bar and this is safe because if our operator is not looking at it, we can type in all the junk we want there and we'll just ignore it. So go ahead and do an oc apply dash f on this file and don't hit clear, try to not do the muscle memory, don't hit clear after this. Okay. And I say that because I control L just instances. Yeah, yeah, I know. Well, if you didn't tell me I was gonna do it, go ahead. Cool. So it's gonna create it, now do an oc getPricelist again. And the reason I said to not do the clear is it's at the top of the screen where we got the error initially. It's different now. Now no resource is found and that's good. That's saying open shift now understands talking about the type or talking about the kind of pricelist. And now we can start to manipulate in our typical fashion. So the top is saying I don't know, I don't even know what a pricelist is. The bottom is saying, I know what a pricelist is, you don't have any. Exactly, exactly. Do you have like screen or T-Mux setup on here? T-Mux, my friend. Oops, batch T-Mux command not found. Oh, I have it. New system here for door 32. Yeah, yeah. Just because when I usually demo this, pseudo bang bang. Yes, good man. I saw you using the bang dollar sign earlier. This is the stuff I love about this, like seeing people's UI. It's like this is a power line setup it looks like. Yes, yeah. I'm curious, I suspect you don't have a custom T-Mux then if you just rebuilt this machine. I have mine on my mouse because I'm like compulsive about it. But I love watching how people like to do their thing. So, okay, split it into two panes just because it's going to be simpler. Let's see if I can do it. This is like a fresh install, hold on. Troll, should be B and then hyphen, I think. Is it hyphen? No buffer. Is it hyphen? I remapped mine, so I damned it. I remapped mine too. Okay, hold on, let me grab my T-Mux. Yeah, that's going to be way faster. Yeah, it'll be faster than me. I'm impressed I remember control B because I move mine to control A, so. You know what, I keep mine in control B. Interesting. I also have Windows key A for launching terminals. So I'm just repeatedly banging on it. Okay, so let's do, oops. Sorry, I didn't mean to divert everything with this, but this demo does look better if you have the two panes going up. Or I guess you just do two terminals side by side if you're sharing desktop. The point is we're going to want to watch the logs and do the create at the same time. There we go, okay, now I have, no. I'm going to be even more obnoxious. I'm going to have you do a third pane. So give me another horizontal pane. Which one, the top one or the bottom one? We'll split the bottom one. Split the bottom one? Okay. And do a horizontal, okay. Okay. Yeah, okay, so on this one, let's set up, oh, sorry, the bottom right, let's set up a watch on OC get all. This is where I kind of should have driven because I've just done this kind of demo and I have my reasons for doing this, but first problem, we already have all of the shit deployed because of our dry run that wasn't so dry. So let's clean all that out. Okay, so let's control C out of this. Let's just create a new project. Can we just put this in a new project, right? That's fine. Okay, now name, you need a name. Baby Yoda. Yay. Baby Yoda, all right. Should we do snake case? I don't think it gives a snake case, okay. I don't think it would either. It's super restrictive. Already on project baby Yoda, OC. Okay, so let's do the watch. Nope, someone's dog is happy. Family's home. Okay, oh, gotcha. Go back up to the top pane and let's do that run local command again. Oh wait, that's something else. Okay, so operator SDK, run dash dash. See if I remember this from memory dash local dash dash watches that watches file like that. Dash between watches and file. Yep. Watch is the name says baby Yoda. Okay. That's good. And then it should now actually start up correctly because it has a CRD. Now the one thing I forgot to kind of explain is what we're doing here. So the actual deployment of an operator is as a container. So, and Christian was talking about that typical flow. So we build an image, we push it somewhere, we deploy that image in our cluster, we run our test.  So I need to very quickly see when I make a mistake and just be able to bounce it. What we've done now is we've taken the, we're running the operator effectively as a process outside of the cluster, but it is attached to the cluster. If you look at those log messages, it's looking pretty solid. So what should happen is when we create a custom resource, it's got this watch going. It just happens that this process lives outside of our cluster. So we should see the logs go flying up. It should actually field it. You should see some very ansible looking logs come out. And then we should see our resources start getting created in the bottom right. So if you wanna go to the bottom left for me. Cool, all right, let's do this. There we go. All right, we're actually gonna have to edit it. So VI into deploy slash CRDs slash autocomplete and then type V1 and autocomplete the rest. There you go. And now size, this was just generated by default by the project. Yeah, we've changed this, right? Yeah, we chose to name it instances. So let's just do one just for simplicity. So again, take a look. This is really the important part of this whole thing that API version and kind, we are now talking not in terms of all the stuff we did in the first hour of deployments and services and routes. This is what the end user is gonna do. They're gonna create a price list resource and they're gonna talk just in terms of those fields. So instances applies to a price list. So that's all they care about. They don't have to know, oh, this means that the actual PHP deployment is compared to the MySQL part or is this using the services? They don't care. They know that they're saying, I want a price list application. I want it to be run off of one instance. And again, they stubbed out, they being the Operator SDK, stubbed out an example for us that we edited. We could have hand jam this ourselves. It's just simpler to use an existing one and build off of it. Cool. We can exit out of here and do an OC apply on this. Oh, you see that? It's going. We are seeing some errors up top. Reconcile error. You can't reconcile. Yeah, I'm wondering if you don't have all of the libraries installed because this is what bit me to. I had to pip install OpenShift before it ran. Do you have actually, I probably should have asked this because you said it's a new install. Do you even have Ansible running locally? Yeah, like what do you have on the box? We have Ansible. Okay. It's probably just you need to install the actual k8s modules. If we dug through that, I bet you that's what it's telling us. So it says process, so it's a pointer, controller, worker. No such file or directory in the middle. I'm pretty sure this is the message because we don't have the k8s modules. For the Python. So again, remember that we're running this outside of an image. So the image itself, we build it is gonna have the k8s module. Gonna have all, yeah. So I don't, since it's, that's your question. Your local machine needs them, yeah. I wasn't sure how far down this much, you know, you've kind of dorked with in the past. I just pip installed OpenShift and got it. You guys probably know a better way. That's gonna pip install OpenShift. You're gonna have to sudo it to install that love vote. Yeah, there we go. The sudo, sudo or sudo? I sudo. It's context specific for me, sudo, sudo, yeah. Just depends. Pip install, cool. Try bouncing the top process and see what happens. Okay. Before, actually don't start it, don't start it yet. Don't start it yet, I'll just do it up. And then go back to the bottom left then and do an oc get price list because I'll bet you that resource still exists. Ah, it created it, yeah. Right, now so the way I've done the same on the past two is without even running the operator, I'll create this and you show that, cool, we can create a resource of a defined type. Nothing's gonna happen because there's no watches, but that's perfectly valid. So at this point, we can just- Yeah, because we created the CRD. We have the controller, right? We have- Be careful, what we're talking about is not the controller at all. Yeah, yeah, no, no. The definition? Yeah, we have the definition, we don't have the controller, yep. Right, and technically speaking, the controller is not needed, it's just not gonna do anything. Yeah, it just doesn't, you get this at least. Yeah, so cool, we've got resources out there. Yeah, yeah, resources, but you don't have anything controlling it, yeah. Could use it as a really, really shitty key value store. There we go, yeah, that's right. We're very heavy key value store, right? Yeah, heavy, that's right. I set up Kubernetes as a distributed key value store. Yeah, it is. Perfect application for Kubernetes. Yeah, exactly. So I'm gonna delete this first, yeah. Now this is another thing where, you don't technically need the operator running to delete them. The way the parent-child relationship is gonna work, anything created by the price list is gonna be owned by the parent resource. So that would have trickled down and deleted all of our deployments and stuff like that had we actually gotten some. All right, so run the operator. Now while that's starting up, I will mention that had we not deleted it, we very likely would have seen it get resolved anyway. This would wake up and then the watch would immediately get told, hey, we have a custom resource you're gonna care about and then it would start running the Ansible and very likely would have brought us back to a working situation. Since we're still in this debugging mode, it was one more headache I didn't wanna deal with and it gave me that kind of tangent to talk about the custom resource existing outside the controller. But yeah, try creating it again. Let's see what happens. Uh, no, you could apply right, there you go. Oh, there's something. We're still seeing issues there. In the interest of the stream, it might be better to just... Oh, it says open. Okay, I'm sorry. There are two more things we need to do. Yeah, yeah. Ansible would want there. There's AnsibleRunner and AnsibleRunner HTTP. It's still probably faster than building the image, but if you just wanna go move on to the image route, but for Helm, this is way simpler, where you don't need even Helm running locally for or installed locally. For Ansible, there's a couple of other requirements. It's Ansible, it's the Kate's module, and then there are these other two pieces called AnsibleRunner and AnsibleRunner HTTP, which are not, again, it's just pip commands, I'm pretty sure. It's your call, how you wanna proceed. If you just wanna continue down to our, you know, this route, because this looks really cool when she get it running or if you just wanna move on to the image. I've never done it this way. So though, I think it'd be cool just to keep going just cause I never have it this way. Let's do this. I've done it the other way, but yeah. Go up to the top, close that out. I'm sorry, just kill this process. Do a pip search AnsibleRunner. Do you want me to page up here? Yeah, it might have been at the very top because it was a direct match. Yeah, that's it. Okay, so it's the first one. So let's do pip install AnsibleRunner and then explicitly say after that AnsibleRunner-Http. If I remember correctly, the last time I did this, that second one came for free, but it doesn't hurt to specify it. AnsibleRunner-Http? Yep. So again, this is to be super clear about this. This is just because we're running it. Got a GCC error. Probably need the Python header. It's Python-dev, Python3-dev, DNF install it. No, you got to DNF install it. This is the SN install. Is it dev or developers? I think it's dev or it's develop. We'll see. We will see. Oh, there it goes. Look at that. Okay, it's doing stuff. All right, back to our pip. There we go. Well, let's read this time. Okay, so again, this is all just because we're running it locally and it's how it manages to wire everything up and run the Ansible and stuff like that. You know, it feels a little wonky because we're doing this like error, fix it, error, fix it. Once you get this running, it's a much smoother process. Yeah. I would say delete the custom resource again like we did last time just so it's, we can see the separation between the operator starting and actually kicking in and doing something. There we go. So watch this again. Skipping leader election. Okay. All right. It's started. Okay. So then here we do create. No, apply. Oh, that's right. It's gone. Go see, apply. What is your buffer history? Like six. You get like two. I don't know why it's gone. Hold on. Apply. Oh, okay. There it is. Press this. It's okay. There it is. Okay. That's what we wanna see. Yeah. Much better. We actually see Ansible now. We see Ansible. Cool. And then we should see, assuming we have our... Ansible exiting successfully. Okay. I like that. So the fact that we don't actually see any resources created is interesting though because now this is telling me we have an issue with the actual playbook itself. The playbook itself, correct. Yes. Right. Which is why one of the other benefits of doing this, we have these logs here and just bouncing it is super fast at this point. Scroll up to the Ansible output itself. That's the wrong, there we go. Yeah. Control.  Yeah. That's just says log runner, Ansible runner exiting successfully. Did we... Oh, we have the templates. Don't we need some piece that tasks? Yeah. We actually... Yeah. You actually have to put something in time. We actually have me to actually... That would be good. So by the way... And this is the beauty of though, of running it. Yeah. So this is funny because everyone's like, well, it's not gonna work because you have absolutely no tasks. The task is empty. So we find they were successful. Of course it's successful. So it's so successful because we didn't... Because there was not absolutely no tasks. You didn't even know that's a file. Yeah, yeah, exactly, yeah. So the task is, the task should be easy. So here we just do name, a deploying, just make it easy. And this, we're doing the kates module. And in the kates module, we're doing a state equals present. And then a definition. Actually, let's do... Then you got smack in the middle. Yeah, right here, this guy. So definition, look up template, blah, blah, blah, blah, blah, blah, yeah, can you smack me? So it is like that, okay. And then the template's called roles. That was the point, I think. Oh, there was two, there was also service. Oh, end route, Jesus. Okay, so then this here is deployed, I am. All right. No, you're also going to want the service and the route. Yeah, do we want to... No, you're actually right. Do you want to deploy, burn the ocean or? Exactly, this is why we went down the first place. So this is called Tmux LS. So Tmux Attach, for those who don't use Tmux. I don't need to do T0, but you can do... You could also done dash B dash C for creating a new window within Tmux. Oh, okay, yeah, yeah. And then shift between them. But I don't know the keys to go between them because I have to shift left and right. There's way too much Tmux for me. Oh, it's so good. I know. When you fly around on it though, you look badass. I know, yeah, badass. There we go, it's control B and it's for the next, right? And that's right, that's right. Okay, so delete the old custom resource. I think we're missing another step. But let's just see here, Oseed delete, delete. Let's see if we run to it. And then this here is local. What's cool is that when you set it up this way, it's almost as fast as just writing and debugging the role itself. So now... When you're not doing the image build, you have the logs available right here. So I can already tell, so the way I used to build it before, I could already tell you, even like stumbling through this, I'm actually gonna use it this method now because it saves me from having to build it, push it to Quay, and then deploying that into a new versus here, I can just like run it locally and just do it right. Instead of trying to... No, it's just for this required. Minimum more difficult than just straight up running Ansible against your role and testing it that way. Apply. Ansible, that's what we wanna see. Failed, that's good. Keep running. Keep running to you. It's funny, because I try to tell my students that too.  Failed is actually a good thing. I mean, we're at a different error now. Yeah, it's a different error. That means you're progressing. It's progress. This is gonna fail because metadata is undefined though. Yeah, because why isn't that created yet? Yeah, you would think the run, because this tells me that there's no, the downward API isn't coming in for whatever reason. Right, yeah. Test me, like three, column three, but maybe elsewhere. Do we need to wire these up somehow in VARs? I don't think you're wondering or passing it. Oh, you know what? So you might not need the namespace, the metadata dot. So I'm looking at my example right now and I just use the curly brackets namespace. I don't actually have metadata in front of it. See, what do I have here? So what's funnily enough, so that's actually in my notes here, I have metadata dot, metadata dot name. That's what someone in chat's saying too, metadata dot name. So this, okay. Well, it's not working the other way. Let's try it that way. That's right. And now that we're heading this point, I'm super glad we decided to invest the time in getting it running locally instead of building it. Yeah. Then we're good in. Deploy, no, it's not a deploy, it's in roles, right? Roles, price list, templates, and then metadata is just meta, data, change that to meta. There's a VI way to do this, but it will actually, it would do what I just did for now, change the ones I don't want. Okay, next. And then dot, dot, dot, next, dot, dot, dot, dot. Okay. See, if I was doing this the way I used to do this, I would have to rebuild this and push it up to Quay. But here I could just like test locally. Yeah, you've converted me here. This will be interesting because we didn't delete the custom resources. Yeah, yeah, I was just saying about that. No, this should kick in, it should almost immediately start running it. So we've got it, start running it, look in. Different error. Yeah. It's different, keep going. So what does this say here? It says error. Invalid name and example dash price, slash dash price. Is there like a light restriction on it? Typo? No. Right away you go with a typo, man. You make one mistake. You make one mistake. It's like calling a, So it's trying to get. Trying to get Zaplogger. This is invalid spec template metadata labels, invalid value, invalid value map string. So like it does not match template. Demendation thing? That's what I'm thinking. Pull up the, pull up the templates. Hopefully it'll just be very obvious we'll look at it. It's just a template, right? Oh, do you want to make a template? App, look at app. Something's going on in there. App, so label is metadata priceless. So whatever the name is dash priceless. So example dash priceless dash priceless, what would it be called? Go back to the error. Can you go back to the error? Yep. This is Tmux in action, man. Yeah. Yeah, field value, value invalid. Deployment dot app's example priceless priceless is invalid spec template metadata labels, invalid value map string. Yeah, Ryan's saying maybe. App. It's the hyphens. Priceless. Yeah. I don't know if it's the hyphens or if it's just the sheer length of it. Maybe. It could be either one. We can kind of fix this quickly. So go delete the custom resource. Yeah, this is the CR. And then let's just change the name of the CR of the actual resource created. Because that's super wordy anyway. So yeah. Delete. And then. That's your farce thinking like priceless priceless is just too much anyway. Like it might not even be able to support that. Yeah. So we'll, I mean, we'll make the whole custom resource V1. And then just change the name to EX. Or wait, what are we doing here? Boba. Hot. Hot, hot, hot. That's nice and short. No, no. Hot. All right. Hot. Battle of hot. Okay. So here it's apply. Yes. Okay. So here, oops. I need to come up here. More error. Okay. So what's the complaint about now? Selector does not match template labels field spec template metadata labels and possible entity. And valid label. That's such an engineer way of saying it. So it says maps string. So in my, is this. It feels like an indentation issue, but. It may be. Or quoting. Maybe the selector happens. Maybe the selector app label doesn't match the metadata. Labels app meta dot name. That's priceless. Priceless. Check the other things besides deployment though. Cause. Oh no, that's right. We're only doing deployments. We're only, yeah. We're only, we're not, we're not boiling oceans yet. Only rivers.  This is when I wish I had a core. It's a little bit of nearby. The creation timestamp is null. Maybe just delete that maybe. Yeah. I would delete that. That's unnecessary. So let me delete that as well up here. Creation timestamp. Go back. Maybe it's simple as just that. Do you want me to go back to some things? Yeah. Yeah. Go back to the error real quick. Cause I. Match labels is not templated. According to somebody in chat. So what you're match labels dot app. Maybe a selector app label doesn't match the metadata. If it's that guys, I'll yell at you. It's match late. Hold on. What? Oh, I see it. Yeah. I see it. I see it now. Is this guy right here? Good. Hi guys. Yeah. Good. Hi. Yep. Good. Hi. Thank you. There we go. Thank you. This is why this is why the Twitch thing is cool. Right. Yeah. So, okay. So I should be able to. Oops. You know what is and just to continue with our Christian and the bus, it's because Chris and I were so worried about him mistyping. That's right. Yeah, exactly. We weren't looking at the forest through the trees. Yes. Yeah. We're so focused. We're so focused on a word and we couldn't realize the whole file. Okay. And this is local. Okay. Yeah. Oops. I don't want that. I want you to do control B down apply. Okay. All right, everyone. You guys ready? Yep. Hold on to your boots.  It's doing something. There it is. All right. Look at that. Here we go. Success. We got success. I love it. All right. All right. We couldn't have done it without the audience. All right. It's true. Thank you very much. Quite literally. Yeah. Quite literally. We would have been here for hours. It's like, are you sure? It was inspiring audience participation because this is a Twitch channel. After all, we want this interactivity. That's right. We threw a few intentional errors there and make sure. Yeah. Yeah. Obviously. Is that what we did? Yeah. Yeah. Yeah. We threw some of these in there to make you guys feel. I was acting. Acting. Okay. Cool. All right. Next. What's up? So at this point. So this is actually really cool. I'm actually going to start. I'm using this. Doing it locally. Because. The idea is now I can do. Go back.  Back to the other pain.  Delete the resource. It should clean everything up. And I was trying to say this before, and I feel like I stumbled over my explanation. There is. A resource called priceless or of type priceless. And it is the parent of that pod deployment and replica set that were created by it. So Kubernetes understands how to delete children like that. So we delete the parent. It's going to go and do all of our garbage collection for us. There are ways to interrupt that. If for some reason the operator needed to do some kind of. Clean up before. Yeah. I don't know that you can do it in the Ansible world. I know you can definitely do it in the go operators. Now that I say that you might be able to even do it in the Ansible. If you set a finalizer on it, which is ultimately how you do it. Yeah. But it's cool though. It's, it's another. I shouldn't say benefit, but a nice side effect of doing it in this broken out model is. Even if you do exactly what you did and accidentally kill that first, it's fine. You can still very easily clean up after it by just killing the resource. Cool. All right. So while you wire in the service and route, I'm going to take a quick bio break. So keep typing. There you go. Cool. So then here I'm going to do. Where was I? I'm not handlers price list. Tasks. Tasks. Yeah. So the, the other one. You've got a deployment, a service and. I forget the other one. Yeah. That's right. What's going to be interesting is the route, but we'll. Oh, which. Price list. Yeah. Okay. I just, I just wanted to know. Okay. Yeah. You're going too fast. Yeah. So here I got this guy here. And then. Yeah. So I want. So this is a service. I'll call this service. Here is route. There you go. Cool. That's the right order. Service present. Yeah. So now I, and now I'm, I'm starting to. See the power, right? We're running this locally. Yes. Because anytime I iterate, I don't have to rebuild it, rebuild it, rebuild it. I can just run it. Right. And to reiterate to folks, what is the flag to do it locally? I think it's dash, dash local. It's the run command in general. And then you have to put dash, dash local. I'm not sure what happens if you don't, I don't think I've ever used the command otherwise. You can do this for helm and go as well. And actually, you don't even have to say type or anything like that. And like I said, the helmet is actually a little bit smoother because you don't need these extra libraries locally. Right. And it just kicks in. Yeah. So we should. So instead of. Deploy CRDs, this has some fun with this. We shouldn't, instead of hot, we should do Alderaan, right? So when we delete it, it's like the death star. This will Alderaan Alderaan like that. No, there's two Rs in it or something like that. Let me double check. Hold the audience to A is A L D E R A A N, but Chris is going to get credit for. Okay. So I took some credit. Yeah. Chris, Chris gets it for knowing that there was some kind of duplicate. Oh, okay. Got you. Got you. Is A L. D E R.  I knew there was a double something. Alderaan. Okay. So when we delete it, it's like the best start getting. That's right. You can get Keshik and just type in a whole bunch of Y's and you'll probably get it closer, right? Yes. And the fact that I caught that reference proves how nerdy I am. I like this group. This is a really funny group for nerdy stuff. All right. So here we go. We got, let's do something. So much creation. There's a deployment. Deployment. There's the service. Service. So now you can see why I like this team.  That's very, very nice. And then there's one more thing we added, right? The route. The route. So you have to scroll down in the other window and O.C. get all. Oh, they don't know they don't. You're right. How would you get the route? Get all comma route. You can do both at the same time. Oh, like that. Yep. Cool. I mean, if you really wanted to, you could do comma price list and show that in here as well. Although I'm a fan of these days of just doing the specific ones I want. Like I don't care about the replica set. Yeah. So you can do like O.C. Yes. Yeah. And. Price list. Or price list. Yeah. I mean, there's nothing terribly interesting about showing the price list. You can do that off in the left side, but it's kind of cool that you could get them all in. So you can do O.C. Yeah. Well, it's all the wrong there. Yeah. So. So I can actually technically go. Oh man, this is, this is ugly. O.C. O.C. Let me go in another window. O.C. get crowds. Oh, that copy. That's the one problem using T-Mux. Yeah. But I think it's, if it goes to two lines, copy is useless. Oh yeah. There we go. All right. We got the route, we got the route there. We got, no, we didn't set up the database. We knew database. So yeah. Mariah is not singing. But there are, there's a couple of things that are worth pointing out at this point. If you go back to your terminal and just show the custom resource. Yeah. And I know this has taken us an hour and a half is to get to, you know, I don't know, I don't know how to type in to get that was, I didn't stretch that out long enough. The price list. Oh, V1 tab. I don't know. Now I see where you're going. Yeah. So all the users have to type this and they got all of those resources. What's even cooler is once we update the operator for the, uh, database, that's going to come for free underneath this as well. Yeah. And you can take that to the next level in terms of upgrading that as well. So, you know, I'm going to go back to the, you know, I'm going to go back to the, where new version of the operator is going to understand how to resolve it. Now we didn't get to see a lot of that reconcile loop because the Ansible. Operator. The Ansible operator functionality in the SDK did it for us. And in fact, it gets really cool. If you were to go, do we still have one running? We have. One in terms of what. Sorry. This. Did you delete the. Pricelist. Oh yeah. That's right. Let's see that it. Price list. In fact, exit out of this.  Nope. Sorry. Back into your other pain. Ah, gotcha. Gotcha. So bottom right. Watch. Get pods. If I spell it right. Oh yeah. Okay. Now on the left side OC edit price list. And I'm going to have you increment that instances up to two. And we should see, uh, the operator start to spaz out again. And we'll see here. We'll run. Say, say three. There you go. Go bigger. Go home. And boom. The operator gets notified. So. That reconcile loop comes in. Yeah, exactly. So it's not just when a custom resource is created. It's any kind of change to it. And that means your operator has to be smart enough. Um, number one, it's not going to be important because if every time it got a reconcile request, it goes to create a new pod that would get out of control real fast. Um, but that item potency we get for free out of Ansible here because Ansible, if I were to just run this for multiple times is not going to keep spawning them. Correct.  But that means if we do do one of these for a go operator, you're going to see me write code that says, okay, make sure that there's a deployment for this. Cool. It's there. Now let's make sure that configuration is consistent with what was in the CR. Because it's all declarative. We're not. Inside of the controller and inside of the operator, you're not seeing operations that say added resource, deleted resource, updated resource. It's just saying, here it is. Here it is. Okay. Yeah. And the operator is them looking at the reality of the situation, the desired situation and resolving the two. Beauty of the case modules is that they do that for us. So we didn't add any update logic in, but we effectively got it for free as evidenced by the fact that we now have three pods running. Because all we had to do is update the configuration. Well, we can, we can also. Sorry, Chris. I was going to say we can go, we can actually attack this the other way too. We can also see edit deployment. Right. And I say in the deployment. Let's say I want. By replicas. Right. It'll give me five replicas, but then the control loop here is like, no, it's going to kill it. Yeah. Yeah. It kills it.  The operator says three. So I'm going to keep it at three, but I think it's very important to point out like how quickly. Yeah. I think the reconciled loop picked it up. Yeah. Like even on a busier cluster, it's going to happen very fast. Like this is using Kubernetes. Kubernetes native eventing to drive. Operator like triggering. So you'd go in and you change that deployment file. It's going to be like, yep, here you go. And then it's going to be like, nope, you didn't say you wanted five. You want three. And it's going to back it right on down. Yeah. This is. And also this is one of the things I have to explain though. From people going from version three to version four, they're like, well I can't scale the router anymore. It's like, well, we, there's this different paradigm now we, we have this, we have operators, right? Like you're no longer controlling it. Be a deployment. You're having the operator. Control it for you. So that's, this is kind of like, kind of what I wanted to show about editing the deployment. You can edit it in deployment,