Hey, we are recording. What does that mean? It means that we have a recording at the end of the video session, and what will happen as a consequence is you will be able to watch it, the recorded sessions that we have. I'm also doing something which is a continuation of our discussion for the last time. We were talking about live streaming from a streaming source, and so today, this session, my desktop and whatever I'm sharing, that thing is streaming to you through Zoom, but it is also streaming right now through custom streaming service that I have built on this site here. So you can see that on this staging site, this is not the main site, this is a secondary site that I have for testing, and I'm testing it right there, and what you will see now here is this button, play live stream, and that should show what you see right now, right live. So it has a 10 second delay, 10 to 15 seconds, but this is just a quick completion of the demo the other day that I said that I will show you a live stream, which is, I think that live has stopped that stream, that is kind of distracting for me. So you can see the stream, it is happening. Our own Zoom conference right now, if you speak, I speak, anybody speaks, that stream is going to go live, right here. It will just appear right in that segment here that you see already. So that's where the stream is playing live on a staging site. This is not the main site because I'm still testing, but that custom streaming is happening. Having said that, that's about the streaming thing. What did we discuss the last time we were, if you, I'm just trying to remember and if you can remind my, refresh my memory, so what did we discuss the last time? I want to continue forward with that and I have a new set of exercises built around using Kubernetes end to end with custom storage that you may have to have data persistence and all those things that I have been discussing, I have ready exercises for that. So I'll be showing you, those are new exercises, they're not published yet on the website. Even today, they're not there yet, they are in my desktop. I will be publishing them soon as soon as I'm ready with making sure that they are readable properly. Currently, they are not, they're just in Git repositories. But what I'm going to do right now quickly is to look at what did we discuss the last time. So here, if you remember, we were talking about, didn't I log in already, log in, am I logged in? And so that takes me to this site here in cloud and go to the segment on the cloud segment where we have, let's begin and then go to the recordings, which will tell me what did we discuss the last time and the discussions were here. So we were talking about live streaming media, we have a code implemented in this gist that you will see the code, Lyric Broadcaster, FFmpeg Broadcaster, and I just showed you this Zoom meeting streaming to the restreamer using Nginx RTMP. That was another live piece that I did not succeed the other day, but now it is working right now. You can see that our Zoom is streaming. And you can scale that RTMP using CDN. We discussed that. We also discussed a bunch of Terraform example exercises and we created our VPC setup using Terraform. So that we did not actually finish the exercise the last time. So what I have done is made sure that you can actually complete that entire exercise in 10 minutes or less. If you just walk through the steps, the steps are written down here somewhere, I'll guide you exactly where they are. So you will know what I'm talking about. But at this moment, what I'm going to do is get to that point where we can actually finish that exercise end to end in about 10 minutes or so. And that's what I'm planning to do right now. So I'm going to clear my ink, identify the exact location where that exercise is written down, which is called, I label it N-tier exercise, that's the name I choose. And so you have to go search for it here, N-tier, that should bring it up. That is the exercise. And here you will see that the source code is at that location and that you will see that this exercise creates basically the same that we did manually a while ago, a while ago, as in more than a few weeks ago, you did this entire exercise manually. And that's what that exercise is. And so what I have done in the next page is that I have created, I think a video somewhere. Where is that video? I think that's somewhere else. So I did not find it in the N-tier discussion, maybe there is another one. And maybe there is a duplicate, accidental duplicate might happen. So I'm going to go to that listing and find out there is a video that I have put, but you can watch it later. I'm not asking you to watch the video right now. What I'm going to look at is the place where it is actually stored. Is it this one? Probably. Probably this one. Yes. So I'm going to grab a link and paste it for you in Slack chat so you have it. That video walks us through the entire exercise so you can actually do it, but I'll do it live again. It should finish in 10 minutes. Slack chat is now coming up with that link to that same exercise that I'm referring to and that we did not succeed the last time we did. That is because of, I think some Docker hub, Docker pool did not go through for some reason that I did not understand at that time. And then I studied that reason as to why it did not actually finish. And we've turned out that there is actually an issue going on. So we can see what that issue is. And here I updated latest commits. You can see some history here. And the issue is described in my history, in my log. You could see that in my commit log, you should see that message. So if you go to Git on that particular folder, which I think is called ntier, so you can see it. And you can see git log here to tell you the reason why it got stuck. So there was this issue, number 591. You can see the issue itself, which is actually a problem across the board. So latest packages of Docker for Linux are broken for that latest version. That's the issue. It is still an open issue. And so that is what we actually ran into. And I thought something else was going on, but apparently this was the issue. It started 28 days ago. And the latest package of Ubuntu trustee, this version of Docker, the latest version is broken. And so that's a problem. And it is still an open problem. The issue is not resolved yet. So what I have done is I've worked around it. So you will see the workaround now. It is already implemented. All we need to do is just run the exercise. What does that mean? Well, we'll clone the folder that I have in Slack chat, which is that folder that I was referring to here. And you go to the main master branch, which is where you clone it from here. And then you use HTTPS to clone. And then I have cloned it already here. So that's my clone. So git status, and I think it's status. And there is some terraform variables modified. That stores my password, by the way, by the secret key access key. And so that's the modification. Other than that, there is no other modification. You can see it. I can pull from git. It's already up to date, which means I can proceed through running this entire exercise very, very quickly. What does that really entail? So it means that you have to begin with the step here, say terraform initialize. So it initializes terraform. But you know what? You need to go inside one step. This folder. And that's where you initialize terraform. The terraform folder is that folder. So you initialize that folder, and it will initialize terraform in that folder. As a consequence, you will see this folder,.terraform created. That folder contains the plugins needed from whichever cloud you're operating on using this package. And this package currently operates on the Amazon cloud. So here is your Amazon cloud, where you will see that I'm going to show you that I have nothing. And then in about five minutes or so, you will have everything created through terraform. That's what you will see, or you expect to see at least, as we run this exercise. So running it is fairly simple. I think the big thing in terraform is to understand what's going to happen. And so that's the reason why I spent that time the other day to help you understand what is going on in that exercise. So if you go back to that video here, you will see that the end result looks like this picture. So if you go see the picture itself, this is what we are going to produce, by the way, create. And so the picture shows in that. Let's go make it bigger. And here are the end result. So as you already seen that, this is the end result mapped out item by item inside. So here you see there is a load balancer, there is a public subnet, there is a private subnet, there are two machines here. There is one machine here, which is going to be our NAT box. This is also going to be our open VPN box. And this is our company, and our company employees can just magically appear wherever they feel like. They can appear here. They can appear here or they can appear on any of the machines here or here or wherever you have any basically inside your VPC. Employees from your company can come in. Other people like this guy cannot go in, except unless they go through this port number 80 or port number 443. In that case, they're allowed to go and they can see what you expose to them. So that's the scenario from a user's perspective, outside user can go only this direction. Company employees can go anywhere they want. And that scenario is implemented through open VPN running on the NAT box. And here is two boxes running, both running Docker and here Docker. And inside Docker, there will be an app running. And here this app running. And this load balancer will actually balance the load between the load balancer here and that app and that app. That's what we want to balance in between the two. There are of course, security groups, there is a security group for NAT, security group for web, security group default, which allows any to any communication within the VPC. And I am just cross checking whether I'm recording or not. Yes, I'm recording. And so that's the picture we are able to create. We are tempted the last time, we got stuck at the very last moment because of that issue that I later on discovered. We have addressed that issue by working around it. It is still an open issue. Having said and discussed these ideas, I will now show you the idea, Terraform. So Terraform, and we say plan, meaning I think we have to clean up two files here. The two files that need to be cleaned out are the state files. They are not a part of the repository, they are get created. So I'm going to remove the two state files, which is Terraform.tfstate and that will remove them out. You still see the git status is still clean, except my security access credentials for Amazon Cloud are stored in that tfrs variable file. And that's what the modification is, which is what the secret and access key from Amazon Cloud is what I'm using right now. So you will see that I'll repeat this kind of exercise using Terraform with another cloud also. You will see that happen. As soon as I finish this exercise, you will see that I will run a similar exercise, but with a different cloud, with a different concept, different topic. And so what we'll now see is, see if we can get to the Amazon Cloud somewhere. Where is that? Here and here I sign in, I think too late. So I'm going to put in the token again, and then I sign in. And so that takes me to the East. I think I'm using West1. So here is California, West1, and that's where I have no VPC, except the default one, which I still have the default VPC here, but then there is no other VPC. Having said, I will say Terraform, can you please tell me what the plan is going to be? And so Terraform is going to compare what you have in the cloud, basically nothing with what you want to have is what your design is, there are 16 things to add and nothing here. The difference is all add, add, add, add, add 16 items to add, nothing to change, nothing to destroy. So when I say Terraform, please apply. And then I apply, you will see that it will actually go and apply. And I will also clear my ink and describe the concept one more time quickly, because I'll open up that atom editor and inspect the folder. You will see the same thing that you saw before, and there's this hold folder where I was hiding things in there, like these files, the TF files, I've tried to move them out of Terraform's view, hiding them in the hold area. I'm not hiding anything right now, so not holding anything. The whole thing, including the bin folder and the cloud config YAML, all of these are open and accessible to Terraform. The hold folder is not accessible, so it doesn't see that folder. That's why when you hide these files away, it just disappears and so Terraform doesn't know what to do. But now everything is outside the hold area. So everything is visible to Terraform, which means Terraform will run and do 16 things. And here are the 16 things listed. And so I'll just say Terraform, apply. So it will go and do it. And you will see the result in a few minutes. And so this time, we have worked around the issue that is currently going on, which is this one. It is broken. The whole package of Docker is broken on Ubuntu. And so that has been worked around. You can read the workaround, how exactly I did the workaround by looking at the last two commits here. And so those two commits actually tell you exactly what did I do to address that workaround. And then I also updated one more to just actually solve the problem. That actual solution is actually not using the, basically I upgraded the OS. And so that OS upgrade here before this line was trustee. And now I'm using Janiel. So both of these work with trustee, this one, and with Janiel, that one, both these tags will work. You can go to whichever tag you like. Both are functional, this one and this one. But this one was broken because of the issue here that you saw in the other tab. And so that's the idea. You are now looking at Terraform constructing the resources. You're looking at Terraform actually instantiating a NAT device. And that NAT device is not a NAT yet. It is going to become a NAT. It is going to become a NAT because of these two lines we have in our atom editor. Where is the atom editor? That one. You will see that the NAT device here becomes a NAT because of these two lines. And they are line number 20 and 21. It converts the box into a NAT. It makes a NAT out of it. And then it installs Docker and installs OpenVPN and a bunch of other things. We'll see what it does. And we'll actually use OpenVPN now once it gets ready. And that OpenVPN thing is going to allow your employees in your company, like you and your friends and colleagues, they from your corporation, like from here, they can visit anything they want within the cloud, but not this guy. That's what you will see now once the VPN gets set up. You probably have used VPN, but not OpenVPN. So this is open source VPN, slightly different and slightly better. And I am biased, but yeah, I am supposed to be biased with open source because I love it. So open source is, by the way, your property. It is my property. It is our property. It is community property. So that's why I am biased. It is your property as well, just like it is mine. It is open. And so that's the idea here. It's finished. So this thing finished. It created 16 things that we wanted. And now we have the design implemented. See that design on the right side implemented here and on the left side. You will see that now when I refresh, there's a VPC going to be showing up, automated. And everything else that we discussed, 16 items. You can count them like literally one, two, three, four, like that. All these labels are the 16 things. And like that. You can count them. They're exactly... By the way, one more. So there are exactly 16 things. This is the VPC itself. Exactly 16 things that are called out by Terraform that it has created. So that illustration that we have on the right is implemented here. This is the best way to actually craft out the Mac, basically capture the state of the cloud. So whatever you want to have, you capture the state in a folder like here, Terraform folder, and then you play. You apply. When you apply the state, it creates the cloud for you. Simply speaking, that's what it did. Now let's go see the cloud. What have we actually constructed? We'll first see it from the user's point of view, like this guy. The outside user. What do you see? And so it sees the load balancer. And so let's go see that load balancer. What does the user see? There is a chat question somewhere in... No, it's a bounce. So I'm going to bounce happening. What's happening here? Bounces. Okay. Not important. So we can ignore that. So something... I thought you may be hitting some issues. So that channel actually is a channel for me to get notifications of things not behaving properly or things going wrong. I get notified through those channels, which is my Slack channel of getting reports. That's why I pay attention to that because it may be causing some difficult time for you. So that's the reason why I pay attention to Slack, which is my way of receiving notifications from machines, as well as people. And so here, no, not that. Let's go see the output from the terminal here. You see that this ELB host name has been given to us right there. It also gave us a NAT IP address. Like that NAT IP address, we have that. And we also have this big long name and we have two IP addresses also. So let's go understand these details in a clear fashion so that we understand what we actually created. So what I'll do is copy the details here and put that in editor so we can dump them and make it big right there. So now we wanted to get two boxes on the public, sorry, on the private subnet. Here are the two boxes. We wanted to get a load balancer. So we got that load balancer here. And then we have a NAT IP also, which is on the public subnet. So this is on the public. This is on the private and these two boxes, app servers, zero and one. Public has a NAT device with a public IP address and a load balancer DNS name available to us. So with that in our hand, we should be able to go to that load balancer and see something useful right there. First thing we'd like to see is see if the load balancer service is functional. For that, we need to go to the front page and see where is our load balancer. It is inside EC2. So go inside EC2, that's where you will find load balancer hiding somewhere on the left side. Here is your load balancer right there. And there you will find that the load balancer is actually in service. There are two devices, both of them in service. And we'll go see the description and it is giving us the DNS name, which is the same we got from our command line. This name that we have, the A record, we will now copy it and paste it in Slack. And so here it comes. So you should be able to click on it and see what the applications are showing. We have two apps, by the way, that we have two containers running, two boxes running same app. It's not two apps, the same app twice. It's load balancing. And so that's what I want to show you, which is the app is running inside Docker. Inside there is an app. So there is a Docker container running and then there is app inside that Docker container. So this is what you will see when you visit here. That's the load balancing action. And now please visit that site and tell me what you see there. And so we'll now go inside those machines and examine and inspect, is that architecture that we put together through Terraform is exactly what we received or is something different? Is there a deviation from what we actually expected? That's what we'll go and check. But first, hit the site, see what you see. I'm also going to hit it. I'm going to hit the load balancer that we have in Slack chat. And so here it is. And we see, welcome to NGINX. Beautiful. It worked. That's what we expected. So now we will see how much time it took, like 10 minutes maybe max to run the actual exercise very fast because the issue is taken care of. Terraform works beautifully. I mean, I cannot stop talking about it. I think it is the best tool available today. It might change tomorrow, who knows, but today it is the best tool to create whatever you want in the cloud or even in your, as I said, grandmother's laptop. You can make it to work with any machine or machine in the garage or whatever you want. Just mostly people use it in the cloud, but it doesn't have to be a cloud. It can be anything. Dominant usage of course is in the cloud. So we now want to see these devices, right? Now we'll inspect what have we got. So there, you know that we have our public subnet, reachable. So I am sitting here and we don't have the open VPN set yet, right? I'm not there yet. I'm sitting here and I don't have open VPN completely set up yet because it needs to be configured with appropriate keys. We need to get certificates installed on our machines before this employee can get on. So currently this employee cannot go there. This is the private area. And so this employee wants to go inside the private area. How do you go there? Well, you take a jump from a jump box like this. And then through that jump box, you go in here or there, wherever you like. That SSH connection will be possible. And we will use that jump method like we have before. We have used that before. We'll use the same method. That method requires us to configure our routes and our SSH config in a specific manner. So you will see that SSH config is stored in that location called, I think it is.ssh and config. That's the location, right? So we'll go to edit that location. You will see that this location currently has some references that are stale. I need to modify them. I need to put my NAT IP here, take it from, and then dump it in place of the line number 16 that I have. And that will remove that line and append this number. Similarly, I need to also advise this SSH config to be able to connect to these IP addresses. And here you will see a pattern. The pattern is that we have, we can use a wild card. You can see what I'm going to say with the wild card. The wild card is this. That's what I'm talking about. This is common. So actually 10.128.whatever.whatever. That's what I'm putting a wild card in there here. And so you can now see it. The wild card lets me jump to any of the machines inside here in the private area, even also on the public area, as long as I have a hook to get inside this NAT device that I've created. And the NAT is an Ubuntu machine, so it needs to be Ubuntu. I'm forwarding my agents and then I jump. So this jump file is already available in your SSH config in your virtual workstation. And that's what this thing is. So I'm going to use this jump configuration with the correct NAT IP address copied from the terminal, which is here. And this wild card pattern doesn't need to change because I already have it right. It is 10.128, and that's the CIDR block I chose for my app servers. So that is already correct. Those are also Ubuntu boxes, so that's why this name is Ubuntu. And I'm using NAT as the proxy jump. And that's the idea here. So I'm going to save that and also clean out my old rem-srf, my old, what is called, known hosts. Just to clean out, rem-srf, slash.ssh, oh, come on, type properly, ssh, known host, there. So they're gone. Now I need to connect first to the NAT. So I'll say ssh NAT, and it knows the IP address, line number 11 on the left side and also in the configuration. So you know that. And I should be able to just connect and say, are you sure? And I'll say, yeah. And I'm into the NAT device. Here I am. This is the NAT machine. You can see the internal IP address is 10.128.0.106. You can match it with the Amazon Cloud. And you go here and say, Amazon, can you tell me my EC2 boxes in where I have three machines running? One of them is the NAT machine and the NAT has an internal IP of 106. That's the same one you have here, 106. And the two boxes, automated app one and automated app zero, those two boxes do not have a public IP. You don't need to have them, no public DNS, no public IP, they're only internal IPs. And so we have one of them here. We'll use them, one of them, these guys, these two boxes. So one of them is this and the other one is that. So we need to connect to those boxes. So first we kind of come out of this NAT thing. So I'm going to exit from here. And then I can just say ssh and say 10. And by the way, just to remind your memory, I'm going to erase the known host again. And then ssh 10.128.1.219. This is a direct reference to the wildcard entry here, which is asterisk, asterisk, star.star, that entry that we have in our SSH configuration. I'm just asking for that name. I don't even need to provide a username because that is already taken care of in the SSH config. I just connect and it will show you what it does. You probably recall this already. So I'm going to just enter and say, yes. So it says, okay, should I connect to the NAT first, which is this NAT device here? And I say, yeah. Go ahead, please. So it says, okay, should I connect to the 219 machine, one of the machines inside? And I say, yeah. So it goes and connects. There we go. We are inside connected to the machine number 1.219, which is this one. That is one of the app servers. In another tab, we will now connect to the other machine, which is this 10.128.1.219. And that machine, simply SSH and that number will let us in. And now we are connected. Two tabs, two different machines. Let's go see them side-by-side. So we have two machines that we have in our diagram here. Those machines are this machine and that machine. We are now connected from my location through the NAT device to 1 and 2, two terminals open right now on that window in the back. So here, two terminals. I will now inspect them, see what we got. First thing I'd like to check is what is running here? I see something running. It's Docker container running up for the last 12 minutes. And what about here on the left side, Docker PS-A? Well, I see Docker running here as well. Awesome. Now what I want to do is go inside the Docker container and modify one particular file to make these two containers look a little different, just a tiny little. What I want to do is on the right side here, I will enter the container. This running container I have, E9, C3, whatever that number is, I'll say Docker exec. And then give me the batch prompt. So I go inside. Now here I'll edit. I don't have editor, so I'd install editor first, sudo apt install, oh sorry, update first. No sudo needed, this is already root. So apt update and apt install vim, editor of my choice. So you see it's already able to update. The machine is able to update because it is able to go out through the NAT. We have set up the NAT and all the forwarding rules and all of that issue is taken care of. So that thing updated apparently. So now we have vim, and I'm going to edit vim and edit a particular file here inside the container. I'm editing one file, which is the HTML index file. And so user share nginx.htmlindex.ym, that file I want to edit this and say, welcome to application server, call it A. And save it. That's one machine, right? I'm going to quit. And here you can do the same thing, call it machine B, but I'm not doing it. I'm leaving it as it is. So no change there. Only one machine says I'm machine A. Now we'll open the browser again here. And in that browser, we'll inspect, what do we see here? So I see something. I'm going to see, welcome to nginx. I'm going to refresh the page, click, and I see welcome to app A. And I click again, and I see nginx. And I click again. I say, welcome to app A. Now do you know what is going on here? I refresh and I see something different like this. You see, one, two, one, two, what is going on? Do you know? Let me give you the answer. Or instead of that, I'll just point at it. What is going on? So this is what's going on. Do you know what's going on? Do you know what this thing is? You know, when I show you this refresh, refresh, refresh, refresh, what is going on? Any guesses? See, when I refresh, I'm this guy looking at the load balancer. Load balancer is connecting me through the Docker container to the app. And in one of these two boxes, I made a modification. I said, this is welcome to app, whatever that A, something I wrote. And this is the usual stock nginx. So, when I refresh, that is what is happening. It is jumping around here and here and here and here and here and here and here. What is that behavior called? What do you call that thing, this behavior of load balancer? Let me show you another way for the same idea. Here, another similar setup, you have this box here, right? And we'll create more of these guys. One, two, three, four, like that. And you have the user coming in and saying, hello, I need to change my ink. So the, come on, proper pen, where is the pen? And maybe this, yeah, so the user says, yeah, show me load balancer, please. So one, two, three, four, four machines now. So what will happen is it will go like one, two, three, four, one, two, three, four, keep on going like this. This thing is called round robin. You say one, send the traffic to this guy, traffic to this guy, then this, then this, then again, one, two, three, four, one, two, three, four, it's like a cycle going round robin. So we are behind the standard default implementation of round robin-based routing of traffic from a load balancer to the actual workhorse machines, one, two, three, four. In our example that we have running live, we have only two. We can add more simply by going to Terraform, where is that Terraform thing? Here, no, not here, in atom, atom. And then here we say app servers, the count is going to be 10. So we just say 10. And then we have 10 machines. That's the idea behind scaling. So this is manual scaling. This example is manual scaling, we'll get to automated scaling also, but this is manual. So what do you see now is as soon as you apply Terraform again, it will have 10 boxes spread out on the private subnet and you will have that thing scale out and automatically become a part of your load balancer. So that's the idea behind this implementation. It is a very, very elegant way of writing down your ideas, like Terraform says here. You write down your ideas, you plan your detail, and then you say apply, apply, meaning you just take my design and just do it for me. So it does it for us. That's what you see. That is the best way today as of right now to operate on any cloud, major cloud, smaller cloud, this, that, other, all of it. Now you will see a new idea, which is a part of this tool that is visual. So I think it is important to see this thing visually. And what I will now do is run another Terraform operation to show you a visual of what we just did. It is called Terraform graph. So I'm going to grab a command from here and run it. And so the command is, by the way, you can run it on your virtual machine also. There's nothing unique about the VM versus other machines. You can run it anywhere. It's just a simple Terraform command to look at the repository and try to illustrate from a mathematical perspective, try to draw a directed graph about the dependency structure inside your design that you have. So that is the idea that you will now see in a live example. You will see a conceptual diagram, which is a directed graph diagram illustration of the end result that you just saw implemented on the left side, looks like on a piece of paper on the right. And now you will see the same thing in a directed graph fashion, which is a built-in tool in Terraform. That's what I want to quickly show. It doesn't take too long. What I need to do is open another terminal. These are actually existing terminals. So I'm going to just open and go to that exercise we were. I think it's called ntier. I'll just go to that folder, ntier. And there it is. And in that folder, I'll just confirm the status. You will now see that I have a Terraform TF app server TF file modified to 10 units. That is not actually my intention to go like that. So I'll put it down to two. And now you will see that the git status shows me that I have only one change, which is the credential change that I made to my Terraform TF ops. It stores my Amazon credentials, and that's the only change. I will now run the command to draw a graph. This needs a little bit of discussion. So by the way, this is a two-part command. So this is the one part. So on the left side, it just dumps a mathematical representation of the Terraform's internal graph that we have defined in our files here, whatever we have. And in the second half, it tries to plot that math into a picture file. So this is a graph SVG file, and it uses the dot package. This dot package is a part of graph this library, which is also open source. And this is the extract command to extract SVG file. And that extension is SVG, which is scalable vector graphics. And that's what you will now see when I run it. You will see an SVG output coming out of that in that folder, which means on the right side in Atom, you will see a new file called graph.svg. So here we go. And that popped up. There it is. Oh, this thing, it doesn't show you unless you have to refresh or something. So yeah, something broken. So close it. Close Atom. Just go open it here. It's LS here. You will see it. So yeah, that's where the file is. We'll go open it. And so we'll say, open the folder and then look at the file called graph.svg in a browser. So like this browser, and you will see the graph now. Okay. Where is the graph? Did it not produce anything or what? Apparently I was in the wrong folder, or was it? Apparently so, because I was in the wrong folder. I should be going inside the Terraform folder. I always forget that. So Terraform folder inside and there I should first of all remove the other graph. And here in that folder, I should actually run that command. So it actually is able to look at the file structure that we have. So let's go see the math first. So here's the math. It dumps the math. This is mathematical representation of each item relationship with the other items. So that's the math representation by an arrow. This is a classic graph representation from a graph theory perspective. So that's your output. You have to take the output and draw a picture. And that's what the next command will do for us or the earlier command that we saw that did not do. That will now do it. And that action is this action. So it will now produce a picture. And I will see it here in Atom. And that Atom shows that picture here. The new file shows up. This is again a text code representation of the picture. So you will not actually see the picture like this in Atom. You have to close it out from here. So it's an SVG file. You have to actually open that file in a browser to see the picture because browser will render it for us. So the graph SVG, you have to go open it up and open with some browser like Firefox or Safari. So here is Safari showing you the graph itself. Here you can actually relate to the ideas that we discussed, basically item by item. And what you will also notice here is a dependency structure. These lines show you that it is a directed graph. So it begins with a root and goes all the way to building your VPC just like you had in your code written down for Terraform like we discussed the other day. And that is something to look at and something to understand compared to what your notes and this tool actually helps you visually understand whether your code is correct or not because it shows you dependency map. For example, the idea of some kind of a, let's say a NAT instance and the relationship between the security group for NAT, the security group default, the VPC itself, the also relationship between let's go identify the public route table and the private route table, private subnet. And it depends on NAT instance. That dependency map you can see it depends on a private subnet slider. So the arrows basically indicate dependency structure for anything for you to be able to build out the complete solution from a visual perspective, this is how you can detect your errors in the code that you write for Terraform. Terraform code is that simple to understand and read. There's not much code actually, just a structure of declarative statements that I want this and I want that and I want this provisioner and I want this app server and I want implement a route table and have that relationship and that's what we write in Terraform basically. So that is just a quick way to look at the picture. You can see it. You can create it yourself. So I don't have to give this picture to you, but I would like you to create the picture yourself for you and you can change your code to see how the shape of this picture changes. Having said, I will now close out on this exercise. And how do you close an exercise like that which is created with Terraform? You have to actually destroy your Terraform infrastructure. Simply speaking, destroy means you say Terraform and say destroy. And so we'll say yes to it and it will go and destroy your cloud. And so that's why it is an explicit yes request to say yes and otherwise it might not do anything. You have to actually say yes for it to go and kill your cloud. So it will go and kill it. Now we'll go to the next exercise. The next exercise also involves Terraform, but with a different cloud. So we'll now go there and I'll close this window and this one is killing the cloud right now. So we'll open up a different terminal and the terminal is here. One more. So here's the terminal. We'll go open the other terminal, for example, what's the name of that folder that I am building a new exercise with Terraform? It has relationship with Kubernetes by the way. So what we'll do now, you saw we did the exercise on using Kubernetes when I walked you through I think two or three sessions ago, we did this exercise here, which is go to the cloud segment and at the very bottom in the sequence, let's begin and go to the index. And that's where you will find the very bottom, almost at the bottom is where this idea about enterprise-grade container orchestration using Kubernetes that is actually gaining amazing amount of popularity. And this is what most companies are deploying. It is where there is heavy demand for people who know how to use this thing. And that is why most people that I find in our program specifically ask for Kubernetes. And that is something that I have taken to task and I've basically created a whole bunch of exercises. This is what we have done up to I think this point, we were able to finish through the last session. Now I'm not repeating that exercise, I'm just pointing out to you that this is something that you should focus on and do this even more because until you get the ideas and concepts, this is a good flow here to understand concepts. And it is mechanical, manual. And so it walks you through concepts. And I think a few of you have already done through this thing, which is nice. I am now going to show you an extension of the same idea, but with automation built in using Terraform. And this exercise currently runs in Google Cloud. I will change the cloud. I'll go to a different cloud that will use Terraform with the other cloud and use the Kubernetes implementation there. And we'll walk you through how to automate creation of Kubernetes cluster using Terraform and basically go build item by item, layer by layer, starting from the hard disk, the very foundation storage. And then you build on your components all the way to the end user, like what the user is going to do. So the end-to-end pipe, how do you build out these things in the context of using Kubernetes? This is an example of Google Cloud, we'll also see examples of other clouds now. With that understanding and discussion, what I would like to do is erase this ink and open the exercise. The exercise is going to happen in the cloud, also known as digital ocean, where you have an account already. So you should log in. This is a very easy to do exercise, by the way, because all the work is already done for us. So the exercise is fairly, fairly easy. Basically it says Terraform apply and then you're done. That's the exercise. But more important than that is to understand what's going on under the hood. That's what we will work on, is to understanding the idea. The actual exercise is as simple as, okay, clone the folder and say Terraform apply and you're done. But that's not the point. You need to know how to build that whole structure to see it for yourself so that you can also do it for your customer. And that's the point. By the way, as you will see on the left side, my Amazon cloud has basically died, it disappeared, the whole thing is gone. So I don't care about it anymore. And I will now go to the folder where I am currently working with Terraform, like that. Which one? This one. Yeah, so that's the folder. And it has my Git status showing me that I have modified some things. Let me just quickly check what I have modified, if anything. And that should also become available to you. So I have a, okay, yeah, good. So got that. Got that. So I think the Git repository is clean, which means it is in a position that it will actually function through. Now we'll open this repository in Atom Editor so we can see what's going on inside. So Atom will open on the left side or right side. And there you will see that I have a folder structure. And there you will see that inside that folder, I have a bunch of TF files, like the example before. Again, more of TF files. Now here you will see that I have a bunch of them, for example, this one, and that one, and that one. So it goes on and on. So there are lots of things that we'll be working through in our exercise. So what I'm going to do is hide them. How do I hide? Simply I create a folder here, say new folder, and call it hold or something, and just hide files there. So I'll hide a bunch of files, I'll just take them all away. And move that to the hold area, like that. And more. These files also need to be going back to Google, back to DL, let's leave these files here. They're not actually TF files. I'm more worried about.tf files. So let's go, first of all, to understand the basic things that are necessary for our discussion. So I'm going to hide that, or the rest of it, and just begin focusing on the variables, and critical details that are necessary for this to function. So I'm going to hide all these guys out. So let's see, this is NFS deploy, one, two, three, four, all these guys can also go to the hold area, this one can go to the hold area, and this one also goes to the hold. So now let's go, and these guys also go hold, so I'm going to hold, minimize the folders I have. So a couple of things that I have here, even this can go in the hold area. So basic files that we need for us to basically begin with understanding, what are we going to do? That's the first question. So what are we going to do is we are going to create a Kubernetes cluster here. This Kubernetes, we are going to create what we have on the left side, we're going to create one using the main file. The main file basically describes what I expect to have. And so here I'm saying that I need to get a resource called Digital Ocean Kubernetes Cluster. And it needs to have, in that cluster, I will have three machines. And that's the idea. So that is called a node pool. That node pool will contain these three boxes. And those three will constitute my cluster. As you know, Kubernetes has a master set of machines and worker set of machines, worker one, worker two, worker three. Now this master is managed by Digital Ocean, so we don't have to worry about it. This is what we are focusing on. So three machines, one, two, three, are a part of the node pool here. And that's what will become the cluster that we want. And so what we have in this illustration is the idea that we are specifying some variable references, which define the cluster name, the region, the version, the tags, and the name of the pool, the size of the machines inside the pool, how many we want, and tags for that. Those are defined in a tf.vars file. That tf.vars file is this file here in the variables file, which I specify that I wanted San Francisco and the name of the cluster, version number, and I want three of those machines of this size. The name of the pool is Deadpool, and a bunch of other details regarding that. So that's the Terraform variables references in this variables tf.vars file and the Terraform tf.vars, which contains specific details about secret stuff that I might have. For example, I have to have a token from DigitalOcean. So in DigitalOcean, you have to go to API, and in that segment, you will be able to create a token for yourself that is similar to creating a AWS access key pair. And so this idea of generating a new token, you give it a name here like that and say generate a token. That's the token you will see, and this is the only one time that you will be able to see this token. This token will become invisible to you. Forget about everybody else. Even to you, it will become invisible after you walk away from that page. So that's the only time you get to see it. You copy it and you dump it in your Terraform tf.vars file as a place to store your token. I'm going to delete that token because that token is not what I actually want to use. I deleted that. The token I'm using is this one, which I already have in that variables file. So I'm not worried about that piece. That's the one critical thing you need. And then we define, we need to have a cluster, like we say here. So that's a resource definition for a cluster we want to put together. So resource, get me a cluster in that cluster. So within the cluster, I have to have a pool of nodes, which basically it has a name, three machines of, sorry, three machines of size, I think 2GB RAM, like that. That's the selection I have made. I get some names and tags and then I'm choosing another provider. What I'm doing is this first segment will actually create the Kubernetes cluster. And the second segment is actually use the Kubernetes cluster to instantiate applications that I will have for the cluster. So first I will create this cluster using this segment. That's all it takes, by the way. This portion will create a cluster. It's very simple. It's actually even simpler on the web browser. And this is the reason I like this cloud is actually very simple. If you go to the browser, it doesn't have too much clutter. All you do is get a cluster and then you basically select a region and select the number of machines that you want. So like you can say I get 2GB memory. The standard nodes are flexible nodes. So say 2GB memory, 2 CPU, that's a good size, I think, to start with. That's what I would recommend is to start with get this. So 2GB memory and 2 CPU. That's what I already have selected for you here. And so that reference in the variables already selected for you. So you will see that that's what I will get three machines and choose San Francisco and say go create a cluster. And you can also choose your version number and names of cluster, cosmetics, basically cosmetics. And you will see that this version of Kubernetes that I have in my exercise is now stale. Okay, I just finished the exercise in the morning. And by the afternoon, this version I think that I have is now old, see, 13.3. They're now on 13.4. So I should just change that before anything happens. Because if I run the exercise, it will die on me, crash on me, saying that version not available. So that happens all the time. I ran the exercise in the morning, it was 1, 13, 3. And now that version is not available here. So I think the latest one. So I made it 4. Now that will work. I hope. It's always a hope. And so that's the main configuration. So it creates the cluster, and then it also sets another provider to use the cluster. Now let's see what else we have. We have a kubeconfig entry. That configuration is something that you need to extract from the cluster so you can operate on it using your command line. So when the cluster gets ready, they'll give you a file here. You put that in a folder like.ssh. You don't put it here. You put it in.kube. And so in that cluster, you put a file called config. And that's where this file that you download from here belongs. Not here, but here. There's also another hidden folder. And that path is what I have called out here in that variable. And so it will dump the content which is coming from here into that file called config. And that content is that configuration itself. And that's what you can do it manually also from a browser window is save the file here. But I don't do anything in the browser if I can do without it. I prefer that because I prefer it automated. So that's this portion. You can see that the code here is actually very, very easy to find as to what do I want to write here. Because there are tons and tons of examples available on Terraform website and also on outside on Google. You will search. You will find them. Whatever ideas that you come up with, you will find that those ideas are available. This exercise I built in one day. Yesterday I was starting and then today in the morning I was able to finish through. And let's see how it actually works out. So I'm building exercise, not doing it, right? Building the new exercise fresh and building it from scratch just by Google searches. And it is now ready for us to consume. So let's go see what are the other things here. The main, as you already saw, is just the expectation of creation of a cluster. And the next is the idea called providers. And here I'm using a variety of providers to accomplish a variety of tasks. Like I'm operating on DigitalOcean. I'm operating on local system. I have a null provider that does trivial mundane tasks on the system. I have a template provider. I have an external provider to grab data. And I have a Cloudflare provider to operate on my DNS system. So you will see that the entire thing is actually automated. You will see what these providers will do for us as we go along. So I'm basically defining them, declaring them that I need them. Then I have some variables defined here. In that variable section, you will see that I have a token defined, a region defined name, cluster version. This is the version that I will override in that file that I just did. This is the version I picked. Cluster tags, cluster default node size, which is like this size that I have, 2 GB memory, 2 CPU. That's the size. Number of machines, I need three. Cluster tags, again, configuration path, I'm going to store my configuration in this file, which is the default file chosen by almost everybody using that folder location. That's a convention. You can choose it wherever you feel like. And then I have some, I think we discussed the configuration step, the main step, the output step. Output, we did not. So output will dump the result of what the host name is and the IP address for NFS service. I'll basically dump these outputs as it runs. So we'll now see what happens when we say Terraform plan. And it will show us all these TF files collectively operating together in the form of producing a result. The result will be creation of a cluster. And the cluster output of the API server will show up there. And now we will execute that step in our terminal here. And so on the, this is the old destruction that happened. So I'm going to quit from here on the, on the rights on the left side, we'll say Terraform initialize. And it will, you know, is it an empty directory? Oh, I mean, again, in the wrong directory, you have to go inside one step K at S. So that's the Kubernetes folder where I need to operate on. And that I have a bunch of files deleted. These deleted files are actually hiding in the whole folder. So that's where it's, it's hiding. That's why you show deleted in the git status. And now I'll say Terraform initialize and it will initialize all the models. Hmm. It's an NFS IP unknown resource. Apparently this, this resource is unknown because I am expecting my whole files to have one of these files available. I think, yeah, I think that that's a dependency. So I had to maybe put that output folder also in the hidden area. Because yeah, it will not initialize because it expects that NFS file to be available in the output. And that was not, it was hiding in the whole data. So I had to hide the output also, which I was able to get through that. I just moved my output folder in the hidden area. So output is not going to be available as a result, but that doesn't mean that the cluster will not become available when I run it. So now when I say Terraform, please show me the plan. So Terraform will then show me the plan, Terraform plan, show me what the plan is. So it says I'm going to create two things. The two things I'll create are a cluster for you, sorry, clear. I'm going to create a digital ocean cluster for you. And I'm also save your local configuration in that location. So are you ready to do that? So I will say, yeah, go apply. And that's what you will see, a cluster pops up. Oops, share it again. So sharing my desktop again. I accidentally clicked on the wrong button. And now I'm going to say Terraform, apply. And you will see a cluster gets created. So let me say apply. And you will see that it is going to preserve the state in the state file here, that state file on the, I had to say yes to it. So it say YES carefully, and it will go and create a cluster as simple as that. And it is also very simple on the browser window, by the way, I'm saying that this interface that these guys have created is a beautiful, simple, good for learning site. Digital Ocean is great for understanding and learning the concept. That's why I love it. It is simple. It is to the point and gets the result quicker than any other cloud. That's why I keep on going at it because I think they have done a phenomenal job, at least for me. I don't know who else uses it, but it's a phenomenal service that I really like. And I use it quite a bit because it's elegant to describe and actually make use of. So you will now see that the cluster is getting created. We can see it here. There it is. The cluster is Andromeda, again, the same name, but different cloud. The cluster is getting ready and you can see that it's going to have three nodes. The three nodes are going to pop up here. Currently, I don't have any. And so once that cluster gets ready, it's a matter of a few minutes for the cluster to become ready. While it does, we'll go talk about a couple of other things while it's getting created because we need to understand what are we going to do with the cluster. So now that we have the cluster going, what I would like to do is to help you understand what are we really getting. So what are we getting? We're getting basically three boxes. We'll get some randomly assigned boxes with randomly assigned names and IP addresses. And we have basically nothing to do with the boxes. That's the whole point of a cluster. We'll treat these boxes as one unit. We'll call it our cluster. Andromeda is the name I've chosen. You can choose whatever name. And so there is a disk here. There is memory, 2 GB. There are two CPUs, two CPU cores, so one or two cores, 2 GB RAM and disk and all that and the network and all that. All the good stuff, right? You have the same setup here. But let me tell you, we are not using any of the disks here. Can you tell me why we are not bothering about using the disks here? We are not going to use the disk. Can you tell me why do I say that? Any guesses? Why do I say that? Don't use those disks. It is kind of a bad idea to use those disks. Nobody? Okay. Well, then I'll tell you why. The reason I say that this is a bad idea to use these disks inside the machines is because I told you that we are not going to worry about the machines. So we are not going to deal with them. We might shoot them. And so if I have data on that machine, then it will be an oops situation if I accidentally shot the machine. So I don't want to be in that oops scenario. So what do I do? Well, I don't store my data there. So by not storing data there, I'm basically treating them like a cow, like cattle. So I can actually shoot them. And when I shoot, I get a new one and I get any number of them. That's the whole idea under the hood that I don't want to store my data in the disk that happens to be there. And I'm just bad drawing right now, but this is disk. So to call it disk, disk, disk, three diskets, they're there with the machines. So three droplets, you will see them coming up. I will be using a separate disk here that is available from here, volumes. And every cloud will give you such a thing like extra external disk, external storage. And this is very nice disk. I mean, nothing wrong with it. You can take this disk and connect it to any of the boxes. But let me tell you, just like I said, don't use the disks. I'm telling you another crazy thing. Oops, I accidentally erased the whole thing. So I'll go to another sheet of paper and that will persist. So this notability will keep the data intact. What I'm going to show you, tell you is another crazy thing that you will probably hear from me because people don't talk like I do. And so crazy ideas. So here, the cluster, there are three machines. Three machines have disks. And I'm going to get a disk from the outside. And I'm telling you that don't use this disk. Don't use the disk. Don't use the disk. I'm going to say that, you know what, you can connect this disk to any of the machines you like, but don't. What did you just say? Yes, I exactly said what you heard. Don't connect this disk directly to these machines, please. And create containers in the cluster. This is your cluster, right? So you just don't worry about the machines inside and use a container to mount the disk. That is also possible. And you will see that in an example coming up soon. So that gives you the total flexibility to be a cowboy of true characteristic. You can actually afford to shoot these machines out and add more, or scale, or grow out, grow shrink, grow shrink, as you feel like, because the machines are irrelevant. It is about the containers. That's what you want. You can mount a disk directly to a container. Not only that, you can do further magic. What you can do is dedicate one of these containers to become your NFS server, NFS. If you know what NFS is, I think you know. So I'm assuming that you know NFS. If you don't, please stop me. I'll describe it. But I'm assuming that you know a network file system and a shared file system. And so that's the idea. What you want to do is take a container running NFS and mount that big disk, big and fast disk, external disk, available to you from the cloud company, and then export the disk. This idea of export is a concept in NFS. You can export volumes from within an NFS server. So this becomes your storage server. And now all of these containers can mount storage available. This is one way of implementation of persistence. There are various ways to implement these ideas along the way. That's what you will see today, by the way, in our example. This is what I'm building right now. Right now, I'm building a cluster, but you will see when I bring the files out of the whole area, you will see this implementation going alive. Once that, these containers will get access to mounted areas, mounted file system from NFS exports, which is exported by another container that you would have. You are completely independent of these boxes. That's the goal I have for a cluster is I want to shoot these cows in any time I feel like and get to my business. So I'm basically directly preserving my data right on the big fast disk, externally stored and protected and backed up. So there's a backup process you can run outside and it will be backed up periodically. You can take snapshots and do all sorts of things. But mount that in a container and export. So every machine get access to a shared storage. So your data gets stored here outside. So you kill the whole thing, you still have your data. That's the point. And so I'm not killing the whole thing right now, but I'm actually building the cluster right now. So that's what I will go and look, see what do we have. The command seems to have finished, which means, what does it mean? It means we have a kubeconfig now, a configuration stored in that location. They already told you that right there, there is a file called kubeconfig stored in that location. So I'm going to use it. Well, using is automatic. You just automatically use it because it's in the path for kube control. So you can see that I can now operate on my new cluster. And we'll go a little bit bigger in font and here it goes. So you will see that I will make it full screen and say Kubernetes, which is an alias for kubectl. This kubectl, I have made it short to just say k, just to simplify my typing and say k get all the nodes I have and it will give you the three machines you have. And those are the three boxes. They are called kind, Williamson, CJ, whatever number. That's the name of the box. You can see the same box showing up in your browser window somewhere as I refresh. And so as I refresh, the three boxes will pop up right there, one, two, three. And the cluster is available here and you can see the cluster. Now if you want to go to these IP addresses, they are not actually accessible. So there are three IP addresses, one, two, and three. You cannot actually do anything with these IP addresses because these IP addresses are again, irrelevant. I don't care about them. I don't want to do anything with these IP addresses because they're tied to the boxes. They're tied to the cattle. I want to be able to shoot them and this IP address will change. I don't want that to change. I want to persist. So what do I do? Well, I have to have another solution from outside. That outside solution will get me into my cluster from the outside. And that endpoint will be a load balancer. And that is where I need an IP address. And that's what I want. That I can get from somewhere in here. I will be able to allocate that load balancer. So it will look at the cluster from the outside and it will actually map traffic to the three boxes or maybe more boxes as you have. But that is the IP address that needs to map to my domain. And I have a new domain today just for that purpose, which is this name, cloudgenius.co. Just a separate domain just to not mess with my other sites. And I'm going to make a wild card entry like that and take this IP address and say, you go there. Meaning anybody who visits any site in that subdomain, in that domain, will automatically reach this load balancer. And then I will put a bunch of other things, as you will see, I'll walk you through that design. So the whole design is implemented in our code. So we'll now see the code one more time. The code is in Atom Editor. And you will see that we have a state file that captures the state of the cluster as it is currently. Just a cluster, nothing else. And now what I want to do is bring out a couple of things from here, or bring only a few items at a time just to make it meaningful, but still keep it small as we build. So the thing that we did right now is main file, which creates the cluster and provides for Kubernetes. There are a bunch of providers defined, but I'm not actually using them right now. Some variables. And then here is your kubectl configuration, which we already have access to in that file which is called, file name is actually that one. So you can see it,.kubeconfig. That file contains the configuration of the cluster. Here it is. So lots of detail. By the way, this is secret information, so you should not be sharing it with other people. Do not share your kubeconfig with people outside your team. This is something to be not shown to others. I just want you to repeat that. Don't show this to others. It's your cluster secrets. Having said, this is what actually is used to connect to the cluster. There is no other way to get to the cluster because all the ports are logged out. The way you can get in is through a proxy connection or through a load balancer entry. That entry point is what I will be now, sorry, there are two ways. Proxy is one and load balancer is another. So I'll now use the proxy method of getting in, first of all. The other one will be a load balancer provided by the cloud provider. So it will get you an ingress point to get inside. You'll get an IP address from the load balancer and that you will get inside and there are only specific ports allowed like that. So we'll have to control the firewall for that also. The proxy connection is a gRPC connection, gRPC connection. It's a Google protocol to connect point to point and you will see that in play right now. So for that to happen, what I need to do is to install a piece of software on our cluster. That piece of software is called dashboard. Dashboard is a separate part of Kubernetes open source. It is called Kubernetes dashboard and that's what dashboard I am going to install right now. So this is the product. For that product to get installed, you need to follow a bunch of steps. That looks like this, by the way. And you need to follow a bunch of steps written down here. I have a script for that. That script is right there. So I'm going to just run the script and it will give me the secrets to get inside through a proxy to the cluster so you can see it visually. So I'm still not using the interface provided to me by these guys because they don't actually give you an interface inside the cluster. All they see, all you see is the cluster and you see nodes, but I want to nothing to do with the nodes. I mean, I have three of them and then I have some settings, but you still see, all you see is a delete button, the destroy button. That's all you see. But apart from that, you don't see anything inside the cluster. They don't give you visibility as to what is going on inside. They show you droplets, the machines, they show you the cluster, but not inside the cluster. There are some volumes, none yet. So there is no volume allocated yet from outside third party, external volume, none yet. We will allocate one soon. You will see that there is a networking tab where we have load balancers, again, none yet. We'll create them again through automation, not by hand. But the view here doesn't give you a view inside what is going on in the cluster. And that is what we want to see from a dashboard point of view. And that dashboard requires us to run the steps that are defined in GitHub. And I will now run them in here. It is simply running the script like that. So it builds out, basically installs dashboard software on the cluster. Dashboard is also open source software, as you saw on GitHub, but it is not a part of Kubernetes. I just want you to understand that piece is that it is not. So let's see Kubernetes, then say dashboard, that piece is a separate package here. So not Kubernetes. It's Kubernetes dashboard. It's a separate package and also open source. And so that's what I just installed. As a consequence, I have this key that I'm going to use. So I'm going to keep that key in a folder here somewhere like that. And that's my key. I have a password, by the way. And so that password I'll be using. And I'll now establish a proxy connection from my machine to the cluster. So it goes like this, k proxy. That's all it takes. So I'll run it. Proxy is running locally. And now anything I do with my local host will just go inside the cluster directly. And now we'll go there. So we'll say Firefox and now go to the proxy address. So Firefox goes there like that and says, okay, give me your password. And so it's going to ask me for the password, which I'm going to provide it to as soon as it becomes ready. Dashboard takes a little time to install. And so that installation must have finished by now. And so I should be able to see the dashboard asking me for a password anytime soon. It is trying to reach out. And yeah, it's coming. It's coming, it's coming, it's coming, it's coming, it's coming, it's coming, it's coming, waiting. Cluster. We have to wait for it. We'll wait. While we wait for this, let's go forward with the exercise. And what I want to do is to bring out other items from the cluster itself. So we have a bunch of other configuration items. One of them that I want to begin with is to allocate a disk. So here, I think it did not reach out. So it may be timed out. So we'll wait for it to finish. In the meanwhile, this file called 00 output and this AWS keys and then disk and reg cred, those files. Let me describe what those things are. They're specific to credentials, by the way. So this contains my Amazon credentials. I don't need to have it. Do not. You don't need to use Amazon Cloud with DigitalOcean Cloud. There is no reason to. But apparently, I like it that way because I want to back up my infrastructure in Amazon buckets because I find that it is a slightly more reliable storage solution than this DigitalOcean thing that I'm going to talk about. So I will take backups, automated them, automated backups, and I'll dump them in Amazon's bucket as opposed to DigitalOcean's bucket. They also have buckets, but I don't like, I should say I like the reliability factor of Amazon buckets slightly better than DigitalOcean buckets. That's why I'm using my Amazon credentials here. So there is a script that takes backup of anything that I actually run for real. And I do run these things for real. You will actually see the Cloud Genius site coming live on a staging area in this site. It automatically backs up itself in Amazon. That's why you have this awskeys.tf file, which takes the credentials and creates a secret to be stored inside that cluster that we have created. So that creation of that step using AWS keys will actually show you a segment which will store secrets inside Kubernetes. So you will now see now, okay, get secrets. We have one secret, which is the Kubernetes default token secret. We don't have any other secret. I will now add that secret file and you will eventually see the secret becoming visible as soon as I grab this AWS keys file from here and put that inside our folder in K8S so that it becomes available in here. And then I will similarly grab this ID, this disk.tf, which will create a disk for us. So that you can see this one particularly, it's very easy to comprehend what it's going to do. It's going to allocate a new disk. So this resource is going to create a persistent volume and claim a disk resource from Digital Ocean block storage. So that's a storage class available in Digital Ocean. And you want to get this disk allocated in that size. And so this file, as you move it out from here into that folder, which will show up here somewhere, that's when I will say Terraform apply and we'll create this disk and you will see that happen. I will also take this credential. This is another credential that I have, which stores my Docker Hub login password. And that thing is something sitting in this file, just like I have my Amazon credentials sitting in that file. I have my Docker Hub credentials sitting in that file. So that will also need to come down here, which I need to move this file from this folder to that folder. And so that contains secrets for Docker registry. That's the reg cred file, registry credentials. It stores my Docker Hub login basically. And so I will not be showing that file to you, but you can see an example from Google searches. I'll show you Google examples. That contains my password for Docker Hub, which is where I store my images for Docker. So that is similar to secrets that I have here in the AWS keys file, which is storing my Amazon credentials. So having seen those two ideas, I will now move that reg cred file out from here over to K8S. So it now pops up here. These two guys are secrets. Now we have disk file. We'll also move it outside. And that disk, that file you're looking at on the right side, I'll move it to the K8S folder. And then what I will do is also grab this NFS deploy. This is something to understand. And we'll just grab this file outside and the output file also. So those are the few files I'll deal with right now. I'll hide the hide folder again and let us see what we added. So what we have now added in our segment is a few secrets. And those secrets are this and this, those secrets. So we understood that. We added this item that created disk allocation. We added, this is the script that generated this password that we have not visited yet. This is going to show us the dashboard view, dashboard. And that script actually creates a dashboard software, installs it on the cluster, gives you this password. And so you can just log in when it's ready. So we'll go there. We have a bunch of new things here, which is the output file. You will see the result. We have the disk. We have the deploy. So this is the most important thing that I want to talk about right now. So what you will see now is that this disk gets created, which is like a disk outside. It is not one of the three machines this gets. It's a separate extra disk, 100 GB. And that disk I want to actually mount on a container running NFS server. And the container directly mounts the disk. And that is what this NFS deploy is. It is actually going to deploy a container and mount that disk directly in the container. So it becomes an NFS server in the cluster. So I can then export this disk from the cluster. That's what you will see now once I apply this design. So before I apply, let's go see what the browser is showing when we visit Firefox and say, can you please show us the dashboard? I think something is wrong with the dashboard. Let's inspect that later. But other things should work. We can say get PO, all namespaces to check out on dashboards. Yeah, dashboard is running for the last nine minutes. Is the proxy running? Proxy canceled. Okay. Okay, break it. Run it again. Firefox, would you please open the cluster for me? Okay, forget the dashboard piece. It's just a visual UI. Let's go understand other aspects. So we'll go apply Terraform here. And I think dashboard is misbehaving. So we can forget the dashboard piece. Now we'll go look at our Terraform scenario. And so we say Terraform plan. So what's the plan? So it'll tell you that something is missing. What is missing? That this file, Docker config JSON could not be found because it moved out to the hold areas. I need to move it outside. That's also a necessary file. So this file somewhere is hidden. That file needs to be moved out. It stores the actual configuration for Docker configuration for Docker Hub. It's also a secret file, related secret. And so it needs to come out. That file is now available in here. And that is also a part of my Docker Hub login. That those login details are necessary for me to actually pull images and things like that. So let's now see that it is going to do six things. Let's go see what those six things are. So here, first thing it says that I will deploy an NFS server as a deployment inside Kubernetes, which means a new deployment is going to create. And that deployment is what is, I'm going to go deeper and help you understand what the details behind that is. But that's going to be a new deployment of an NFS server, basically inside a container. And so what we will do now is to look at the next step. We are going to create a Kubernetes persistent volume claim on a disk. This claim is for 100 GB. It's going to give you DigitalOcean block storage, just hard disk from DigitalOcean. And you rent this hard disk for about $5 for, I don't know what the pricing is, $1 per GB per month or something like that. It's not free, but you probably have a coupon. You probably have a $100 or some coupon for playing around with DigitalOcean, so you should use that. Here, the next thing is it's going to add a secret called AWS keys, it's going to add another secret called RegCred for Docker credentials that lets me access Docker Hub without having to type password. And then it's going to create a service for the NFS server that we create a deployment on. And that is this server that we created a deployment. Similar to that, we have a service for the NFS server. And that service exposes its NFS to other containers inside the cluster. And we'll also refresh our local kubeconfig file, which requires a new resource. So we're going to force that recreation. So we're going to create a fresh new kubeconfig, and we'll say terraform and apply. So it goes and create these things in our cluster. So we'll say answer yes, please go do these six things. So it'll go quickly, create a deployment, create a service, and also allocate a disk, and map that disk to the container, and let me draw it. So let me draw these things, so they already did very quickly. Okay, finished. So let's go see what it did. We'll go and look at our browser to inspect what we have. And here you will see that this thing has given us a volume. Come on, show me the volume. Jumping whale. There it is. So I see the volume. That volume is this one. It is 100 GB. Now, let's see what else we have, the droplets and cluster and all that. We already know these things, but we don't see anything like we set up an NFS server, or whatever happened to that, right? So that's the detail I want to show you now. And we'll see that detail ideally in our command line. So you will see that we have a volume here, 100 GB. And what I have created is a NFS deployment. This deployment is basically a pod running NFS software on a CentOS machine. In a Docker container. On one of these three machines, we don't know where it runs. We don't care where it runs, but that container is actually mounting this disk and it's going to run NFS. And then we want to have this setup, specifically this pod that runs that container, expose itself and it gets a pod IP. But if you want to have this pod might die and a new one might come with a different IP. So new IP addresses keep changing, pod IP addresses keep changing because of the dynamic nature of pods dying and new pods coming and growing and shrinking, things like that. So you don't want to tie yourself the NFS service to a pod IP at all. Instead you create a layer of abstraction around it and call it NFS service. And that is the second thing we created in our example illustration that you saw in the... No, you did not see it in the code. I will now walk you through the code piece. So that service that you see and the deployment that you see is actually here. I will walk you through that now. So the two pieces to understand here are that we have a disk and it is mounted to a pod IP running NFS deployment and it has a pod IP, which is dynamic in nature, pods come and go, pods grow and shrink and they die and they come back to life with a new IP address every time they do. And so we want to get an abstraction around it, call it a service. The service abstraction basically is mapping to all the pods in the same deployment. So you have this pod, that pod, all pods, these are in that particular service, they all will map to one static IP. That IP is persistent, it doesn't change until you kill the service. You don't kill services, all the reason of the service is to get that static IP. That's what we really wanted. And so you will see that there is a deployment resource here that creates the NFS server. It has exactly one replica, which is this pod and it has some names, some labels mostly. The operative thing here, it runs CloudGenius NFS server version 4.1. And then it has some resource limitations and it has the NFS port open. It has a MountD port open and I think RPC port number 111 also opens. You will see that as soon as I scroll. And so I'm going to erase the ink again, only a portion of it. And so RPC buying ports are also open as you can see on the lower portion of the port section in this particular deployment. So what you will now notice is that these three ports get opened up on that particular pod running the deployment for NFS server here. So one, two, three ports are these. These three ports need to be opened up on a NFS server so that this service can actually export the disk that you want other people to be able to consume, other containers to be able to consume. And so other pods and containers that you will have will be able to mount this storage that this service exports on these three ports. That's the nature, these are defined ports according to NFS specification. So that server software is a custom image I created just for this purpose is to take this disk and not worry about any of the machines here, but just directly mount in a deployment and expose it out like a service for other containers to consume. So that way you find out the most economical bank for the buck solution is right here. You're spending money here and that's it. There's no other cost. This you already paid for in your deployment in the cluster. This service is free. I mean, you just create a service like a piece of code running inside your cluster. There's no extra money involved, so no money here, no money here. All you pay for is this and you get shared storage for all bunch of other pods you might have in your cluster. All of these guys basically share the storage. That's a good way to get to a basic decent solution. Of course, there are various ways to make your storage performance high end and we'll talk about that also if you're interested. You need to tell me that you are interested. We have exercises for that also, but you need to tell me that you are interested in high end storage. Then we'll do high reliability, high availability, persistent storage in a cloud context. We have exercises for that also created. People in the last time asked for it, so we built that one. It is there, by the way, and there's a video recording also available if you're interested in watching that. Having seen that portion about a deployment that you're looking at here, this is your Kubernetes deployment for NFS server. If you scroll down a little bit below, you will then find a service reference. This is your NFS service that basically exports the same ports and makes this collection as a service reference to the deployment here up all the way in that portion. That's what you're now looking at in our cluster. You now have a discount side, three machines. We don't know where they are. We don't know where this particular deployment is running. We have no idea, but it runs somewhere. Let's say it's run here. This is your deployment running NFS server. Then you have a service that maps to this IP address and that service generates its own static IP. That is what I'm interested in because I want to have other containers. This container, that container, this part, that part, I want to map to that IP so that they can all use this disk which is exported from this server. That is your deployment. This is your service, the service defined here. You will see that this is a classic service definition written in Terraform format. This is similar to the YAML format that you have seen before when we discussed Kubernetes in two, three sessions ago. Same thing. We discussed services there. This is the same idea implemented in Terraform. In YAML, it looked like the same thing will look like this, the deployment file that looks like this, and a service file that looks like that. You can see that. The same thing in YAML format. You have a deployment, you have a service. In the deployment, you have one replica that uses this image, the same image. It has these ports open that map to these ports one by one. This is your server that exposes itself as a service for other containers to consume the storage. In this guy, this one, it mounts the disk volume from the claim that we have created. This claim you can also see in the Terraform format also. The same thing basically just written in a different format. The same YAML written in Terraform format looks like that. You can actually, item by item, compare it. It's the same thing. You will also see the volume mappings here. The volume called CSIPVC, the same thing here. That's the volume claim here. This is your volume export called MyPVC in the folder called exports mapping here. The same thing again and again. Now, you will see the relationship between this volume itself, the actual disk, actual disk outside. Where is that? That you will see in your disk file, which is in the YAML format sitting here and in the Terraform format sitting here. We'll now see them. I'm going to erase my ink and I'll show you the disk in YAML format and the disk in Terraform format both, just like you're looking at the YAML and the Terraform format. Same idea, deployment, deployment, service, service. Now you see this disk on both sides in two formats coming up in few, closing, closing. Here, your disk in Terraform format, open it, and now you see the disk in YAML format on the right side. You are basically asking for digital ocean block storage. Give me 100 GB and call it CSIPVC and I want to claim it and that's the claim name. Same thing here, claim a disk from digital ocean block storage of this size. Give me a disk. I asked for a disk, they gave it to us here and I'm going to mount it, but not on a machine. Instead, I want to mount it here, also known as here for the NFS deployment. That's what I will be using this disk with that name or rather this name to mount it to this deployment or the YAML format, the same thing. I'm going to clean my ink again. That gives you an understanding of what we just built, but how do we actually test this? I want to make sure that this NFS thing that Nilesh is talking about, it should show us the result of the disk that is actually persisting. What I want to do is put a test there and I will actually create another container that will test. Here is the whole area where we have a test Terraform. I'll bring that Terraform out, tf file out to the K8S area like this. Now show you the corresponding YAML for test as well as the Terraform representation. Here is the Terraform representation of the test and here is your YAML on the right side coming up in right. What this thing is, think of it as it's quite complicated because actually it is a production ready tool for me to back up my own stuff. It also does testing and we can use this as a proxy for testing. It's a tool that uses Amazon access key and secret key and actually does the backup for me. All my backups go to Amazon Cloud in a bucket. This is a custom image created just for that purpose. I will be using this image and creating a claim. Let me describe this idea first on a picture first before we talk about the code. The code idea is like this. You saw this diagram that I had drawn already. We have a disk and then we are exporting it to a NFS deployment, creating a service and exporting it to other people. Now we'll simplify this illustration simply like this. We have a disk, 100 GB and then it is mounted to a deployment. By the way, as you notice, I have stopped drawing the machines altogether because I don't even care about them. I care about my deployment that I have, which is running my deployment of NFS and then there is a service to wrap around it and that thing is the deployment of NFS service. What this does is exports the whole disk. What I want to do is to actually mount this whole disk on a test deployment. I will create a PV, a persistent volume out of this area. I'll use the slash, the whole folder, the whole thing like as is, total, root and say, hey, this is your PV and so you claim it, PVC, persistent volume claim. I'm going to give you a PV. You please claim it and so this whole disk, I'm going to make you available to you. So this is going to be a new deployment and now you will see that this deployment, test deployment will be able to claim the disk here that it is exporting and you will be able to operate from here, create and read and write files on this disk through the NFS service like that. You will see that now. I will need to instantiate this particular run, which includes our test deployment. So it takes a little time, I think two, three minutes for the test deployment to actually get deployed and that deployment is what you see in here is what it has is, first of all, a persistent volume called out. This volume called test is going to allocate just one gigabyte space out of the hundred, but it's going to be read, write, many. So any number of machines, any number of containers can read and write simultaneously. That's the beauty of NFS, is you can have multiple containers writing and reading through NFS lock. So that NFS provides a beautiful implementation of locking and that is what allows us to do read, write, many. So multiple containers can read and write the same file system at the same time because of locking is built in. And now here we are calling out that use the NFS service and grab the Kubernetes service NFS server cluster IP address, grab the IP address of the service and use that as the server and the path is slash, give me the whole disk. And I'm calling it a storage class cloud genius. This is a made up name, made it up. You can repeat that same name here to associate the relationship. And then I am going to create a claim on this disk here, that path I have, I'm going to make a claim. This was an allocation of a volume. This is a volume claim. So this is PV. This is PVC. I'm going to ask a claim on the disk here. I mean, it could claim this disk, one GB, small portion of the whole disk, but I'm getting the root path, this path. And once I have those PV and PVC ready, I will create a deployment. The deployment down here looks like this, and which basically uses this image and runs it. There are some environment variables for secrets and other things to do a backup and things like that. And there are some volume bounds that you already saw here, PV and PVC, the same thing is written down here. Having seen this, I will now execute Terraform apply. And let's see what it does for us. So we'll go back here and say Terraform apply, see what it's going to do now. So it'll tell us, it's going to read the differences and it's going to tell us that it's going to add four things now. What are those four things? Let's go see. First thing it says, I'm going to create a test deployment. So here, test deployment. Next, what it does, as you will see now as I scroll, is that it's going to create a persistent volume called test. It's also going to create a persistent volume claim for test and then rewrite my cube configuration in the four things. So I'll say yes here, Y-E-S, and it'll go and do it. It'll go deploy a test deployment, create a PV, create a PVC. If you're not with me, ask me to slow down. There are details here to understand and I'm going to elaborate on that again. So I think it did four things. What did it do? So we have a disk outside the cluster, 100 GB. We created a service for NFS, which points to a deployment for NFS, which actually connects to the real disk. And this disk exports the whole disk via NFS exports. And out of that, we created persistent volume. Say, hey, you, please, you are ready to receive 1 GB of this disk, a portion of this disk. So you can call it test PV. And there's a test deployment here. And the test deployment says, hey, I want to claim that PV. So here is a claim, PV, PVC, claim, so I'm going to claim the test claim, our test PV. And that relationship establishes. So it's going to lock the test deployment and mount this 1 GB space and the slash path that we have chosen from this export. So now this container running this deployment should be able to read and write through the NFS server all the way to this disk. Let's go see that. And so this thing seems to be running and I'll go and inspect what do we have. So I'm going to erase my ink again. And then we will inspect what do we have. So k get deploy, how many deployments we have. So we'll see that we have a few deployments there. What have we got? Well, we'll see it again. We have a NFS server deployed. It is ready. It is up to date. It is available. We have a test deployed, which is ready, available up to date or the 91 seconds ago. So now we'll see the part that we have, k get PO. How many parts do we have? Well, there's a NFS server part in the deployment for NFS and there is a test part in the test deployment. Let's see how many services we have, k get service. And so I have a Kubernetes service, which is built in, that one. And then I have created a custom service, which is this service, which is NFS service. And that service maps to the NFS deployment here. And that is the IP address of my interest, which is the NFS server service IP address. It's a static IP, exposes these three NFS ports, so I can do my export import business. I mean, sorry, my NFS exports in that IP address over those ports. That's where NFS is running for me and is directly mounting a disk externally stored that you can see here in that location. And that's where the disk is, that disk will pop up. So that disk is that one. Now having seen that scenario, let's go see a couple of other things. First of all, k get PV. How many volumes do I have? So it tells me that I have a volume. This is the actual volume, 100 GB allocated as read write once. And here is your read write many. It is bound to this claim made by this deployment. And that pod. Now we have also another thing here, which is test. Test is also another volume, which is read write many. Many containers can concurrently read and write because of NFS locks. It is also bound by a claim called test in the CG, cloud genius storage class. So it's a fictitious dummy class I created for no reason. And you can call it whatever you like. It has no meaning. You cannot leave it blank though, at least not in digital ocean. In other clouds, you can leave it blank. It doesn't create a problem. But in digital ocean, I used to just use go blank, like nothing. And it caused problem in digital ocean because they expected a string there. So having seen that, we'll now see the PVC. Like right now, you're looking at PV. I'm going to now inspect PVC. So here is k, k get PVC. And that's what you see next. So let's go see this one. So we have a claim. This is PVC claims. The claim is bounded to that disk, which is here. And that is the same disk, read write once. And the other test claim is bound to the test volume, which is that volume, one GB, read write many again. And this is the same class of storage. This is the NFS class. I should actually rename the CG to NFS. That makes much better sense. NFS storage. That should be the name. I think it makes more meaningful sense than just calling it CG. So just read it as NFS storage class. And that is the class of storage available to us for the last three minutes and 17 seconds in the test scenario. And the claim is a slightly older claim and the volume is slightly delayed, but whatever. But I'll clear my drawings again. Now recap, this thing is an important idea. So here you are looking at your deployments. We have NFS server deployment, test deployment. Here you have pods, pods that are part of the deployment. You have a server as a part of the NFS server deployment. That's a pod, PO pod, and a test pod, PO pod, test deployment. Your test does not have a service because we don't need it to serve anything. We need to do grant work for me. And what it does is actually backups every night. And so that's that test pod that also helps me test things. So it has a bunch of tools loaded on that pod that lets me do whatever I want once I go into the pod. And I will go there right now. Here we have services. We have one built-in service from Kubernetes. And then I created another service, NFS server service. And that is the IP address of my interest for storage, the NFS storage class, this one. That's where it is actually exporting on that IP on these ports. That's a custom service we created that maps to the NFS server deployment, which is actually running in this pod. Having understood the services and pods and deployment, these ideas about PV and PVC should be simple. You know, you have a disk and then somebody claims it. So this is a PV and that's a claim. So it becomes claim as in PVC, PVC, PVC. And then you have a portion of this claim that you export as another PV. And then other people can claim it, PVC. And that's the NFS scenario. This is NFS storage class kicking in. Whereas this scenario, you have DigitalOcean block storage scenario. That's the storage class in play. This is actually a real SSD somewhere in DigitalOcean. This is NFS server exported from that service IP. So that's the PVC discussion that I want you to understand. And now we will go inside the test deployment, which is this one, and actually inside the test pod, which is that one. That's where I want to go to the pod and then see what do we have, whether we have storage and what do we actually contain? Can we read and write and things like that? We'll go see that now. So I will say, okay, get PO. So you've got two pods. I'll say K, connect me to the test pod. I get connected. Now I'm inside the test pod. You can see that this test pod is actually running Ubuntu. So here is your name, it is Ubuntu. And here, actually, is it Debian or Ubuntu? The same thing, I think. Let's go see, check. Star release should say, I think it's Debian, it's Ubuntu, sorry, yeah, Ubuntu OS. So the underlying kernel is Debian kernel. That's where the upstream is Debian or Ubuntu. Ubuntu is derived out of Debian. That's why you see Debian here on Ubuntu machines. But this is Ubuntu. So it's slightly upstream from Debian. No, sorry, the streaming thing is that the mountain water flows down. And so this is the mountain, this is the ground. And so the downstream is Ubuntu, and upstream is Debian. And so water flows from Debian to Ubuntu, Ubuntu receives it and then packages it up like this. The actual origin is from here. That's the underlying idea behind upstream and downstream. And the top of the mountain is Linus Torwards, where he creates kernel. That's where things flow from. Everything flows down from there. So that's the underlying idea of upstream downstream. But having seen this idea, we have a connection to the pod running test deployment. So I will now play with it, see what we have mounted. So we will go and clear and then check what we have in the disk. So hello, we are PWD. And what do we have? And so we see some files there. Let's see what files number one, cat. Oops, cat index. And what do we see? So this is a file saying hello from CloudGNSS NFS server. That is the storage that you are exposing from the server NFS deployment service, NFS service. Excuse me. Now, let's see the other thing, cat test. What do we see here? Well, it shows you that there is this entry that you saw, which is coming from this file. And it has this string here. If you match this string, it is actually matching the string of the deployment pod. And you see the times, whatever that time is. So it is that again, what's the time here? The time is March 12th, 1, 7, 15, that's UTC, by the way. So I will now cat it again. And you will see something changed. What changed? This time changed. This time is actually a printout of a file. See that? It is the same container in the deployment, same pod, GWSH6, the same name. But the time changes and you can keep catting it and you will see that every time it gives you a new time because that container, the test container is actually dynamically changing the file as it runs. And you will now see this in the code in the container itself. That proves you, by the way, that it is actually writing a file on the mounted volume, which is this, which also stores the index HTML, which shows you it is coming from the Cloud Genes NFS server. And it is dynamic, meaning the timestamp changes and you will cat it one more time and inspect. So here we go, cat index and cat test. And your different time comes up right there. It was this. So it's every few seconds or so, it will automatically rewrite that file with a timestamp and the pod address. This pod needs to die now. I kill it. But you know what? The beauty of Kubernetes is even if a pod dies, it doesn't matter. It automatically creates one. So you remember the name here, whatever that name is, 6, 7, GWSH6, I'm going to kill it now. I'm going to shoot it for no reason. And you will see the next exercise popping up now. I'm going to come out of this cluster, come out of the cluster and completely come back to my machine. I say, K, get PO, get my pods, and I'm going to kill the test pod. So I say, K, delete, delete, PO, test. You die. So it dies. But that doesn't mean that the deployment is gone. It means only the pod dies and a new one gets created. That's what's happening right now. And it should not take that long. It should die quickly. But I'll let it die. Let it die its peaceful death. In the other screen, I'll go and check what do we have. K, get PO. And so we now have it is terminating. It is slowly dying a painful death here. But a new container is already running for test. The test deployment is going to make sure that you at least have one replica. That's what you asked for. So if you have one replica in the test scenario, you ask for how many replicas we ask for? One. So one replica is going to run no matter what. And that visibility inside the cluster right now is only through command line. But you can have various tools like the dashboard tool if it works. And it will work. I'll just destroy and create it again. It will work. Sometimes hiccups happen. But dashboard is not that critical. You see that this container dying because I killed it and this container started to run, which is a different name, by the way. Just note the name. The name is GN7XJ, whatever that number is. Before it was GWSH, whatever. So now I'll go inside this container and see what it has inside. And there I go. Okay. And there I see that I have files, the index file. And then I have the test file. You see what it does. See what it shows you inside. That's the important part. See the name is what is popping up here in the file. And the timestamp is more recent than the one before, the one timestamp you saw before. It is dynamically writing that file every so often to prove you that it is actually accessing the shared storage, even though I killed my container. And I can kill my entire deployment and show you persistence now. I will do that next. So I killed the container. I will now come out of the container and kill the deployment itself altogether. So here we go. Coming out of this scenario, exiting, I get k get deployment. So I have my deployments, a test deployment. So I'll say k delete deployment called test. The whole deployment dies and this time your POs and all the parts will also die and they'll not come back because I killed the deployment itself. So it is not going to come back again to life on its own because I killed it completely out of the cluster. So I k get deploy does not contain test anymore. Now we see k get PO. We still have the pod dying. For some reason it is taking a little longer, it will die. The other pod disappeared, by the way, it is terminating right now. So having seen that, I will now create our, sorry, what I'll do is I'll actually say Terraform, can you help me? That's the best way to handle. I killed my deployment by accident. So say Terraform, apply, so Terraform will go and look at your cluster inside the cluster and find out that your deployment needs to be created. So here Kubernetes deployment test, green color showing it needs to be created. So it will create one and here local cube config need to be refreshed. So we're going to refresh that and then there are two things to add and one thing to destroy. The old cube config dies and new config comes in and the deployment gets created. So I'll say yes, and now you will see the deployment gets started. And as a consequence in the deployment, there will be one pod. And we'll now go inside that pod and you will see persistence. So here we have k get deploy, oops, typing mistake, k get deploy, we have two deployments now and we get k get pods, we have two pods now, the first pod we have, the second pod is test and that pod I want to go inside, so k exec test, and then get me a bash prompt and then I see my listing and then I cat my index and I cat my test and you will see the pod name and the new timestamp, here's part name and here's your timestamp. The date timestamp is slightly different than that one because like five seconds ago. This is few seconds ago, 10 seconds ago. And that same name shows up inside the file, this is the timestamp, this is inside the file. And that's what you see is actually persistence in action. You can also see that I can totally destroy these droplets altogether. And in this cloud, they don't have auto generation or droplet automatic scaling yet. They're building on it, working on it. So make, you can kill a machine, it will not appear by its own, I think, or maybe you cannot grow and shrink the cluster automatically on its own yet because this is a baby cloud or I should say what's the right word to say. I think it's a developer focused cloud, it doesn't meet enterprise expectations. It is still good and I like it, but I don't think big companies use it extensively for their mainstream corporate deployments because of some missing features like here and there. They're building, they're working on it, but I think it is still a good one to discuss because it gives you the clarity of visibility of what's going on. That's the reason I like to use this cluster, this cloud also. But so that's why I'm not able to demonstrate this killing of machines themselves. I can do that in Google Cloud because they support automatic growing and shrinking and kill a machine, new one pops up, all of that is completely hands-free automated and you don't have to worry about a thing. I can, by the way, show you this scenario of killing a machine and then the machine comes back online, all that in my live website and you will not see a difference. I can shoot the machines and you will still see that sites are still functional. I mean, there's absolutely no reason to even think about worrying. That's the point of Kubernetes. Having seen this scenario, we'll extend our exercises even further and we'll go build all the way to the end where we have an end user visiting real HTTPS, TLS enabled site and all that good stuff. That's what I'm going to build towards, which requires us to go look at our code again and move some files out of the whole area into the main folder. So what I want to do now, now that we have a cluster and we have tested it out and we know that we have a disk that exposes itself via an NFS service that exposes, creates shares for other containers. So what I want to do actually is to have... So we had a test and it was able to make a PV, PVC claim and allocation of disk from the NFS solution. This is your 100 GB PV, and that was a claim PVC and this is in the DO class, DO class of storage. These classes of storage are the CG class or the NFS class of storage. And so they are read, write, many, multiple containers can write on the same file system at the same time because of NFS implementation is beautiful. This is not read, write, one, not many. And that's how this PV is implemented by DigitalOcean. So that is something that you have to understand it. On a disk, you can map a disk directly to only one computer at a time. That's what the scenario is coming in from. And so that's what the underlying logic behind RWO is. But this is RWM or RWX as they call it, many. So any number of containers can read and write on the same volume exported through NFS. So that's the beauty of NFS in play. Having seen this, what I want to now do is run a bunch of other containers also on a our setup. So we have the scenario will play like this, disk, NFS, and then exported. So you have test running here, we'll leave it running, or maybe kill it, I don't care. That's verified, validated. And we want to create something else here. And that will become a deployment, which will mean that it will be a pod running any number of things that you want, one pod, 10 pods, whatever number you want. That's a deployment. And I want to create a service for this deployment. And I want to have a PVC and a PV for that claim like that, a claim I want to make a claim on the exported storage. And then expose this pod or the collection of pod, they can have one or many pods in the deployment. And I want to have a service map that custom software that I'm going to actually install. So let me draw it here, it's much better. So it will persist. So storage, NFS, test, and I want to create one more deployment here. So call it cloud genius website. Let's call it that. So that's, I think that's the one I think we'll run example. Yes. Yes. That's what I'm going to run. So this cloud genius site is what I want to run as a custom image. And I will just inject and run it like a deployment in that deployment. I will say I will need, you know, N pods. So it will have N pods each running the cloud genius website or parts, for example. And so what I need to do is have a service represent service for cloud genius represent these four pods and expose it to outside users. But users cannot reach here yet. They cannot come in here yet because I need to have a load balancer and a proper way to come inside. So I need to create a load balancer and an ingress point. Ingress. This ingress point lets people from the outside come inside the cluster and map to a service with a name. So that will be a name called stage.cloudgenie.us. That's the name that I would like this person to go. That will take them to the load balancer IP address, which will drive them inside the cloud genius ingress point, which will map it to the service endpoint, which will map it to the pods, which is a part of the cloud genius deployment, which is mapping a volume PV PVC volume through NFS server, which is ultimately connected to the hundred GB disk that we have. That's the complication that we are trying to build. Now to build this, there are bits and pieces needed to make this puzzle complete. And that one of them is the deployment for cloud genius. Another one is cloud genius service. And then this ingress, ingress for cloud genius. And then we have to have a load balancer and a reverse proxy, like nginx reverse proxy. And that solution is another thing that we need to have. And to simplify the installation of a proper certificate for this site with an HTTPS, we need to have a certificate manager software also installed. So we need to have this running as a deployment somewhere here, separate deployment. We have to have this nginx reverse proxy running as another deployment. We have to have an ingress, a service, and the actual deployment for cloud genius website. So you will now see these components come along. To simplify these ideas and to simplify the automation of installation of these big packages, a certificate manager will actually get you real certificates, a reverse proxy will get you a route from a load balancer for the outside user to come into your service through the cloud genius ingress. You have to have these also implemented for which there's a separate tool called Helm, which is a package manager, which is what I think we briefly discussed the other session when we were discussing Kubernetes is this thing called Helm. Helm.sh is what we used to construct a ingress point that this software that I will be using now again in our example, where I will be basically grabbing more items from our, let me see here, that these files, I need to bring it outside from this folder, the whole area into our K8S folder here in that location. So I need to first begin with creating an initialization of Helm software. And that's a lot of piece of code just for initialization. What this actually does is provide, sets a provider for using Helm inside Terraform. What I'm really trying to accomplish here is I just want to use one tool to do the whole thing, create a cluster, put applications, allocate this, do this, do that, create a certificate, basically do the whole show for me. And this is how I really manage in my company. And so that is what I'm building is actually showing you how to get things done for real for actual implementation with completely done properly like you would expect. And so what this is going to do is to just initialize Helm. This is a standardized approach. You can actually see this on Helm website and also on Terraform website as to how do you initialize Helm. So it is not that tricky. You have to basically create a service account for Tiller, which is a corresponding component or server-side component of Helm software. So Helm runs on your local laptop, local, and this Tiller is the corresponding component that runs in the cluster. So that's what you need to have an account, a service account created, and that segment creates that piece. You also need to have extra privileges called cluster role binding. And that's a security feature introduced in later version of Kubernetes without this thing called RBAC or role-based authentication. You cannot move anything at all inside a cluster. If you don't do this, it will not let anything happen, and that's a new security feature built in known as role-based access control inside all Kubernetes clusters, newer ones. And that is something that you have to account for. And that piece here is a cluster role binding you need to create for the Tiller component, which is a server-side component of Helm, which is the software you're looking at. And then it uses Terraform to instantiate Helm, and that's using our credentials for the cluster itself. And that is this initialization step. So I need to grab this output, this tf file from our init folder and move that inside our K8S. Now having seen this piece, I will now look at the next piece of puzzle, which is now that we have Helm software, at least we will have Helm software, what we need to do is to make sure that we can install an ingress point. Now it is very easy to actually install because we can just say Helm, use the stable version of Nginx ingress, use role-based access controls, and use this particular image and this version and go install it. So Helm will install and use the name ng for ingress. So that's my name chosen that I have. That name I have chosen for ingress is ng. That's the name I will go move this file out from here to the K8S folder. I will also use this opportunity to use Helm again to create a certificate manager. This is the exercise that we did not succeed the last time when we ran it, but this time I have figured out what the problem was when we were trying to get a certificate answer. It's not going to work at that time. This time it will work. So this Helm release that we have is going to install a certificate manager software, stable version, and this is also using Helm to install certificate manager again. We have a version chosen for us, 0.5.2, and what I need to do is just drag this file out from our cert manager TF into the Terraform folder, and now we need to have one more thing before our Let's Encrypt actually issue a certificate, and there are actually two more things. One of them is a cluster issuer. So you need to provide your email address. Say, hey, take this and please, please get me a certificate. That's what you're asking. You're asking this registry that is called the cluster issuer for your Let's Encrypt service that you know you will now see it in a live action, and that is the cluster issuer file that I need to grab it from here and put it in K8S so it becomes visible to Terraform, and then you need to have a systematic method of grabbing your IP address that you will receive from the load balancer and putting that entry in Cloudflare. So that's what we want. We want to get a load balancer and say, hey, go to stage.cloudgd.us, and that domain is managed by Cloudflare, and so I need to grab the IP address of the load balancer, IP, from DigitalOcean and give it to Cloudflare, and that needs to be done through automation. So that is this piece of code, and you will see this as it goes live. So I need to grab that Cloudflare entry from here and say, dump it in K8S, and this is an empty file that I need to have to capture the IP address from the load balancer. So that file captures that entry, basically. And now I have to hide the whole folder again, and now ask Terraform, what's the plan? So we'll say, Terraform, can you? So by the way, we're going to exit from this container. So exit and say, Terraform, what's the plan? And so Terraform says, something is not installed, Helm provider not installed, so we need to install it. So Terraform in it, it was not initialized before because the files were hidden from view of Terraform. It was hidden in the whole area, so we'll install that. It will pick up the Helm provider, and now we'll say, okay, Terraform, what's the plan? And so now it will show us the plan. The plan is coming up, and here's the plan, there are eight things to add, eight to add. Let's go see what those things are, eight things are. So here, we have to add a Cloudflare record, so we have to create an A record, like A record, and then we need to have a Helm release for certificate manager installed, this release. Then we need to have a release for NG for the NGDEX ingress installed. Then we need to have a cluster role binding for Tiller, the Helm corresponding component. We have to create a service account for Tiller. We have to have our configuration refreshed. Those are the things that we just discussed, and this is going to create that. And there are two more. There is a cluster issuer that we need to provide our email address to request at SYNCRIPT. Will you please give us a certificate? And that's where the request for cluster issuer comes in. You will see those in action once I go. And this file basically grabs the IP address from the load balancer and makes it available to Cloudflare. So the Cloudflare will also update as a consequence. Now let's say Terraform, please apply. And so what Terraform will do is ask you for permission and say, I will go and do it. So it says, I'm going to do these eight things. Are you ready? So I'll say yes. So it's going to do it now. So it's going to see that it's going to install. Let's see what's going to happen right now. So yeah, it's installing the NGDEX ingress and then things are happening. So we have to wait for it. It's a few more minutes and we'll get there. While it is doing that, let's go examine KGET deploy. Something got installed and at least it's there, ingress controller is coming in, it's not available yet. Test is running, NFS server is running, NGDEX ingress default backend is available. Let's see more deployments, KGET deployment in all namespaces. And let's see what we have. So here we have all the namespaces defined, like this was just the default namespace. Now we have all namespaces here and there we see NFS server, we have NGDEX ingress controller is now available. We have test running, we have CLM operator, cert manager is also available and running. Core DNS is the internal DNS server for Kubernetes cluster. There is a Kubernetes dashboard also running, I need to kill it and get it to work, but I'll do that later. Tailor deploy is the deployment of the server-side component of Helm that is also running, which means our things have happened, which means you should go back to the other window. And it tells you that it added eight things. And by the way, this Cloudflare is already updated with this correct IP address. So let's go see it. I didn't do anything. I just sat here and ran Terraform apply, but if you can now go dig and say stage.cloudgenie.us and what do we see? We see that IP address from load balancer popping up already in our DNS. So this IP address came as a result of a value from the creation of a load balancer. And that execution is already mapped to the domain in our Cloudflare account, at least in my Cloudflare account, and that IP address shows up. That's a required step for a certificate to be issued. The certificate issuance happens when you first request for a certificate. Hey, let's encrypt. Would you please give me a certificate? So your machine, we need to specify, I need to get a certificate for this name. And would you please give it to me? And when you request that, then let's encrypt will come and challenge you. Challenge. Prove it to me that you are indeed this name by, I will go to that name and you should respond. And that response, challenge response happens automatically through the cert manager software, which we also have running in our Helm deployment. The cert manager will respond and say, yes, I am that IP address. That traffic will arrive here only if this IP address is correctly mapped to the load balancer. Otherwise, it will not come and you will not receive the challenge and the challenge will fail and you will not get a certificate. But I don't think that's the scenario right now because we have our IP address correctly mapped. Having seen that, let's go forward. So now we'll examine, quickly examine our deployments and our KGET services in all namespaces. And here we have our Kubernetes service, the NFS service, the NGINX ingress controller load balancer IP address, the front end endpoint. You can see that the default backend showing you it is available at port number 80, kubeDNS and dashboard is for some reason not working. And Taylor is running. So yeah, we'll kill the dashboard later. Let's go forward, forward with the idea of actually running something live. So here back to our atom editor, we have our hold area contains a bunch of things. For example, this thing, the cloud genius course book file, that file. This file, I need to move it out from hold area into the Kubernetes folder. And we need this and that, this and that. No, I don't need these guys. They're kind of pointless. So with that file in place, what I'm going to do now is run Terraform one more time. And what will happen as a consequence is that now that we have in our design, what we have constructed is, draw it again. By now we have a load balancer with an IP address that is mapped to the stage.cloudgd.us. That domain is not active yet because there's nothing running. But if you dig, it will go to this IP address. And then there is a load balancer, there is an ingress, nginx ingress called ng deployed. And inside there is an ingress for cloud genius that I will create. There is a service that I will create for cloud genius. There is a deployment that I will create for cloud genius. And there is going to be a PV-PVC relationship from the NFS server. And the NFS itself has a PV-PVC relationship between an actual disk. And that's what you have the whole chain. Now this is where the cluster stops and the load balancer is an external item from the cloud company. So now you can see that load balancer and this IP address visible to us from the cloud company's portal. So here is your cloud company and here's your networking section and the load balancer shows you that the IP address is that one. That's what we have for our result, somewhere here. And so that's the same IP address. So we can see that this, by the way, is the load balancer that tags to three machines that we have. And why is it showing you down, like status down, healthy droplets? That's the reason why. Okay. I don't know why they're down, but I know the reason why the dashboard did not work is that these guys are down for no reason. That's the problem that you'll see when you see less than stellar cloud services. This is what happens when you have really good services like from Google cloud. I have never seen such problems. Occasionally you see this problem, the machines are down, healthy, not healthy, boo, bad cloud. But I still like it. I'm probably partial. I don't know why I like it. In spite of, I just showed you a problem. So the reason I like it is because it's easier to digest from a learning perspective. That's the only reason. I don't actually run my services here. As you can see, most of the time the cloud is empty. But this is bad. Fixing it is easy. You can just say Terraform, apply the whole thing, and you destroy the cluster and say, apply it. It'll create the whole design effortlessly. Having seen this idea, what I want to do is look at our droplets. Are they functional? They should be functional. They are functional, but the connection between load balancer is not functional. Hmm. Issue. What's the issue? Well, later on, let's see if we can actually get the exercise to work. Otherwise we'll destroy and create the whole thing. It takes five more minutes. So back here on the Terraform apply segment, so we'll say Terraform, what's the plan? And so Terraform will read what you have in the cloud versus what you actually want. And so here we say four things to add. So let's go see what the four things are. And they are to create a cloud genius deployment. It's called course book UI. That's the name I chose. And so that the deployment gets created, then we have a service created for cloud genius and then a local cube configuration and an ingress point created for cloud genius. So this ingress is how the NGINX ingress will actually map out to the service that I'm creating. From the picture point of view, the thing that we are going to create right now are this one, two, and three, the ingress, service, and deployment for cloud genius. Those three are creating created. We have other things available to us already. Other things are already available and running. This portion, we have it, there is an ingress running, there is a load balancer running, the DNS map correctly, the PV-PVC relationship, NFS, this part is tested, that part is examined. This is a missing puzzle. So we'll now say Terraform apply and see what happens. So we'll go clear my ink and say, hello, please apply. So what it does is actually goes and installs the cloud genius custom image. That custom image is what I need to say yes to here. The custom image is what actually goes to and it quickly apparently. So let's go see what KAA get deploy. So we should see a cloud genius entry right there. It is not available yet. Now we'll see KAA get service. And we should see a cloud genius service right there. And that's that port. It's a custom port that I use for that software that I've run my website on. And that image that we are using is the cloud genius image, which is a private image. And that's why I have this KAA get secret stores my registry credential for Docker Hub. That secret is stored in that secret value. This is how it's able to grab the image, the private image that I store in that location, in the Docker Hub location. So that I need to provide my email address, password, login information right there. I also have my Amazon credentials in there, which helps my test machine backup. It also acts as a backup tool. And then we have one more thing here. So we looked at a deploy, we looked at the service, we now need to look at the ingress endpoints. So KAA get ing and this is our first ingress. So this is going to show you the ingress for stage.cloudgenie.us and it is probably succeeded. Let's go inspect. Let's go inspect the logs for the certificate resolver. So apparently KAA get PO and the resolver is running, which is a bad sign. It should have finished by now. But let's check, curl. And we have a bad certificate. So that's a problem. So what we can do in this scenario is what we will do in most scenarios. If such a thing happens and when you have a broken setup, like you saw the load balancer showing issue, that's what's causing some problems apparently somewhere. The best way to recover from this setup is very easy because what you can do is set terraform destroy and destroy the whole thing and say yes to it. And the whole thing disappears. And we'll cross check whether it actually, I think it may not actually clean out completely because of the issues here. So the cleaning out we have to probably do by hand. So say destroy, please, and destroy your cluster, please, like that. And say the name is Andromeda and destroy our volume also. We can leave the volumes alone and so we can say destroy the volume. So the volume goes away. Now we have no droplets, we have no cluster, no volumes and no networking, load balancer and so on, nothing. Having seen we have destroyed the whole thing. What I will now see is git status to see what files are missing. So there is a back to DigitalOcean, back to Google, modified nginx ingress. I need to remove the ingress nginx IP address. It contains the current IP address, which is also not going to be valid anymore. So now I have the ingress cleaned out from the old IP address. I'll also go cross check my CloudFlare entry, which is probably need to be deleted. CloudFlare entry and we go login in CloudFlare and delete that entry for that domain and the DNS entry for stage where we have this page and hello, the domain is the name correct. Am I typing right, S-T-A-G-E, oh that one got deleted already, nice. That's good. So we need to now be able to say terraform, delete the state files we have here, two, three state files gets created like backup and tf.state, I need to delete them also. You don't have to, but I'm just cleaning out so that it doesn't cause any confusion. Oh, say no, no, no, no, no, no, that's not what I want to do. So I want to remove, I want to, I think I made a space in there in between terraform. That's a bad mistake. Okay, now you delete these two files and now we have git status checking. These are useless files. Okay, I'll check my status visually also. Yeah, I think we are good to run. And so I will now run it, the terraform plan and apply, actually just say terraform apply. So this should do the whole thing of 20 things in here. I'll just say yes to it and let it proceed and we go review what it's going to do. So it's going to begin from beginning, like absolutely beginning from the first thing it does is first thing it does is to create a cluster. And so Cloudflare entry is not actually, this is not sequential, by the way, it's a graph with a dependency structured in between. So don't read this like a sequence. It is just showing you from alphabetical order, but it is not a sequence. There's a dependency map structured inside your terraform that you will see in a visual form when you say terraform graph. So you can see that you say terraform graph and you can see the graph popping up and you can see the terraform graph and.png and all that. While it does the actual implementation, we'll go inspect the terraform graph. Now terraform graph like that, yeah. Please create a graph for me and show it to me like this. And so now to open the graph in a visual form and show me that graph, please, in a browser like this. And so here is the graph. It's kind of bigger than the previous graph we saw. And you will see, I'm going to shrink it a little bit. There are 20 things as opposed to less from before. So I'm going to adjust the width of my screen. And it is way too difficult to even read from a video conference. I don't think you can read on a video screen. It is too small even for me. So I need to zoom it in a portion and it is actually, it doesn't even fit my big screen. So that's a problem. But you can go read it part by part by zooming in portions of this and going through. And so you can see all the ideas that I've been discussing all along in a visual graph fashion with dependency structure, beginning from the root level at the very top. From the root, it goes out and builds every single thing that we ask for in every single scenario inside your Terraform implementation that you are looking at here. It's going in the other screen here. So it is probably still doing it. So it first creates a cluster and then gets the handle of the cluster and then starts to inject your images in deployments and services and connect them all together with PV-PVC relationships. And I have the NFS server start, create another volume using NFS to create exports for other containers to consume, create a test setup, create a NGINX ingress, HEM deployment, certificate manager or cloud genius website, connect them all together, go to CloudFlare and inject your public IP, come back and ask for a TLS certificate, and then go to that authority and I request them to grant a certificate. And that is what is happening right now. So we'll see what works, what doesn't, and we'll figure out what's going on. So we'll wait for it. It's doing its job. And so this is what is going on right now. As you can see, the graph is big and you can make it as complex as you want. There's no limit to how you want to accomplish, but the ultimate idea behind this tool is just sit back, relax, Terraform apply and enjoy. That's the whole point of this exercise. We'll see what actually we're able to see as an outcome of this. And there is one gotcha that I should point out and that is an academic gotcha. It's not a practical gotcha, it's purely academic in nature. And that is that this let's encrypt authority, it has rate limits. And that's a gotcha for me. You will probably not run into it. I'll tell you what the gotcha is for me. The gotcha is that you can request this authority to give you certificates only so many times every so many days. That's the rate limit. Now being a person who likes to experiment and likes to talk about and describe to other people, I might be at a point where I'm actually hitting the rate limit because I'm probably overdoing it. Not everybody does it like this and that's okay. That's a normal usage. But in my case, you know, probably have run this destroy apply many, many times, probably one too many times than the rate limit. If I'm there, I'm screwed. I will not be given a certificate. That's a gotcha. I just want you to know that. That's not going to apply to you because you're not going to be like running a boot camp showing people what's going on doing the same exercise 10 times in a day. That's where rate limits kick in. So I hope I'm not that point yet, but we don't know. We'll figure it out. That's a gotcha. It is probably just for me, unless you are as crazy as I am, in which case you will also run into the same gotcha. Having said, let's see what happened. So we'll go and look at the other screen and see what has actually happened. By the way, if you want this picture, I can paste it for you. You can examine it, zoom it, and look at it trauma. You generate your own picture. I paste the command. That's a better way. So the thing finished. Awesome. The thing finished creating 20 things. Beautiful. So now let's see. Okay. Get PO. What do we got? Well, things are running. Nice. What about K get deploy? All namespaces. They are also running beautiful. K get service. They're also running. And our NGINX ingress controller has a load balancer with a public facing IP address as this. And so now let us see if we can dig stage dot. That is also working. Beautiful. That IP address mapped up. What about K get PV? We have two diskettes. So one is a test PV. The other is a PV, the actual disk. And K get PVC with two claims. And then what else we have? Helm list. Helm has deployed two applications for us, sort manager and NGINX ingress. Then what else we have? We have the dashboard that I did not install yet. Let's get to the dashboard later. It's not installed yet. So I'll do that separately. I've kept it separately because I don't actually need the dashboard. We can just do the whole thing on a command line just like we're doing right now. But the thing I want to check now is the logs for our certificate manager. So this sort manager deployment that we have here, this sort manager that will have a deployment. So let's go K get deploy all namespaces. And we look for the sort manager deployment right there. And now in that deployment, I want to get the PO. So K get PO for that namespace called cube system. This thing certificate manager runs in the cube system namespace. So we're to go get that part from that and we'll go inspect its logs. So these are the parts running in the cube name, cube system namespace. And for that particular certificate manager deployment, there is this certificate manager part. And that's the part I want to go log. So I'll go inspect the logs in that. So K logs you, please show me the logs in that namespace called cube system, please. And here are the logs and see what do we have. I think self check failed for domain. It says the re queuing item error due to processing HTTP self check failed for this domain. Already exists. So it's kind of confusing. Logs are confusing. It tells you at one point it's saying 404 challenge, then at any time did it say certificate issued, preparing certificate for, so it is requesting a certificate, no doubt about it. So that request is going on. Let's go visit. Let's see what happens. So here is the browser, Firefox, and go to that site. The site is called stage.cloudgenie.us. So let's go see what happens. Stage.boom. Did not get a certificate. Oh no, no, no. This is okay. We have to go and examine what's going on here. Security policy, which means Firefox, I think we need to clean up the cookies. So this only I run into these problems. You probably don't. I don't think the certificate got issued, although it would have said the certificate is issued, but I did not see that in the log entries. So we'll clear the data and clear history and quit from the browser again and start it to see stage.no, advanced. So I'll accept the risk and proceed. And what happens? It is waiting. Waiting to see what? Timeout. That's not what I expected, but we can go and debug and I'll walk you through how to debug these things. The actual result is, you know, they have probably a failure on the log, which it shows you that it doesn't actually get the certificate because it tells you that there is an error processing. I don't know what the error was. We don't read this. So it did not actually get a certificate, so that's what you have the issues that we have running. Otherwise, it would have said clearly that, you know, here is the certificate issued and it is saved and operative and all that, but I don't see those entries here. But apart from that, are the services running for the cloud genius side? Let's go see the services. So the ingress that we have, kaget-ing, should show the cloud genius ingress, which is this entry that you're looking at. This thing, entry maps to the service that we have, so kaget-svc should show the corresponding service for cloud genius also, which is this service. And let's go see that whether it actually gives you something running. So we'll go and inspect from inside that container that we have. That one, that's not a container, the container is here, kaget-deploy. This is where the containers are. So this is where the deployment is. There is one available container. That's what we have to go inside. So kaget-po should show us that container, which is this container and it is running, which means it is functional. So the only issue that we have, I think, is the rate limit issue that I suspected is going to be hitting us because just too many times doing the same exercise over and over, I might have run into that issue. So I'll go and examine that, but let's go check the course book UI, the part here itself and see what is going inside the part. So kexec, IT, course book UI, go inside the part like that, and there we have ES. And we have our app running. So here PM2 is running our JSON file and the servers are running and the worker is running and the server is running. The two servers are running our application already, which means we can curl it here. Curl not found. This is just how containers are. They're so tiny and so small that they don't contain software. So I cannot even curl like that, but let's recap what we just discussed and did. What did we do today is that we used Terraform to actually construct a full end-to-end service and we missed the very last piece, the HTTPS piece. We also see if we can get the dashboard running. So I'm going to say dashboard. Can you please get me in the dashboard running? And dashboard is not working, which will probably indicate us if it works, we'll be able to see the cluster visually. So I'll say kproxy, get me an access to that website, which runs this on local host. So we should be able to see this cluster from a graphical perspective from that point of view where I'm expecting to see the, and no, it is timing out bad, bad Kubernetes, sorry, bad digital ocean. This is bad digital ocean. You can run the same exact exercise in Google cloud and it is written down for you here in this site. You can go and say cloud computing, let's begin and then go to the bottom and the enterprise grade Kubernetes orchestration site and say start now and go to the next one and scroll down all the way to the bottom in the optional area. So there is an optional area here. So here we did this exercise, we have bring up a cluster and all that that we did ourselves, but there's an optional segment here and that's where you will see that there is a alternative approach defined here using Terraform to do the same exercise that we have already done manually and that is this repository, which is basically the same repository that I ran, but I ran it with a different cloud. This is the repository for doing the same exercise on Google cloud. This will work. The one I did, did not. I mean, I am not satisfied with what it did not work the last very last thing, the rate limit issue. I think rate limit, let's encrypt and there is no way to reset those. So here is the rate limit. And so the rate limit is, there we go, limit of five failures per account per host name per hour. So if you have made a mistake, like if there is an issue in your DNS mapping and you try and ask for a certificate without actually making a correct request, then you're getting a hit saying, you know what penalty, I count one failure, I count second failure and like that it accumulates failures. And so that's the limitation. So I had to wait for an hour before I can request another one. And then I'm still again limited to five failures per account per host name per hour. That is the limit and there is no way around it. That's what you get. So there is a request for request for resetting the limit and the answer is no. So can I reset, can limit be reset? Unfortunately, no, it's a hard limit. And that's, that's what I, people like me run into, but use this approach and you will not run into problems because it is a better cloud than this one. So I just want to experiment with all possible clouds and that's the reason why I have built both exercises in both clouds. This Terraform exercise already is available for you. You should run this and it will accomplish the same ideas. Of course you need to follow through the step sequence written down in that site. So check out the repository, download a JSON file from Google cloud like this picture shows you and then create a provider for Google and initialize Terraform and then Terraform plan and then Terraform apply that will get you a cluster. That's how, that's how it goes. And you can then start deploying your YAML files for any application you create. And there are examples in the repository itself that you can actually play with. So with that, I'm stopped recording and I will like to tell you that I will be speaking in Boeing in your weekly Webex sessions. So it's like open to everybody inside the company on April 8th on zoom. No, no, it's not zoom, it's Webex, Webex. That's what your company uses. So you have invited me to talk on this day. So there is this new series starting up in which people will come and talk about cloud and that's the session that I will be talking on. You can see me on video conference, internal Webex, open to everybody in Boeing, I think. That's what I'll let you figure out. If you need access to that, ask Brad or other people in the Kubernetes team, they will get you access and I will be speaking about something that we will decide. But that's the date, April 8th. You will see me at 11 o'clock Pacific time. And with that, I will now ask open for questions, which I am already always on. So I'm stopping the recording, by the way.