you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you you back on the other computer. This is like a other machine that I just started to let you know. I will be projecting from the other computer just a second. I'm just logging on to the other one. This was giving me trouble. I hope you can hear me. Did you hear me? Yes, we can hear you. I'll be online on the other machine in just a second. All right. Thank you. Thank you. Okay, I need to take control of the host. I will switch away from the other computer and be on this machine going forward from now. I will be going away from one of the machines, which I am testing my microphone. It should be working on this regular computer also, I hope. Okay, I think we are back in business. There was some hiccup in an update that I did to my laptop, which I use primarily, and that was the reason why it was giving me trouble in signing on. I should be visible to you now, and I am also going to project my desktop. And there it is, projecting my desktop right now, and also making sure that I'm sharing my screen, which I think is going on. Now you're sharing the other screen, probably. Not yet, not yet. So the sharing of the desktop, what just happened to it? We can see it. Okay, hold on. I think it's not sharing my desktop, or maybe is it? Let's see, can you see my notepad opening up? Yes. Okay, good. I think we are back in business. There was a delay in publication of the video recording from the other session from two days ago. I think that something went wrong in the publication. As a consequence, it did not go online immediately, as I expected. But this morning, I think Alexi emailed me, and you will notice that that video is now available online. What were you doing up at like six in the morning? At six in the morning, I was preparing my tax paperwork. I do every single thing, almost from janitorial work all the way to management, business administration, writing contracts with Bellevue College and other colleges, financial accounting. I'm a CPA, I'm an attorney. Yes, I am an attorney in India, not in this country. So I do almost every type of thing that is needed to run a business, including my own taxes, which I've been doing for so many years. So that's what I was doing. Like six o'clock in the morning, I got up and found time to finish off. And then I saw your email, Alexi, which is that I noted that this video was kind of missing, which I think it is available now. So let us quickly get to what I want to talk about today, which is what I would like to bring to your attention is a change in the way we think is what I want to bring in how we deal with machines or rather infrastructure, I should say, as opposed to dealing with what I would like to say is the frame of reference in terms of how we think different is what I want to actually start maybe in the rest of the program is to think like this. Whenever we think of some kind of a resource, which is one of these three types, compute or a storage resource or a network resource, we typically tend to think about some kind of a machine, like a box in a box with a CPU and some disk and things like that. That's how typically is a thought process. I would like us to transition away from this mode of thinking into the other other world. This other world is, again, the same set of resources that they're common, you know, everywhere we go, that is how we will be dealing with. However, our frame of reference in how we think how we operate, I want that to be a slightly different approach towards thinking, which I think you probably already know what I'm talking about, but I'm just going to call it out. I want us to think in terms of containers. That's the fundamental shift that I would like to you to keep in mind as to how we think about things as we go forward in the boot camp, in the remainder of the boot camp. So most of the time, we will focus our energy, our attention in this frame of thinking in this frame of operating in this style of working, making sure our applications work, making sure that, you know, we accomplish a business goal. We will, of course, need machines under the hood, under the hood, as in, you know, at the foundation level, we will have machines, of course, but from an applications perspective, I want us to think like this, you know, totally for every single thing that we can do, we should use and operate in containers and not don't don't really think the old way of thinking, which is, you know, get a machine and operate on it. That's necessary, by the way, it is absolutely required that you have to have a machine or maybe a bunch of machines. But the frame of reference of thinking is what I want you to transition from here to here, that transition has to mentally happen in our minds. And that is something that I want to, you know, make sure that everybody gets it. I think you will get it. So if we're thinking containers, but containers also contain configurations for networks and storage, do you still want us to think in that way with a container that a container still has to connect to a network, open its ports, and it still has to have a volume to save data to? Do we still want to bring those ideas over? Or are we thinking containers just in containers in that sense? No, we will have all these elements also, but in this context. Okay, thank you. So we will have storage, we will have network, we will have compute horsepower, every single thing that you would otherwise expect from the infrastructure, think containers, as opposed to think machine. Like, you know, in typical situations, we'll go to some cloud, and we'll find that the cloud company gives us a machine, like most of the time, you know, pretty much everywhere you go. This is like a new cloud I want to use today. And so I'm just logging in. But bottom line is, you know, if you go look at that cloud in here, as I log in, you will find that it gives you this is by the way, just like DigitalOcean, but it actually is different company. That's pretty much it. There is no other fundamental difference. It's also nice looking and easy to use and all that. And it also has some kind of a coupon available for you to use. And that coupon should be somewhere available in the forum and the in the discuss button on the website here on top discuss. So go through that and then you find a coupon, you should be able to find it. And then, you know, we have more locations than in DigitalOcean and, you know, some server types available. There is this new thing called bare metal instances. But, you know, we are talking about machines again, which is a necessity. I mean, no doubt about that, it is necessary to discuss this thing. But when we thinking about applications and deployment, we need to think more of containers as to how we actually handle them. And what what will that do for us is that it, you know, basically provides a layer of abstraction. This abstraction under the hood, we will have machines. But then we will deal with containers, container, more containers, like that. And we will manage these containers agnostic irrespective of where the actual container resides on which machine, whether it resides on M1 or M34, or M2 or whatever that number machine number may be, we are basically creating this level of abstraction, which separates the two fundamentally, in effect, we should be ultimately able to accomplish a goal in which it doesn't even matter where these are, it's just some kind of a amorphous pool, you know, that's how I would like you to think of a pool of machines. And we really care about these guys, because these guys is where we will be running our applications on. And a pool of machines more than one is how we would like to think about our underlying infrastructure. And inside there, we will have, you know, storage resource, network resource, computer resource that we'll allocate to these guys. And we'll deal with containers, and then have this pool come and go as in as in grow and shrink, as in, you know, maybe in the pool that at some point, we will have like three machines, maybe it can become four machines or grow like that, or maybe shrink back down to three, like that, so that that growing and shrinking might happen. But that's not what we really focus on, because we focus on our containers and have them run on any of these machines agnostic to what the underlying setup is required. That's how we want to think about. And to enable this kind of thinking, of course, we need some containerization technology like Docker, for example. And we will use our tooling that we have been discussing, just started discussing the last time Ansible, that was I think the last 30 minutes or so we did discuss in this video, I mean the session the last time here, for the last 30 or so minutes, we discussed an Ansible exercise. And in that exercise, what I wanted to do is go step by step in the Ansible run, which is something that I wanted to, but I did not actually succeed. If you recall, that exercise of making sure that it runs in a step by step fashion, it required a subtle change in the command execution, which is what I want to briefly tell you so that you understand it. And then we will move on with more Ansible exercises today. And we will introduce the element of Docker containers, introduce the idea of collection of machines put together as underlying infrastructure on which we will run Docker containers. But essentially, our thought process, we are migrating towards using more of containers than the underlying hardware machines. That's what I would, I will bring that to your attention. We'll use more of Docker and introduce, sorry, sorry, sorry, I should say we should introduce the concepts of using orchestration architecture in Docker. And that will evolve into discussions on Docker Swarm as a technology, Docker based Kubernetes as another orchestration platform. These two are very commonly used platforms for orchestration of containers, but under the hood, yes, we will have machines. And that is what we will use to configure, use Ansible to configure those underlying infrastructure, machine level, and then go on using containers from foremost. What's going on with the machine? Why don't bring up? The machine should pop up and it didn't. Something went wrong with this machine apparently, so I need to reset it. And now we will run that Ansible exercise quickly, briefly. It should not take too long. But then we'll jump on to other exercises for today, which is I have a list of them here already. That list should pop up. Where is that list? Come on. Okay. That list is coming up. And on the other end, I am. Hello. Where is the command window? Huh. This is lame. Okay. When this happens, occasionally it does, like it's happening to me right now. If that happens to you, you know what to do with it. You want to go back to the machine, shut it down. You want to go to a snapshot of the machine and the previous known good state, and you want to reward the snapshot to the way it was to begin with. That's what I will be doing, by the way. I'm going to shut down my host, sorry, shut down my VM, or even go extreme and just power it off, like there. And then I will start my VirtualBox software, which is you already know. This VirtualBox, I have managed to preserve a bunch of different snapshots. Like here are the snapshots. The Chef is really ready is the last snapshot I have from six days ago. I want to restore that snapshot. And then that should bring my current state in time, point in time snapshot back into life. And that's what I will be doing. So Chef is ready, should now start. And it is restored in the state of the machine at the time before the Chef exercise began. So it will take us to a new point in time, which is fine, but just want you to know that I am going to be back in time history. So with that, this means that my machine doesn't have any Ansible exercises run as of yet. In this computer, I don't even have that folder which we used to run the Ansible exercise the last time. If you go to SlackChat, you will have a link to that. And that's what I will quickly grab that link. And I have updated that SlackChat to indicate how to run Ansible interactively on a step-by-step basis. And you will find that link should pop up right here. And there it is. Something somebody said, blow it away. What was that? Blow it away. I did not understand Jerome what you said, but yeah, I think you meant blow the machine away, which is exactly what I did. And so what I'm doing now is bringing that Git repository into this machine right here. So I'll say Git clone, and that Ansible first run repository should pop up right here like that. What is going on with my computer today? Okay, hold on. I think I am not liking what I'm seeing right now. Let me go make some fundamental changes to the machine itself. I think that update that happened did not go through really nice. That is the problem, I think. And I will quit some of these guys here. For example, you should go away. Come on, go away. Did they do a Microsoft on you and update? I know this Macintosh, I think it is not, I would not blame them because it is me who is doing stupid stuff. Update the Spectre and the Meltdown, and it's causing a lot of trouble. I know. It is me who is doing this. I cannot blame anybody else right now, because it is indeed me who is causing this trouble. So let's go to basics, which I just did. So back to basics. Our Slack chat, I think I have managed to reset the problem, which should be fine. Back to basics, our Slack chat, I think I have managed to reset the problem, which should not happen anymore, except on some link clicks may not work correctly. So Safari, I should manually open you and go to that location where I have the Ansible first run exercise. I will clone that right here using HTTPS clone, bring it to the machine here and paste. Right click paste, try right clicking. I know, I know. I'll explain to you what is going on. This is crazy atom popping up in front of me without my permission. That is, I understand, but that's not what I want to see. I don't want to see atom and it is continuously popping in my face. So force quit. Come on, force quit, please. There we go. Your keyboard is not being picked up by the VM. I think that is one of the problems. So I'm going to kill a bunch of these guys right now. One of them is this hammer spoon should go, quit hammer spoon. Okay. And sublime text should be quit. And what else I want to quit? Nothing else. This is good now. So let us see. Can I paste it now? Yes. How about now? Almost. Okay. Let's go copy from here like that and bring it to the VM. Please paste. No. Right click, right click paste. Okay. Thank you, sir. Okay. So this machine is getting, that repository is getting cloned right now, which is so slow. Why? When in doubt, reboot your machine. I know. I know. Yeah. Reboot. That's, I guess, I guess that is true. So here we go. Reboot. I'm going to reboot this thing and also reboot my Macintosh. This is bad, bad behavior. So I'm rebooting my Macintosh and also reboot my Macintosh. So I'm rebooting my Macintosh and also in the meanwhile, my conference will die. So I want to start my conference on another computer right now so that I don't kick you guys out for no reason. And otherwise I'll quit the meeting accidentally. So that's not what I want to do. I'll continue my meeting from this other machine right now and resume. Okay. Here we go. So, wow. Okay. Hold on. I hope this VM should function. If it still gives me trouble, I will switch to the other machine and reboot the Macintosh itself. So let's see. Screen. And can I paste from the browser? Okay. Forget the paste part. Let us see if the network is connected. The network is not connected apparently. Connection information. No valid connections found. That's the reason why it was not functional. What about you? Are you now connected? Enable networking and enable again. Please get me an IP address. Yes. Okay. Think. No. No. Wow. Okay. I will, you know, ignore the VM and run the machine and run the exercises directly on the Macintosh. So shutting it down and let it go. This is still functional. This is a disaster. I hate that when it happens. But why did I do that update? Okay. Okay. I have to do not disturb this. And I'm going to straight go to the Macintosh directly. Here I'll be running that Ansible exercises. Ansible first run should be available here. Open Atom right here. And there I will have to make some changes because I don't have Ansible, I think. Or maybe I need to set up Ansible quickly. So I will do that right now. Which is what I will be doing in. Okay. Come on. This thing has thrown me off completely. It sucks. When things do not work. Okay. So that project that I was dealing with Ansible first run is now available on the half, left half of the screen. And it is available on the terminal and the right half of the screen. And what I want to do is list out the items I have. Then I have a readme file, how to run it. So there is a how to run file. And I will read that. The file says remove all these unnecessary elements in there. So all these items that need to go, I'm just removing them. And now we have only the basic minimum things needed for the Ansible exercise to correctly function without unnecessary complexity. And in here, it requires the how to run step actually involves Ansible playbook, Apache MO, ask become and then a dash dash step as opposed to just a single dash. That's the key thing. It was different in the last time when I run, I was running with a single dash right there. Now it has to be dash dash. Now this playbook is designed to run on a target computer that runs on some Linux box, but this is not Linux. So in order for this machine to this this playbook to run on some Linux machine, I need to get one. So what I need to do is identify this host listing that I have, and it is not going to be a local host machine, but it's going to be some IP address from some cloud. And then and the Ansible connection, I will have to mention how it connects to the the cloud machine. So it will be SSH connection. So we can basically delete this item completely from here and put an IP address of the machine that I will get from some cloud, for example, this cloud here, I would like to get a compute instance from Seattle location, and I will get, say, your choice of Ubuntu 1604. And take this machine size. And then I'll add my key pair. And then I'll give it some name, call it test and deploy the machine starts up momentarily, I'll get an IP address here. And I'll use that IP address to put in in the list of hosts that I have. I want to run this play on that target. On the target is going to be this machine that is coming up right now. And that is the IP address I now have. So I'll grab that IP and put it in the host entries right there and save that will allow me to make a connection with the remote computer, which is a list of all the machines I have to deal with Ansible using this folder. So now if I begin and say Ansible, can you please ping? I think the Ansible can you Ansible all dash m ping, can you ping the machines, the Ansible is not installed on this machine. So I will break this. And then I will first of all, quickly set up Ansible, which requires two steps. One of them is work on test. And then do I have Ansible here already? I think so. So I'll just say Ansible all the machines, I would like them to be pinged. So please go and ping Ansible. And so here, it is giving me a deprecation warning, which is something has changed in Ansible. And so the key is misleading. But it successfully, it actually did not succeed in pinging the box, it attempted to ping this IP address, it says unreachable. And it is because SSH cannot connect to this host. So let us see if we can actually SSH to that host. So SSH, and then we'll say root at and then IP address. Let's see if we can SSH connection to that. And looks like yes, we can. And no, actually, we cannot because our key pair is- So that ping is trying to SSH connect? Oh, yes. The ping here is not the usual ping that you think of ping. When you say ping in Ansible, it actually makes an SSH connection. And it's a ping pong bi-directional handshake. So that's the difference between this in case of the way Ansible hooks up. So in order for us to provide this thing, also the remote machine in needs to have Python version 2. This machine doesn't have Python 2 that we have. So we have to enable those setups also, which requires me to modify a little bit. So I'll tell you what goes on in our other examples. Let's see if we can pull up another example that I have. I think this exercise will have a better way to look at the setup in terms of how you configure the configuration and provide the key parameters. So key parameters, you have to specify like this. If you're dealing with a remote computer that doesn't have Python 2, you have to call out the parameters pretty much like this file does. Let's go look at that file in greater detail. You have to provide the IP address, of course, like this. So the IP address I'm putting in right there. The remote user has to be called out like this, line number 10. Then I have to specify that my key pair that I will be using is going to be the key that I have in mind, which is what I just used in this machine. And then I have to call out that the remote computer does not have Python 2. So please use Python 3 because Ubuntu 16.04 includes Python 3. It does not have Python 2. Ansible expects Python 2. And so you have to this way communicate with Ansible to let the remote machine use Python 3 interpreter. So that's line number 13 right there. So I'm rewriting the simple way of handling local connection to a remote connection using the machine name. So here is the machine called test with an IP address of line number 2, like, or rather 3. And then you have line number 1, like, or rather 3. And this line number 4 is the remote user, which is in my case, root. Line number 6 is the key pair that I have on my local computer. And line number 8 is the Python interpreter on the remote side. Now the thing I did like this for ease of readability, but the expectation from Ansible is that all these things need to be on the same line. So I put them like that and save. Now we should be able to connect on the remote computer pretty much like this. First of all, SSH and then make an establish a connection. It is expecting my password because my key chain doesn't have the key loaded in the key chain in the key ring. I should say key. Yeah, key chain doesn't have my key. So let me add my key SSH add. And the key that I have is sitting in here. So I added that key. And now I should be able to SSH connect to that machine. And I did. Now in that remote machine, let us see if we have Python number 2. We don't have Python 2. Let us see if we have Python 3 there. Python 3, are you there? And it is there. So remote computer by default in Ubuntu 16.04, they have removed Python 2. They have added only Python 3 by default. So it don't even have Python. And Ansible uses Python. It expects Python on the remote side. Having said, we'll exit from this machine because we tested it out. It works with a simple connection. Now let us use the Ansible way of pinging in which it involves Ansible. Ping all the machines I have in my host file, which is that file on the this side, which is only one file. Bring all the machines, use the ping module to actually establish a connection and return a ping pong double handshake. So it will go connect and then return a ping and pong, both responses, bi-directional connections established. And there is some deprecation warning, which says that the default host file option, the key is misleading, which can also be a list of hosts. This feature will be removed in 2.8. So you can disable deprecation warnings like this. For right now, I will disable them. We'll handle. So Ansible is changing rapidly. That's why you will see sometimes you will run into deprecation warnings like that, which is a good thing to note. But this will actually generate a clean response of a ping and a pong. So that is what just happened. It establishes a connection. Now, what did we use today? This module called m-m module called the ping module in Ansible. It is not your simple ping, ping this IP address, sorry, ping that address that we had. That's not the idea of ping here. The Ansible ping is Ansible ping module is a separate module written for a bi-directional connection test. The examples are, you can invoke and sorry, the synopsis here, a trivial test module that always returns a pong on successful contact. It has to make a connection through SSH and run remote Python on the other machine and report back that it succeeded. The establishment of connection succeeded. That's what we just did with our quick, simple test of the machine on the remote side. And again, as you know, I'm not using that VM for something is going on. Something happened today that to the VM that is not behaving properly, but principles apply the same way like it does in Unix, like in Macintosh, the same things apply. So now we are ready to run this host. On this host, we want to run this playbook. So the command to run a playbook is slightly different than just Ansible. What needs to happen is we need to run the command called, it's called Ansible playbook. So Ansible playbook, and then you have to call out the Apache, the YAML file. I think there is one more issue. I think this should remove most of the issues that I was having with my keyboard behaving properly. Ansible playbook, and then Apache.yaml. And then I will say, please ask me for password, which is not necessary because we have a root connection to the remote machine. So that ask become is not necessary because we, our remote user is root itself. So there is no need for asking that password. And then the next is to say dash dash step. Now this time it should actually go step by step. It will prompt me, Hey, do you want me to do the first action? Yes or no. So I'll say yes. So it will go and gather facts. The first step in the playbook is to go gather facts, is to find out what you are going to do. And that is a default action that Ansible does on every machine in this list of hosts that we have, which is this listing, which is only one machine. It'll go and gather facts. I continue. I say, yes, it will go and gather facts. And it'll gather those facts and put that available inside in runtime for Ansible to operate on. So next action is, should I install the packages? And I say, yeah. So it does install those packages that we expect, which is right here. These two packages will be installed on the remote machine. You can see that happen on the other side. You can actually go open another computer, another terminal and we'll say SSH to the machine there. And let us see if we have Git there now. So Git dash V, we should now have it. Does it have the other thing that we installed called Apache? Apache 2. Do we have it? Sorry, Apache 2. Do we have it on the machine out there? Yes, we do. But is it running the way we want yet? Not yet. That's the remote connection to the machine. We'll go to the next play. Next play is to start Apache. So we'll say, are you sure you want to enable Apache? And I'll say, yes. So it does. Next play. Mod rewrite. Yes. It's very simple. The only difference that I think I ran into was the dash dash step. And I think I did not read it properly on Google search and I just used only single dash, single dash step. With that, I will say, you know, all the other steps you're expecting to, you know, just like that. I'm going to say yes to everything basically, because I'm iterating, but not really. I just want to move on with the next idea here. So it is restarting Apache right now. And it finished the play. It changed six items. If you run the play all over without the dash step, it will do nothing comfortably and come back and saying that I did nothing. And so that's what you are seeing right now. The nothing is happening. And so it is connecting to the remote machine and doing the nothing things. Now, having seen this step, we'll now go back here and say in your machine out there, this test machine that we are dealing with, it did nothing like change zero items and it came back reporting success. But on that machine, we have configured our domain as example.com. Now I don't own that domain, which means I cannot actually visit example.com DNS and modify that is a problem. So if I go dig example.com and the NS, these control, I don't control these servers. I cannot actually change my domain record in there. So what I can do though, is for demonstration purposes, modify my own host file. And there I will type my password and proceed ahead into this location where I want to actually say that, that IP address that I am dealing with this IP here of that machine, this IP, I want to mark it as example.com. So that's what I'm doing right now here. I'll say insert, mark this IP and treat it as example.com. Like that. And then what this does is basically creates a fake DNS entry. Now I can ping example.com and it will ping my box, but you can see that. And now if I open up a browser and go to example.com, you should see what you see, which is expected, which is exactly what we ran the other time, except this time we are running on a remote machine. The differences between the last time and this time are subtle and critical. You should note those differences. When we run it locally, this host file was simple. We'll say local connection. This time it is not a local connection. It is actually fairly elaborate. So you can see what the differences are. If you want to reset this view a little bit. So soft wrap. Now that should give us a little different view. Like that. So here you can see all these parameters like SSH host, SSH root user, sorry, SSH user, SSH private key file, and Ansible Python interpreter. This last item is strictly not necessary if the other machine on the other side has Python 2, which is most of the time not in Ubuntu 16.04 and higher. They have dropped Python 2 completely. They don't include it. Most Linux machines have it. That's why this line is necessary when you want to deal with a remote Ubuntu 16 computer. Having said, I will switch exercises now and go to another one. This time I want to close this window and try another exercise. So I will say remove this. By the way, you have access to this project already in that Slack chat, which is that link right here. So I'm pasting that link already. You can run it in a remote computer and operate on it just like this. The only difference that you will do will be something like this for establishing a connection to a remote computer. This is what you will have to change like I just did. And I'm pasting that snippet for you. So you can make that modification to that remote machine just like this one, like I did. And I, as a consequence, want to destroy this box because that box is done. I'm done with that box. So I'll say, you know what? This box, you should die. So I kill it and say, yes, destroy the server. The machine is gone. Now let's move on to the other exercise. What I want to do now is a different one. So we'll say remove project folder right there and then close this window. Now another exercise I want to take on is this one, which is kind of a security focused exercise, I should say. So the idea behind the aspects of security, as you will see what I mean when I run it, you will understand the security related aspects. Let's go open that in the browser window and grab that link or git clone. And this is the clone that I want to grab. So I'll copy that link. And it's actually a very short succinct set of things that we need. It is already cloned in my local computer somewhere here. So I'll just go to that location. I'll say, go to the Ansible example folder, which should be right there and open Atom Editor in that folder right there. So Atom should open up on the left half and the command line is on the right half. And we should be exploring now. What I want to explore here is this Ansible configuration is the first thing. What I'm doing here is first thing is I will define my host file. Where is the list of all the hosts that I want to manage is that file. It is called hosts plural. And in the plural file, hosts, I have only one host. Pretty similar in structure, except this time I want to use a different host name. It's really immaterial what host name I use. So I'll create another machine now. I'll say, go create a machine for me. So Seattle and let's say, you know, Debian and this machine size and give me the private key, sorry, the key pair that I want. And I'll call this Ansible example exercise and deploy it. The machine is getting ready. I want to grab that IP address from that computer and make sure that I put that in the right location in place of this old IP address, which was from a previous attempt. Other parts of this, the SSH user, the private key, I need to change the private key to match my current private key in this computer, which is this name. So I match that. And then again, I'm using Python 3 here. Let's see whether that remote machine that I just chose a different OS, by the way, as you noted, this is not Ubuntu. This is, uh, what is the Debian. I chose Debian right there. So in that Debian OS, I want to check whether they give me Python 2 or not. I think they do. I think they do. I just want to show you that example that some of them do, some of them don't. So it depends on the OS. SSH root at IP address. Let's go see if we can connect to it. And it's still getting booted. So it's not available right now. Maybe it'll come online in its resizing right now. So it will come up in a few. And then I will connect to it, check out whether it has Python 2 or 3 or what do we have? What do we need? Which is a one-time operation. You need to know that the distribution that this company has provided, whether it actually does give you Python 2, which is expected by Ansible. But if, you know, you don't give you Python 2, then you have to let Ansible know to ask the remote computer to use the Python 3 interpreter for Ansible purposes. And that's what I will be doing right now. So waiting for that machine to get ready and say, can we connect? And looks like we can. So I connected. Now here, I'll say, Python, what are you? It says, I'm 2. Great. What about Python 3? Are you there? And it says, yeah, I have both. And that's great. And so that is the goodness of this release that we have is it has both. This release is the latest version of Debian, which is stretch. It has Python 2 and 3 both. So we can use either way. You can either strike this line out completely like that, or you can keep it. It's your choice, really. So I'll keep it. It doesn't matter. With that understood, what I would like to now do is carefully, completely review this configuration that I have in mind, which is the host file reference point into the list of items I have in the hosts file here. And then I'm saying host key checking, true. This checking basically is similar to this kind of a check that you saw here. Like, are you sure? Kind of a check. That is what host key checking is. You can say, make it true. You can actually make it false for testing, if you like. Similarly, deprecation warning, you can make them false. Otherwise, it will complain that this is not, this will fail in the future iterations of Ansible and things of that nature. Ansible is being rapidly developed. So you will see lots of deprecation warnings, things change all the time that you occasionally will see. If you don't want to see them, you can hide them. Like deprecation warnings, false. You can hide them or keep them. It's really up to you as to what you want to do. What you want to do with it. Having said this, what I want to now focus on is the actual operative part on security and hardening of the box that I have. This box, called Ansible Example, which is running like a root login. And I don't even have a password because I am using, using that authorized key is my public key sitting right there. This public key that I have in my local computer is sitting, the public copy is sitting right there in the authorized key location. So that's a good thing that I'm not using a password, but I'm, I want to improve upon finer aspects of making sure that the box is reasonably sane in terms of secure defaults. By default, it is not. I mean, I don't like the fact that I'm using a root login. That's one problem. There are several other problems I have with this that I would like to make sure that it is hardened up and strong enough for me to let this go on the public internet and live without getting me into trouble or other things into trouble. For which I want to make the behavior of the box by default a little bit more secure. And for that, I want to run this play. So let's go see what that play does. It is actually going to be intuitively simple for us to understand. The play is kind of, you know, 61 lines long. The small little bits and pieces that you will see in action and you will understand what I'm doing with it. But I'll begin explaining. The first thing I want to do is, is to not use the root user, which means I need to have another user. Do I have any other users in this machine? No. So I want to create one. And then I will create one user on that remote machine, which I need to come out of that first. So I'll say, come out. And then I need to, on that remote computer, I need to have a user called Cloud Genius. You know, that's my login name on most machines that I use. So that's what I want to create a user. I can create that user manually on the remote machine, but what if I have a thousand machines or more than that and I want to do the same thing repeatably in across the board and all the boxes I have and make sure that everybody has the same login name called Cloud Genius, even though the company that gave me this box gave me a root login, like, like you saw here, which is not what I want. So I want to create a user and I will create a password for it. Now, when I want to give password, I want to encrypt them using open SSL library. So that's the method to generate this hash that you look at, which is what I generated using this method, which you can also see by the way, this Ansible example link, I think I've pasted in Slack chat. You should be able to access the code right there in GitHub. And that is this, this line number 10 that you're looking at is actually the shadow password for my favorite password. One, two, three. So we can see how we generate a shadow. Simply speaking, you generate a shadow password using open SSL library like that. There it is. There's a shadow right there. You can store that in your, in your line number 10, pretty much like I have here, this is the password shadow for the password one, two, three as generated. So I can override the old one with the new one and say, that's my password one, two, three that I just created and it's shadow. And I saved it in that location. That's the password I'll be using to establish the cloud genius user as the one, two, three password. You can change, make it more complex if you like, but it's your, it's my choice to make it one, two, three for right now. And it's more of a demonstration, not a real life situation. So we don't have to make the password complex. Having said the first task here is to actually create a user on the remote box, which involves Ansible user module. So we'll go search it. It's right there. The very first link is the right documentation in there. You can go straight to an example or maybe read the synopsis. The synopsis is to manage user accounts and user attributes. You can read what the options are. Or go straight to the example, which is what you're looking at in this is I'm creating a new user called cloud genius with a password provided to me in the variable section in line number 10, which is the cloud genius password, which is this shadow password, which is actually one, two, three. And then I'm assigning a shell to the remote user called bash and group. I'm adding to the group user, sorry, group and appending this newly created user in the password file, the etsy password file. That's what you will look at if you go remote connection to that machine. And you will say cat etsy password. You will find that the list of users we currently have the one on the top is what we are currently accessing with. But I want to create one more user, I can simply do that by running through this playbook. And I will run this playbook play play by play step by step. Next idea here is this line number 17, all the way through 22. Now this segment, what it does is allows the cloud genius user to become a super user, or rather allow it to escalate its own privileges as needed by escalation of privilege. I mean, elevation of privilege in windows, you can say, you know, run as administrator. That's the idea here in, in, in Unix Linux is to allow escalation of privileges by adding the user cloud genius to sudoers list. You can do that manually by going to this file here and say, etsy, actually, there is a vi sudo command for that. etsy sudoers, vi sudo not installed, but we can cat that file should exist. This file should exist. It doesn't. Well, we'll create that this, this new file will be created according to I think it should should work. It'll get it'll get created as a consequence of this step, which is another task to add a line in file, which is this file. I want to add a regular expression. I think this file should exist. Maybe I'm missing a module because that's sudo or sudo there may not exist if you don't have any users using it. I know that. So I will find out if we try, if we run into a problem, we will, we'll run into that problem if at the run time when we run it, but this should work. Let's see what happens when we actually execute. Next one. We want to provide our public key that we have here in our location. So I will call this my new delish. Is that the same type? That key that I want to take from my local computer, which is sitting right here. Uh, is there a key? I accidentally exposed my private key. Ouch, ouch. I would have to change it now, but okay cat. Let's see ls. Uh, ls and I don't have the corresponding public key. So I'll have to use this public key in that case, which is this private key in that public key for the cloud genius user I will be using. So I'll keep this as it was, like it was, I think IDRSA. So we'll keep it like that. And just remember to use the other key for the cloud genius user. Having said, uh, next one, what are the ones to do is to disallow SSH access to the root user for that. What I will do is run this segment. What this segment does is go looks at this etsy file, uh, sorry, in the remote machine. In that remote machine, it will go look at this file called etsy SSH SSH SSH slash SSH, uh, deconfig. And in that file, it'll make some modifications. One of the modifications I want to do is to look at a file that that file, that particular file, SSH deconfig, and evaluate the regular expression which says permit root login and say permit root login. No, basically disabled root login. That's what we'll have to find out. So if you go, we, I, that file, when it says permit root login, if you go, we, I, that file, let's see SSH SSH D and you will search for the expression permit root login. It currently says yes. So that yes has to become a no as a consequence of, uh, as a consequence of your Ansible run that particular entry, which currently says yes should become no after we run this. And then you have to restart SSH for that. The SSH daemon will know that there is this change that has happened to the SSH daemon configurations. It needs to pick it up. And as a consequence, you will find that your root user will be prevented from accessing that machine that you currently have. You are able to access right now, like I'm going to do it. Next one is this modification of another configuration, which says disallow SSH password based authentication. Right now, if I, if I, for some reason manage to forget my, my public key, private key pair, I can still go to the cloud machine and say, you know what, why don't you just show me the password or the copy the password right there. So it has this ability to get the root password from the console. If you like only some clouds allow this. Other clouds don't, uh, other clouds like EC2 or Amazon or Google users. I think Google allows it, but Amazon and Microsoft, you have to actually kill the machine. There is no way to get it, get a root password from the box, but this cloud does. So if I manage to somehow forget my private key or something like that, in that case, what I will need to do is SSH add, and then delete all the entries that I have in my key chain. So now if I say SSH, and I'll not be able to connect unless I type my password, which I will now type because I know the password from the web browser, I paste it and then I'm in, I can connect this way also because I use the password, but I want to actually prevent this from happening because I don't want people to be able to access the machine, even if I have a password. So I'll say disallow password based authentication. That's what needs to happen in this same SSH configuration file one more time. So I'll add back my key, by the way, so SSH add, and that key gets added. Now I can connect without password and I'm connected and I'll go back to the same file here. We, I see SSH, SSH de config, and in there I look for the expression called password authentication. And that, that file authentication of a password, it actually has a silence. There is no such reference to either yes or no, because if you want to disable clear text passwords, change to no here. That's the reference mentioned in the, in the help text in that file itself. So I want to make sure that this line called password authentication that way that is actually disabled correctly, which currently is not the case. Having understood that piece, I will move on to another disable that I want to do in the same configuration file to disable SSH GSS API authentication. That's another flag in the same file. And we want to say no to it also. And then restart SSH. You don't notify SSH as to restart. And that notifications are gathered, collected in one shot at the bottom. There is a handler for that. And you can now see as a consequence, each of these actions as what they do actually in, in real example, let's go play this play, rather play this user YAML play this, this YAML file. I want to play that YAML file just like it is currently stored, except what I will do is simulate the step-by-step in a more meaningful approach by creating a replica of the whole thing. And then opening up, saving it in another folder and just holding it right here and go back to my user YAML. And in there, I will say own all these things up until then I delete the whole thing. I'll just have my file very, very simply, just this with one task. And I will go back to my machine. And here I will say Ansible playbook, and then run my user play, which is, which is user dot YAML. That's the play I want you to run. And here I will say, please go connect and do the play for me. And it will do the only one play, which is to create a cloud genius user with the password of 123. So let's go see that. And it does, it fails because it says that, what just happened? It fails because no one host permission denied public key. Let's go read that. I think my, my IP address is wrong. Apparently I have not modified this yet. Is it? Yeah, my IP address, copy IP address should be in that location. This is the new machine that I have and the IP address should be saved in that location, just like that. Now the host entry is correct. With that, we should not have this authentication problem at all. It should connect and then come back reporting that it created a user called cloud genius on the remote machine. Now we can go to the remote machine and check out whether we have a user called cloud genius in there. And there it is right there. It shows up. It also has a password in the shadow password stored as one, two, three, and the bash shell allocated to the login for that user called cloud genius. That's what, that's what we did in that play because we assigned the bash as a shell assigned root group to this user. So you can see that the root group is assigned and the user is created, but that should allow us to actually log in using SSH cloud genius at IP address. This should also work provided I type my password, which is one, two, three. So let me type that one, two, three. And I am in now here. I can see what I have, but I cannot go to like random locations and destroy stuff because I don't have super user privileges. In fact, if I go say pseudo and as simple as say LS, it says pseudo command not found. Because pseudo is not installed in Debian to begin with, which means we'd have to install pseudo for this exercise to actually complete. A pseudo is not installed by default on that Debian box. So for the next step here, which is to add user to pseudo or file that will fail, because I think Debian doesn't come with pseudo. So we're going to get pseudo first. So here we go. And make sure that we install pseudo. So pseudo, or rather no pseudo, apt install pseudo. And this should install the idea of pseudo and all that to begin with. It is bare minimum Linux to begin with. So many of these times, some cloud providers don't give you certain packages. So now we have pseudo, which means there should be a file called hc pseudoers and is now available. That file was missing because the package was not installed. We just installed the package. Sometimes this is handled in another play. You have to have a play with basics, like foundation stuff, like basic stuff, like our base role in the Chef idea. Base role, I need to have these ABC things installed. One of the things on the base role from Chef time you will recall was pseudo. And that is what we just did manually. You can write, of course, write another package, manually. You can write, of course, write another play to get this action taken care of simply by creating another task saying name or other, no, make, don't make mistakes in indentation, install pseudo. And here you have to say apt. And I don't remember how to write it. So here's what I do. I go ansible apt module and search and see how to write the actual syntax because there is no point remembering these things. It's right there available for us. So it says install foo package state present right there. Copy that, bring it here and paste it. Boom, like that. That's how it should be written. But again, indentation is the key here. So make sure that your indentation is absolutely stellar. Without that, boom, you have a problem at hand. So don't make that mistake. Is it one space or is it two spaces for the app name? It's your consistency is important. Your choice. Oh, so the, the, the interpreter is consistency. Consistency is key. It's not specifying how many spaces. It's just got to be consistent. Exactly. You're going to use tabs. You're going to eight spaces, four spaces, whatever you like, but consistency is important. So having said, you know, I just did this item, which is created a new task, which I actually did manually here, install pseudo by hand, but I can do this in Ansible by introducing one more task to begin with. So I save this, this item, copy from here, put that in my actual file and right there. So now if I run the play and come out of this box, and then I'd say, okay, Ansible, go do your thing. It has now two plays. One of them is to install pseudo and the second one is to create a user. So both of them are already taken care of. So it did nothing and came back saying, boom, done. That's what it just did. Now let us see the next idea, which is expanding it. So now that we have the pseudo package installed on the Debian machine on the remote box, we need to make sure that our super our cloud genius user can actually go super user. Right now it doesn't, it doesn't have the ability because we never granted their ability to it. So we'll grant it now. I will save this in adding one more play to the playbook. But now here on the remote machine, let us see if, sorry, on the remote machine as cloud genius user like that, can we log in as one, two, three? Yes, we can. Can we do pseudo and then say LS? I will say, yeah, let me try and see what happens. I'll say one, two, three. So here it says, we trust, you know, all that, you know, you actually, you should read that. This is like classic Unix language. This, we trust that you have the usual lecture from the local sysadmin. It usually boils down to three things, respect privacy of others, think before you type, and with great power comes great responsibility. This is what, you know, Uncle Ben said to Spider-Man. So let's see what Uncle Ben said to Spider-Man. So I type my password and I say enter. And here, what happens? It says cloud genius is not in the super user pseudo list, or rather in the pseudo file. This incidence will be reported. So where does the report go? It goes to Santa Claus for being a bad boy. I'm just joking. But it actually goes as a log entry in the root log. Because somebody attempted to become super user that did not, was not allowed because that cloud genius user was not in the cloud. You see cloud genius user was not in the pseudo file because we haven't added him or her. So that incidence was reported to the root user, whatever. Okay. Having said, let's go see and add that user to the pseudo file. Currently it doesn't exist. So I'll save this play as is and run the play. How do you run the play? Like this, it'll go to one, two, three, three things. Second, the third thing will actually be operative, which is one item change in yellow color. The okay are in the total count. This yellow item actually changed. You can see that change happening and civil example target machine and add the user cloud genius to pseudo list. Now you can go here in the root login and find out in the pseudo file that there is an entry added to right there for cloud genius as an entry in this would do was file, which means now we can go connect to this machine as cloud genius. And now type the password one, two, three, and now I can actually do pseudo LS. And it did, you know, maybe it did not show you anything because there was nothing to show. But these guys exist. So I can actually run it like pseudo LS and it shows you without even having to ask for the root password because that permission is implied. It is a super user enabled user. And I'm actually asking for no password. So there is no need to prompt for a password. Now we'll expand further. What I will do now is to make sure that our SSH key for this ID RSA that I had in mind here, right? This, this key that I had, sorry. Yeah, come on. And that key that I want to use this ID RSA key and the corresponding public key. I want to use this key pair for the cloud genius user to connect to the remote machine instead of typing the password one, two, three. So I'm going to grab that and send this public key to the remote machine and make it available in the cloud genius user like that. I'll type one, two, three first manually and go look at our dot SSH folder. It doesn't exist because that's what I would actually do is to create a dot SSH folder and inside there will be a file called authorized keys with content. So I'm going to go ahead and create a dot SSH folder which contains, which would contain the ID RSA pub. That's what I would like to happen. So I would like to make that happen through this module, through this, this play in Ansible. What I'm doing here is I'm saying grab the file ID RSA pub from that location, look it up as a key and associate it with the user called cloud genius on the remote machine, which is Ansible example, that machine that we are dealing with. So inject the public key in the right location for the cloud genius user. That's what this play is going to do. So let's go run the play. We'll run the play pretty much like this. You will see the first three things are dummy, do nothing. And that is this one, two, three, done nothing. And the fourth thing actually did something. What did it do? Added the public key to the remote user. Now let's go to the remote machine and look at, by the way, you saw that it automatically let me in without even prompting me for the password because of our key got activated. Now you can actually see that the key is stored right there in authorized keys file and you can cat it and you can compare it with the actual key right there. The item by item is the same thing. You can see JSJHQ right here and match it with here. So the same key word injected in the IDRSA authorized key location in the SSH folder for the cloud genius user. Okay. Next idea. What I would like to do next is to disallow SSH from accessing, I'm sorry, I shouldn't say it again. Disallow the root user, prevent your root user from accessing. Now that I have control on the box with a cloud genius user, I want to disable root logins. So that's this segment, which I want to grab, which is to disallow SSH user. And I will take that segment from the playbook and paste it at the bottom. You will notice that there is this extra notify step, which requires and expects a handler to restart SSH rather to grab the handler also. I'll grab the handler from here, which is basically saying that the state has to be restarted. You can read that and I'll read it for you. The name of that service is SSH. The state of that service is restarted. That's how you declare that you want the service to be restarted. The SSH daemon will be restarted as a consequence, which means if I run this play, then I cannot connect to the box like this. Right now I can, but then I run the Ansible play and then root logins are disabled. And it is restarting SSH and it finished. So it disallowed the root user from accessing and it restarted SSH handler, which means if I now try to SSH connection with the root user, fails. It actually asked for me over a password. So that is not what I want to do. So if I, well, let's see what happens if I, let's read that thing. What it did is permit root login and says no. So root login is prevented from accessing. Now if we can actually go back to the cloud location and grab the password from there, copy the password and provide it to this command line. Say, Hey, root user, I know your password. Here it is. Take it. And it still will not allow you to connect and type the password again. And still fails. It is going to fail by design because that's exactly what we wanted is to disable root logins. Even though you're trying to give the password, even though you have the key pair that is correctly placed in the right location for the root user, even all of these things, they don't matter because we have prevented by policy. And why were disabling the root password? Cause everybody knows the root credentials or the root name. So the idea behind disabling root password and root logins and everything to do, anything to do with root is a, is considered a good security practice. It is also, you will notice that, you know, as a part of server hardening, it is a recommended idea to disable root logins. Don't even though the simplest way to think about it is that everybody on the planet knows that there is a root user. And so you want to disable that. The idea is here, partly security through obscurity. It's also in security. They call it an attack surface. It's providing another route for an attack. Yeah. Correct. So, the idea here is to make sure that you prevent anybody who even happens to know the root user from accessing the box. That's what we just succeeded. So I'll break this and come back here. And now in this setup, what I want to do is expand our further actions. Like for example, the other two actions we have still to do, which are we disable root plugin and root access. That doesn't mean that we cannot access the box though. It means that we have to go through the cloud genius user. And then here we can do whatever we want. For example, here I can do whatever I like, say, you know, sudo, I have to go through super user access, the sudo apt update, and it will work just fine. You know, there's no issue there. And it will update the app cache and everything will be working just fine, except that you are now logged in as a cloud genius user, as opposed to a cloud genius user, as opposed to the root user. So you don't have default privileges to begin with the escalated privileges. It doesn't have, it will still prompt you for password when it needs to, unless you have overridden saying, don't even bother asking for the password. Having said the next step that I want to do now is to disallow SSH password authentication, meaning I know my cloud genius user has the password called 123. Like if I say that SSH add dash D, all the identity deleted. And if I try to now connect to the remote machine, it still lets me connect. Okay, I think the ID RSA is something that is picking up. So I will go rename that ID RSA file, which is where is that? So I'll go to the SSH folder. And in there, I have these files called ID RSA, I'll rename them ID underscore RSA to XYZ underscore RSA. So just just like that, I removed it. Then I'll also check my keychain SSH add. And there are no identities. That's good. I'll go back to the Ansible access example exercise. And here, I want to connect to that box using the cloud genius login. And it says, okay, now give me the password. And I can give the password 123 and enter. But this is also another security implication that you know, what if my password gets leaked? I don't want people who accidentally have access to my password to succeed in logging on to that box. I don't want anybody to log on to that box using the password whatsoever. I mean, I'm disabling password based authentication altogether. That is what this segment will do. And so what I will now do is take that segment, put that right in this location in as another play right here, for example, and I'm disabling password based authentication, what's going to happen inside that SSH config is look at the password authentication flag, and append a word no, and then restart SSH that action is expected to happen as soon as I run the play on the machine on the local computer, I'll say go play my playbook right there. So it's going to do all the things and add one more thing is something failed. And why it failed, it basically failed because our Ansible configuration here expects the root user. But we know that we have shot ourselves in the foot and have disabled the root user from logging in. That is the reason why this thing fails. This is failing as expected. So we have to go change our host entry. And in here instead of root user, specify the cloud genius user and then save. Now, this should also require one more change. The private key corresponding to is not this private key for the cloud genius user. But it is the other file which are renamed as x y z underscore RSA if you recall just a few minutes ago. That's the private key which is corresponding to the cloud genius user is what I will be using. So that change also needs to be made in this Ansible configuration as I did it for you as you saw. Now we'll go back here and run the play one more time. This time it will connect Ansible will use the cloud genius user to connect to the remote machine with the x y z RSA private key and a remote Python three connector and disable password based authentication. Having done this, having seen this section, what I will now attempt to do is connect to that machine. But first of all, check my SSH ID identities, they should be empty. There are no identities. Now I will cut an attempt to connect to the cloud genius machine. And it doesn't even bother asking me for a password. It just says unable to access permission denied, boom, go bye bye. I cannot access my own machine even if I know the password. And that's exactly what I wanted. Because if I accidentally write down my password or give it to somebody else, I don't want them to be able to access my machines. The only way I can access this machine now is to add that key again, SSH add that key called x y z underscore RSA into my key chain. And now I connect. There is one more last item that I want to talk about, which is esoteric. And so that is this GSS API authentication, you want to disable that also. We'll grab that piece. And we dump that item here and say that you should please run the play one more time. And it will go disable the GSS API based access also and report back that it did what we wanted it to do. And as a consequence, we did a few different steps to harden the behavior of the bots. We are not using the root user at all. We are not allowing anybody to log in as good user even though they know the password or their key that's stored in that location. We have created a new user called cloud genius. We set a password for the user. But then we also prevented anybody from accessing even if you know the cloud genius password, you still cannot get in. We chose a different key and a different method of authentication like this, like the one you saw in this step here. So using key based authentication, we are able to go through the cloud genius user who has escalation of privileges without explicitly providing password is already enabled in that play that you saw here, which is no password. So you don't even bother asking for the password. You just do whatever the cloud genius user says, provided that user has come in through SSH authentication using a key pair. I got a question. So what happens if we simply edit the etc password file or etc shadow and etc users and remove the root user that way? You can. You can. But the point is to not do anything by hand. Okay. Right. You want to do through automation. So that that's that's this method, which is this is the answer. But there are hundreds of hundreds of ways of doing the same thing. Like one of the ways is just go to the machine and do it manually, which is kind of boring if you're dealing with like 1000 machines. So you want to get all the machines listed out in this host file. We can automate that using Ansible. Oh, yes. Yeah. We just did this right. So yes, even in Ansible, you can go and hack a file if you like. But let me say it this way. Yeah, I see what you're saying. So what I would like to say is, I think what you what you did mean to say if I'm correct me if I'm wrong, let me show you what I think you mean. What you mean is, you go to the machine, and you go to this location, let's say that file. Oh, sorry, that file. And here, this line, you want to delete the line and you want to delete the line using Ansible. Yep. You can, but don't. That's not a good practice. You want to keep the root user for physical access to the machine. Alexi, when, so this is something that we did in one of our labs in college. We deleted the root user here. And this is a while ago. So I don't know if they've fixed any of this. But what happens is, is it becomes completely unusable OS. Don't disable the root user. There's so much infrastructure in the OS in Linux that relies on root and, and, and services running as as root in certain situations. Okay, got it. Got it. Didn't think of that. Yeah, yeah. So this this ID zero, the user ID zero and the group ID zero are critical to the system operation. This is you can rename the root user to something else. That name is the root user to something else. That name is not important. Maybe that's a change you can do, but this GID, UID zero, GID zero is a critical thing in Unix. So you don't want to get rid of that line. You can use Ansible to destroy that line, but it's not a good practice. Okay. Okay. So I will now come out of this machine and we finished this exercise. What I would like to now do is, you know, extend this another further step. So let's go see what exercises I have ready already. So what is the list? Okay. The other exercise, next one I have is, is to prepare the foundation of what I just began discussing here. Like I said, you know, can we take a short break? Yes. Yes. Cool. Yeah. So I will remove my microphone and put this down and walk away and start the timers. And the machine out here should die. And I've done this, done with the machine. So it just dies. It's fine. Okay. I will walk away briefly and come back. The time is running and I have to fix my computer. It did not behave properly in the first few minutes. It was giving me a nightmare. Sorry about that. That actually is a lesson. I wanted to see you shoot that Macintosh. I know, but it was not the Macintosh's problem. It was my problem. I was being stupid. Okay. I didn't even reboot the Macintosh. If you notice, if you get crack of it, I have not rebooted the Macintosh. It is not a Macintosh problem. It is me being silly in making stupid things on a production box. That's the learning. I mean, the learning here essentially is I use this machine for my customer facing presentation, which is giving it to you, right? I should not be messing around on the production machine. That is what I did. It is stupid of me to do that. I see you did an update or something. I'll tell you exactly what I was doing. I was experimenting with Hammer Spoon. You can read more about it. I'll come back and you can read more about it. Everybody does. It's a keyboard-ish nightmare. I'll let you read and understand. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Oh, I'm back. I'm assuming you guys are also back and let us proceed. Yes. Okay. So the next idea that I want to talk about, I should put my microphone in the right spot. The next idea is about enabling foundation for us to run containers and we will use Ansible to set up that foundation. That's this next example that I want to run and it is another Git repo. So I'll paste that link for you and then make use of that repository to play. So the link is line number five. I'll grab that link and paste it in Slack chat right there and open that in the browser. Okay. But before I run this exercise, I would like to tell you that it requires an external dependency, meaning I want to actually use this thing called the Galaxy Ansible Galaxy. I want to use this Galaxy to use a ready-made piece of code, just like we did in supermarket and chef cookbook. This Galaxy allows us to browse for authors or search for something that we would like. So now I am in the mood of using containers. So I'm going to search for a Docker. And so when I search for Docker, I find there are several solutions available and I have tried many of them, but the one I like is not on this page, apparently. So I will go look by the author and his name is, what's his name? It should be on the Git repository. His name is, that's his name. I don't know how to say it, though, unfortunately. I'll search for him and he, it's not actually his name, but it's his name. It's not actually his name. His name is Paul. Okay. So Paul, that's his real name. And he has created a comprehensive way and ideally the same way to install Docker on Ubuntu 14 and higher. That's the idea. So that's the role that I want to make user. It is a ready-made piece of code that this gentleman has developed. He's contributed to it and contributed to the Galaxy. And it is available as a role ready for us to consume in this location, which is a different location, by the way, this is not, we will use directly, but we will use Ansible tooling to download the role and incorporate into our own play, which is what I want to do. So I will open up GitHub terminal, go to that location where I want to play. And it is not the Ansible example. So I will close this folder, remove project folder, and then see if I have that Docker Ansible already loaded locally. I think I do. I check my remote for GitHub. It is the same location that I'm looking at. So I'll say git pull to get the latest. And I don't have access rights, which means my key needs to be added. So I just added that key and now I can pull. Okay. Already up to date. So I'll open Atom and inspect what we have in that repository, which I just gave you a link on in Slack chat. So you have the same link. Now this repository or this folder will help us set the foundation, as I said, to get Docker running on any machine out there on the cloud. So this particular example will be using Ubuntu. So if you look at the Ansible configuration file, which is usually a good beginning point to look at any Ansible project, you will find that it defines certain locations to look for. For example, this location inventory is that folder which contains a file called hosts. And that file hosts, this file is going to store the values that I expect for all the hosts that I want to actually use in my infrastructure. So if I open that file on the side and look at the host file on one portion of the window, I'll compare what I'm talking about. What I'm really talking about in the Ansible configuration line number two on the right side refers to the file on the left half of the screen, which is the host file. Now here you can see that there are lots of entries, like line number one, four, five, six, and seven. Five items, five line items specifically called out. And the first one is kind of commented. We can just begin with one. We don't have to have all these machines ready and simultaneously operating. But here are just examples. So what I want to do is actually just comment them out, all of them, and begin with one example. Let's go pick this one. So I'll copy that one example. And it is this example I want to begin using. So I will toggle the soft wrap on this so I can inspect carefully exactly what I'm dealing with. I want to focus on this line number 13, which happens to be a name I want to change. So I will change it to the other cloud, this cloud. It's actually immaterial. It doesn't even matter what name you use. Or you can call it whatever you like, as long as you don't call it late for dinner. That was a joke. That's an East Coast joke for those of you who have been to East Coast or have understand from Boston area. Most people use that, crack that joke in Boston. Don't call me anything. Just don't call me late for dinner. So I intend to use the word late for dinner for this machine as such. And then it needs to have an IP address. So I'll need to get a machine and provide it an IP address in that location. And that becomes the place for me to begin running this exercise. So I'll need to get a machine first. I'll go to some cloud and grab a machine. And I'll say go to my account. In that account, I'll deploy a box. And I'll say go to Seattle and choose Ubuntu. And you can choose 14 or 16 or whatever your choice is. I'll begin with 14 this time. And I'll select, you know, $10 droplet or $10 machine. I'll add my private key there and give it some name, like late for dinner. That's the name of the machine. And I'll deploy it. So it gets started. It is now going to install and I get an IP address. I'll take that IP address and put that in that machine. I'll take that IP address and put that in that location, line 13, Ansible host. It has a user called root, which we know already. It uses a private key file, which is not this name, but a new Nilesh, different name. That is the file that I want to use as my private key. And I want to not use Python 3 because I know that the remote machine that I am dealing with is Ubuntu 14.04, which should have Python 2 already. And so that's the other example I want to bring up is this line 13, 14.04 has Python 2 already. So you don't need to have that Python interpreter line as called out like Python, use Python 3. You don't need to specify like that. Having understood these pieces, I'm still waiting for the IP address to pop up. So I'll grab that IP and then copy it. And then bring it to this machine and paste it right there. Now I have the IP address in the right spot. That is the inventory I'm beginning to work on. The next idea in the Ansible configuration is line number three. In the line number two inventory, I just have one machine and that is represented by line number 13 on the left side in the host file, in the hosts file. Only one box right now. Everything else is commented. So it is ignored. The next item on the right side in the Ansible configuration is a path definition where I want to store roles. In my folder here, I don't even have a folder called roles. So I'll create a folder, say roles. And that folder did not create why? I said new folder roles and then create it already exists. So why are you not showing it to me? That's a bug in Atom. I expect to see roles folder here and it doesn't show me. F5. Yeah, except I don't have an F5. So a function F5. No, it doesn't show me. It doesn't show me F5. So a function F5. No, it doesn't. Okay. So I'll quit and open again. That should show up. And so here is the... Why does it not show me? That's crazy. That is crazy. Is it created? No, there is a folder called roles. So why do you not show up? There is a folder. Atom, please show me the roles folder. You're in a different GitHub repository. Aha. No, this is the one I want to play with. Docker Ansible. That's the one I want to play with. And that is should have a role file there, but apparently, no, it doesn't show me. So I'll remove the project. And then open file, open, dot, dot, dot, and then go to Docker Ansible. There is a roles folder right there. So please show to me Ansible. Open a new window, add to this window and discard state right there. No. Okay. Something wrong with Atom. So quit. Atom, please show me the roles folder. Quit. Atom. I'm not using Atom. I'll use something else. Different. So now I see the role folder. And that is the folder I want to actually use. So this Ansible configuration I have here is what I was talking about line number three. The roles folder will contain the roles that I want to use. And those roles are sitting in that location in the galaxy, which is what I want to actually use is this is a role that is ready-made piece of code that this gentleman has created. I want to consume it. It says how to install it right there. You can install Ansible Galaxy. There is a command for that. You run that command right here in this window, and it will bring down the role in the roles folder right there. When you invoke this command, Ansible Galaxy, please install this role from this gentleman that will help me install Docker on any Ubuntu box anywhere out in any number of machines. So I'll run this command. It will go to the galaxy and download that role and drop it in the roles folder. So if you now look at the tree, you will see that I have a role in the roles folder called that name. And it has all the code that this gentleman has created sitting right here. Having understood this part, we can also go read other aspects of this Ansible configuration, which is like ask, become, pass. You don't need to ask for a password because you already are connected like a root user on the remote machines from Vulture Cloud at this moment. So this line number five is strictly not necessary. Host key checking is a good idea to keep in most of the time, but when you're testing something, you may want to disable this. Deplication warnings, it is your choice whether you want to see them or not. I would rather not for right now. So I disable them. And then I'm back to the point where I can actually run the play. The play is called Docker YAML. And the play is really, really simple. It is simple because most of the work is done already for us. You will see that the structure of the play is not called tasks, but it is called roles in line number seven right there. Roles. What I'm doing is not using tasks, but invoking a ready-made role. And that role is what I want to make use of, which is this role here, which is created by the gentleman that I mentioned. Now in that role definition, if you go look at here and read its documentation, you can actually go to the GitHub repo or read this readme file here. It says how to play this role. It's very simple. You need to run it like this. That's his instructions on his repository. So we can either run it like he's saying, or compare it with what I am doing, slightly different. My role invocation is slightly different than what he's suggesting. He suggests a role invocation like this. He says just name a host that you like, line number 18. So we have line number four on top. This is similar. You have to have a name. The name is line number three. So I delete that. And then the only difference between his role definition, which is 17 and 18, and my definition is that I have added two more items. These two items are making it a little bit generalized to get it applicable on any cloud of your choice. What happens is you will notice that, you know, most cloud companies will have their own fancy way of naming the username by default. Some cloud will say it is EC2 user. Some cloud will say, you know, it is Ubuntu user. Some other will say use your name you like. So I have these examples, and they give you a way of representing your username as a variable right here in these host files, host-vars variable in that folder. In there, what I'm really doing is calling out for a variety of cloud companies. For example, the late for dinner company, which is the Vulture Cloud. I am choosing my username as root, and my home location is root. So that's the late for dinner YAML file, which is what I want to use in the play, which has a root. So I'm going to use the play, which has a host. The host currently includes all the hosts in that file. The file currently contains only one operative line called late for dinner. It has the IP address and the root user called out by name, and the key pair corresponding to that user. Having discussed this part, I would like to go back to other clouds. For example, the DigitalOcean example. It also has the same situation where the root user is called root. The user available to you is called root. The home location for that user is slash root. So that is easy and simple to understand. For example, the Amazon Cloud. We know that gives you a username Ubuntu for any Ubuntu machine you create in the Amazon Cloud. And the home location is not slash root, but slash home slash Ubuntu. You can specify them by the cloud as an example in this case. So what I will like to show you is that when you have this kind of a variation, you can implement that host variable, like user name, like this. And what this will do is make sure that they will add that user as a Docker group member. What does that really do for us? It will allow you, when you run the play, to run as the user that the cloud company decided to give you. So let's go see Amazon Cloud. I think console, AWS, Amazon Cloud. We'll go there and grab an Ubuntu machine, just like this one is coming up. And we log in. And then we go to the next step and then provide a token. And then we go create a machine out there in this Oregon location. We say start an instance and we'll say, give me a Ubuntu server. And I want to select Ubuntu 16 in the Amazon Cloud 16, select. And T2 Micro, launch configure details. I want to leave it alone in the default VPC and I don't have a preference for any subnets. I'm assigning an IP address so I can connect to it directly. And then I will add some storage. And then I add some tags and then I configure security groups and I choose my existing security group, which is this one, which allows me access from my location. So all that is good. And I'll review and launch. And I will launch the machine. And it will not have the key, I think. My key has to be given because I'm not using Linux machine right now. So if I launch it, let us see, it says, select a key pair IDRSA. That's not what I want to use. I don't have that key. So I need to go back and provide the key pair first. So I'll do that. I'll go here and say, get my key pair. Oh, this is the private key, right? So I don't have a public key. So if that's the case, in my example, you will run into this occasionally, you will accidentally by mistake or something, lose the public key, like I seem to have lost. Don't have the public key. I only have the private key, this one. So if that's the case, you might run into such situation through human mistake, like I did. And so you want to generate public from private key. And so that's the instruction, how to generate the public key from private keys, you grab that and bring it here, and say that I want to generate my no, no, it's not what I mean to say, I want to generate a public key from private key. Generate public key from private key, that's the key command, I want to actually retrieve the public key from the private key. And the command is right there. And I will invoke that. And I will say that I want to generate a public key from my private key, and store that in the location. So now I have it. I can say that my key is now available in that file, I can cat it. And then grab that public key, give it to Amazon, EC2, and key pair, import key pair, this file is called new nilesh, and import. So that's the key pair now I have given, I will like to use that key to generate a new machine in Ubuntu OS, like that, in T2 micro, and make sure I get a public IP address, and add some storage and add some tags and configure my security group, this one and then review and launch. And when I launch, I would like to make sure that I select the correct key pair and I acknowledge that I have the corresponding private key and I launch an instance, it gives me an IP address, I go back to that machine and get its public IP from here, copy that, bring it here to the options here, and then go to my host reference, and uncomment the Amazon example, put the IP address in that spot and save. Now I have Amazon machine up and running right there. Line number 14 has Amazon. What this will do is use a different user called Ubuntu, as opposed to the late for dinner machine user, the root user. And it has the Python 3 reference as the interpreter, because that machine is 16.04 as opposed to 14.04, which is line number 12. 14 is 16.04. I've got a question, a quick one. So the very first entry on every line, does it have to be a URL or a fully qualified path or just a name or something? String. Oh, okay. Just string. So like late for dinner, it's not a FQDN, right? It's just a name. So if I have just a name, I correspond to that, I'm a variable assignment, I'm using this late for dinner YAML. If I have a fully qualified domain structure, I use this way. Okay, got it. So it's just a label. Yeah, just a string. So two machines right now, we can add more clouds and more machines and Amazon lets you use, sorry, Microsoft Azure will let you create a Linux machine with your chosen username, like Nilesh, for example. That's totally acceptable. So if that's the case, you will generate an Amazon Azure machine and include that file in the operating list of machines. And that's how it could go. But I don't intend to actually go to Amazon Azure cloud. So I'll leave it there and leave it commented and leave it alone for right now. So just two machines. For this example, the first machine, line number 10 is 1404 and machine line number 12 is 1604. Those two machines will use a different YAML. This one uses the Ubuntu username, this one uses the root username. And what I'm really trying to accomplish is to add the Ubuntu user as a Docker group member. So then I can operate on that machine in the Amazon cloud using Ubuntu login name as the username, which is what I want to enable in this line number 10. It's a generic way to operate on any cloud of your choice with any username that they dictate, or sometimes you choose. And I want to make sure that the kernel package is available and present on the target machines. That's my extensions to this, in how I run it in line number nine and 10. The recommendation is to just run it like this, very, very simple to execute a ready-made role. I expanded it like this, and I am going to run it now. When I run this, what do you think will happen? What will happen is, first thing, I added my inventory, which is the two items I added. Then I pulled my role from the galaxy for the Docker Ubuntu role, and then I run the play. Running this play is actually running a role. The role is fairly complex. It does exactly what you would see it'll do, but at the end, you will have the two boxes that we have in mind, this machine out here, and also the late-for-dinner machine, which is in the other cloud here somewhere. Where is that? Vulture Cloud, where are you? Not this, not this, not this, not this. Where is the Vulture Cloud? There. This late-for-dinner machine and the Amazon machine, both machines, we should find that they are both able to run Docker. Let us go quickly connect to the Ubuntu machine in Amazon Cloud and see if we can connect. Does it have Docker? No, it doesn't. Great. Quit. How about the other machine, SSH, root, at, and the IP address for the other box is this IP address. Grab that, bring it here, and say connect, and make the mistake. Go remove that space there and connect, and connect, and does it have Docker there? I bet not. And why is it not connecting? Connected. So Docker, do you have it? No, there's no Docker in there, so quit. Fine. So we don't have Docker on the two boxes. I would like to use the role provided by this gentleman, Paul, and I want to play that using our method here, which is use Ansible Playbook to run the Docker YAML play. The Docker YAML play, as you already know, is this play, which is simple. Line number eight is the operative line. It invokes the role that is defined, and we can read through the code for how he has written the role for us, but right now, I just want to run it. I'll say, okay, Docker, sorry, okay, Ansible Playbook, go execute that play for me. So it does. And now at the end of the play, you will have those two boxes, both running Docker. That's what we'll see. So we'll see it happen. It is actually enabling all the things that are necessary. It'll actually go do a thorough analysis of the machine, look at the thing that is missing. It'll install whatever is needed to make that work according to the play. Let's go read the play. I think it's easier to read the play than look at here, because this is going to be doing its thing, and it will tell that it did. It's not super interesting. I would rather read the play in terms of the role as to what it is doing for us, and then revisit the command line when it is done doing its thing. So here we go, look at the Ansible role. If you look at that role here, it begins looking at the invocation of the role itself. There is a Docker YAML file, which uses the dot slash reference. Let's go see what the dot slash reference is going to be. There are some defaults in here. There's a main YAML. This main YAML is the one that actually begins invocation. It has chosen some sane defaults for us in terms of if there is an existing version of Docker installed, do you want to keep it or remove it? So uninstall previous, no, don't. The desired version of Docker that you want is the CE community edition version, open source version. It is also calling out the AUFS layered file system that you remember from a previous Docker example we discussed. Docker expects to have a layered file system in place. That layered file system Docker uses is called AUFS. There are a couple more options available, but this is the most commonly used file system, AUFS, that is generally used in Docker by default. That's what is going to be installed. You will see that happen on the right, on the left side. As the play runs, it is changing a bunch of things and finishing it off for us. You will see the whole play exactly runs pretty much like you see in the role itself. And it will also do a couple of nice things. For example, it will make sure that the Python is installed, pip package is installed, setup tools are installed, pip install Docker, pip install Docker compose, those pieces may be missing. And if you just install Docker compose, or rather, just install Docker directly, Docker compose may not be there. So if you want to properly set up all the missing pieces, that you would rather use a ready-made structure like this, so you don't have to repeat their work that most people would rather not want to repeat the work that this guy has done. I would rather use it. I would rather use it. I would rather use it as opposed to writing the whole thing from scratch myself. And you will also see that it is grabbing the latest versions of pip, latest version of setup tool, pip Docker version latest, kernel update and reboot permitted. No, don't want to reboot the machine. You want to update Docker packages. No, kernel package state is the latest. This is similar to what I have in my description, which I'm saying kernel package state present, and he's describing it as the latest. So change these to present if you're using Ubuntu running 12 or 13. And you know, if you're and are fine with older packages, less than latest packages, if you're okay with that, just make that present if you're using older versions of Ubuntu. But those two versions are not even available in most clouds, they've taken it away. So the clouds will give you a 14.04 choice and a 16.04 choice and any newer choice, but those older versions are gone. So this present choice is not really relevant. You can use the latest in the example here. So I can actually make it go latest like that. It doesn't hurt because we are using newer versions of Ubuntu, not 13 and 12. And at the end, what you will also notice is that this has enabled the Ubuntu user on the Amazon machine. For example, this, no, not this, this machine has the Ubuntu user able to run Docker. So it's a Docker dash Docker dash BS dash A should run successfully and show us that there are no currently running processes. And Docker images should show that there are no images available and Docker info should show you the information about Docker setup. So this is what we now have currently ready and set up using the latest kernel version available for 16.04. Using the layered file system that we wanted. Where is that? AUFS reference. AUFS, where are you? Well, grep for it. So grep, AUFS not listed. Maybe the info doesn't show you, but there is a AUFS under the hood. That is absolutely necessary requirement. You have to have a layered file system for Docker to function. Docker is functioning. And it's not going to show that you have to have a layered file system for Docker to function. Docker is functioning. And that is how we were able to see the success on one of those clouds. Let's go look at the other cloud right here. The other late for dinner machine, right? That one. This machine is slightly older. It is not 16.04. It is prompting you to do an upgrade. You can, but don't have to for right now. Whether we can see Docker there. Docker info should be available. And it is slightly older kernel because the operating system is older. That's what you're looking at. And it succeeded in accomplishing our goal. Our goal was to enable Docker as the foundation on all the machines we have. So back in here, at the beginning of the session where I began describing this idea, that prepare for container thinking. Thinking like you want to run everything in a container as opposed to dealing directly with the machine. Any application you want to run, you want to run it in a container. But you want to automate that using tools like Ansible for one example, or Terraform for another example. You can use any tool that you like, but at the end of the day, you want to not run applications directly on the machine. And that doesn't make sense anymore too much. Some cases you still have to do it, by the way. So those cases you will know when you need to use a machine, you will use a machine. But most of the times, in most cases, you would not run applications in a machine, but run them in a container. That gives you the ability to move them around and shuffle from one machine to the other. Nilesh, just to be fair, you are talking to Boeing engineers and we still have a lot of legacy applications. And I know that other big companies do still have a lot of legacy applications. Yes. That's what I'm saying. Make sure you understand who your audience is. But I said, you think containers. I'm saying you think like this. It doesn't mean that you are actually able to do exactly like I said that you should because there are legacy that you have to carry forward. And I want you to think different. That's the point here is how you think is how you make progress. If you don't think like this, you will never go that direction. That's the point I'm trying to drive towards. I know and I understand that almost every company that I work with will have something here. They're stuck here because that's the legacy. I mean, that's where we came from. That's how life is. I understand that. I want you to think like this. That's all I ask. Doesn't mean that you implement every single thing like that. Just think, how would you do if it was a container? Because that's the limitation that I want to remove is to let you think different. So it's an invitation to think different. That doesn't necessarily mean that you do every single thing I tell you right now, right away. It may not be possible. I understand that. But thinking is important. And that's, I think, the key takeaway from this discussion. And I appreciate that. I was kind of poking fun at you, but there was a conversation that I did have yesterday that somebody brought up a good question. And I don't know if we can, we have time to answer it here, but maybe you have some resources for somebody else. When is it not appropriate to use containers? Because right now the comment was containers is becoming a hammer and everything's a nail. And it's being improperly used in a lot of situations. So the question is, when is containers not a good solution or should not be used when you're talking about an application? Maybe when it's on an IoT device. Maybe not. Yeah, there it is. So when you are dealing with data, avoid containers. What do you mean by that? I will describe, I'll describe that. I'll show you with live examples. When you're dealing with user state or information or databases or storing relevant data that designates a state of some application, designates the state of a user. The idea is to separate state of user, state of a machine, state of a container, state of anything in your infrastructure, in your environment, in your overall architecture. When there is relevant data that needs to change, you leave that outside of the container. That's how I would want you to think. Now by doing that, it brings a solid approach to making sure that you remain sane. Because if you keep your data, it is totally able, you can store state in a container, no problem. You can, but it drives you insane. I want you to stay sane. And that's where I would suggest that when it comes down to maintaining state of something, state of the user, state of the data, state of the application, state of this, that, whatever. That's where you want to avoid containers. Why not to export the file system out of the container? That's exactly what I mean by avoiding, don't put it in the container. That's one way to approach. I'm sorry, misunderstood. I'm talking about at an application or in architecture level, what application areas like high performance or we're talking, I know this isn't the case because they use containers is like a machine learning and things, application level ideas that don't, that containers you could use but are not necessarily sufficient or good to use. That was what we were discussing because what we're feeling is it's like XML back in the 90s and 2000s is everybody used XML for everything data related. And it became just overused. And they're feeling the same thing is happening here with Docker is push, people are pushing Docker so hard that they're missing the fact that there's maybe a use, there's an application space that containers should not be used. Yeah, there are cases, there are cases. I'll show you some examples. There are cases like that, which is, it is, you know, the fundamental application itself is monolithic. When an application is monolithic, meaning a gigantic big beast, that is one area which makes it difficult, really difficult to port it to a container environment. So that is easy target to avoid to begin with. So as is you don't take a monolith and put that in a container. That is not considered a good practice. So you still want to think of containers, which means you have to break this monolith into smaller microservices of some sorts. And so if you're able to accomplish, let me see if I can find a tweet from Kelsey. And was it that reason when he said where, when you really know a tool that, or when you've mastered a tool, you know when not to use it? Yes, exactly. Like that's his latest tweet. And then a couple of days ago, I think he tweeted something else. Kelsey, we'll do one of Kelsey's exercises, by the way, when it comes to Kubernetes, he is a well known, very respected person. So that's, that's how I follow him. I like what he's doing. And I will be using one of his, the Kubernetes, the hardware example in our program to understand what exactly this Kubernetes thing is. And we'll do it the hard way. And then we'll automate later on. We'll do the difficult way, but I'm just quickly see if I can find the idea. Maybe not so quick. So yeah, I could not find it. Now it's probably buried somewhere deep. But bottom line is when you're dealing with a monolith, you think of it as, you know, how do I say this describe? So I think another way to think about is this example. So here we go, SAP. So here is SAP HANA, which is available now on the Amazon cloud. SAP used to take me three, two to three months to set it up. Just setting it up, right? Two to three months in year 2000, long time ago. Now it takes a couple of clicks. And that is possible because we can actually find that you can get an SAP setup of HANA in the marketplace. If you go to EC2 and try to create a machine and you want to use in the marketplace and you search for SAP, such applications which are available here, this is like a 99 cents per hour of usage. So you can get SAP HANA one select and sign their agreement and pick the appropriate machine size. So there'll be some machine sizes here. The machines that are capable of running are not here. That's the only one I think that is available. Computer optimized, 36 CPUs. It's a fairly large machine. You can configure it further and you can put that in wherever you want. You want to add some storage, already predefined some storage and some disks connected. Then you add some tags and then you configure security groups and you review and launch. That's all it takes to set up SAP HANA. If you go really technical, you can in practice actually implement this whole thing in containers, but I don't think it is a good idea to do it that way right now because SAP itself is a complex application. You want to break it down into simpler, smaller ingredient components and you want to run these component-based services individually in a single container and have multiple such containers cooperate to produce the behavior expected of the application that we just discussed, which is SAP HANA. This one and that is from this company called SAP. You probably heard of it. You probably use this in your company. You probably use SAP already. Now taking this SAP and trying to map it to a container setup, not necessarily a good idea to begin with unless the application itself evolves into a modular services-oriented smaller components of the application that cooperate and collaborate together to produce the same result that SAP today does, will be a good idea at that time to containerize it as is. This is not a good application to containerize as one example. You can in theory, if it really comes down to making it happen, you can make it happen, but that's not the ideal way to implement and run it because you should not be running monolithic applications in containers, although you can. That doesn't mean you should. If I find that picture I was talking about, I will bring it up and show it to you in Slack chat later on. Let's see what we did up until now. In our setup that we have, we have two machines running Docker in two different clouds, but we accomplished our goal through the play that we ran, which is this play called, where is that? This role that we invoked, it was available on the Galaxy. We used that role and pretty much ran it like this, line number eight, which is what did it. The whole thing was run through this invocation. That's it. We accomplished our goal and we were able to do that even though we know that in Amazon cloud, the username is different and this machine, the username is different and all that good stuff. Having done this step, I want to actually go and kill those two boxes which are currently running here because I want to move on to the other exercises. I'll say destroy this and let it go. Go destroy this one also and terminate and say, yes. Both boxes dead. Now, I would like to talk about container orchestration a little bit. Before we, and we'll again come back to Ansible, but I want to change the topic a little bit to give you some concepts, conceptual understanding about what exactly needs to be there for us to run containers under the hood. We will have some applications like that running in containers that will be running in some machines. It doesn't have to be a one-to-one connection. Of course, this will need to be many-to-many. You can have multiple applications in multiple containers spread out depending on it. It's a many-to-many relationship, but when it comes down to machines, you would like to have a setup that you can potentially run all these containers in just one box or maybe two boxes or sometimes more boxes or sometimes you have the other boxes go away and these new boxes take care of the three containers that you have running three applications. I would like to set up a system which allows this kind of a thing to happen. The machines under the hood can go and come, appear again, and new machines pop up and machine number five comes along and then I decide that this can go away and maybe this one dies and the application should continue to function. That's the kind of goal I would like to have because I really want to, what I call, pull the rug under the feet of these containers. Literally, I want to do that and when I pull the rug, I want my data to be preserved, my state to be intact, my application to continue to function, as long as I have bare enough machines available at the foundation. Like here, here, some machines are able to handle the work, the other machines are able to handle the work, like here, here, some machines are able to handle the workload that these containers put on. As long as that is true, I can actually pull the rug and I expect my application to continue to perform. I also expect that my data remains intact and available, my state gets preserved, and all of the good stuff that you will usually expect to see. So this is the kind of Uber goal that we have for ourselves and technologies that enable orchestration of these containers have come into play that allows us to look at the underlying pool of machines as a resource, as a place for us to run our containers and where this container, exactly where it runs here or runs here or runs there, is not left to us but is managed by the orchestration layer. Let the orchestrator find out the best place for that particular container to run. It will depend on the capability of the underlying machine. It will also depend on how much capacity is left in that machine and let the orchestrator decide and schedule. If you look at Kelsey's, again, Kelsey. Kelsey is good, by the way. Kelsey is a fabulous demonstrator and better than I can do. I think he is amazing. What he does is, I'll point a video for you to look at later. Kelsey, and he uses the, what's the game called? The block compaction game. It's a famous game. Do you know? Tetris? Tetris. Yeah, Tetris. So Tetris, as an example, he gives a live demonstration playing Tetris and explaining on stage two years ago. That's his video. So it's a four minute video and he is amazing in terms of how he does his live demonstrations. It's just stellar. I mean, that is something that I admire. And so you should watch that video, which will give you this idea, which I described, which is to let the automation for orchestration handle where your containers actually run. Don't worry about it. Trust the orchestrator. It will do the right thing for you. That's how the orchestrators have come into play. There are quite a bit of these guys, by the way, the orchestrators. Let's see how many of them are. Actually there are more than a handful. Docker Swarm is one such technique to allow that, by the way, this is a Docker native clustering system. This is on GitHub. You can see that it is a part of Docker itself. You have to just configure Docker differently, and we will do a live exercise with this right now. And then we'll do the same exercise, but with Ansible. Ansible will be easy. I run the play and it just does the whole thing. We have another exercise ready for it, but I don't want to run the exercise without understanding what's going on under the hood. So what I would like to do is grab a link, which I want to actually use. Grab a link, which I want to actually use. And where is that? Editor sublime, please. Not this. Which is, this is the link I want to use next, but I want to understand it before I run it. So that's the link I'm opening up. And here is the actual action that we will first go through by hand, step-by-step, understand what it does, and then implement it using Ansible. So the exercise that I'm beginning to do is right here. What this does is what I kind of described to you is helps you set up a foundation of multiple machines. Some are managers, others are workers. They collaborate, cooperate, and basically operate in a method in which they will handle. So there is a manager, manager zero, manager one, manager two, like that. There are worker zero, worker one, worker two, worker three, like that. You can keep on adding any number of worker machines and three or five managers. Typically, you're sometimes one manager that will become a cluster of resources. All these machines will basically become a swarm. And on this swarm, you will run containers, like that. That's the way to think about separating your machines and don't deal with them directly, but let the orchestrator layer handle orchestration of these containers on top of the orchestrator, which is the swarm in this example. So like swarm, there is Kubernetes, which is another famous example of Kubernetes is a Google product that you can see it is now open source for the last two years. Open source system for doing whatever it says it does. There are more such examples like MISO. It's an Apache foundation project available in the open source. There is also DCOS, not Costco, but DCOS, that one. Another one, which also does conceptually similar. Excuse me. It lets you run containers, it orchestrates it for you. So all these toolings, you can deploy a complex, full-blown data center for your applications, and it let it handle the grunt work primarily. That's how I look at these guys. There are, by the way, more. Let's go see some lists. I'll see if I can find a list of all these things. So here is a list of all the other orchestrators that are available. And I mentioned Docker, swarm mode, Kubernetes, Marathon, console, Rancher, ECS, and these days, EKS. No, not this, not this. Amazon EKS, and then Amazon AWS EKS is coming up. Not ready yet. It is in trial preview. So it's not available publicly. Then there is AKS, which is Azure Kubernetes service. So there are lots of other services are ready and available. So we can evaluate all of them. But primarily what I have seen is that the industry has chosen the leader, the winner. The winner is this guy. That's what I have found. That's what I find through my interaction with people who are using these orchestration toolings. Kubernetes seems to be the one that has won the war, maybe. Maybe I don't know. I'm not going to be the judge. Let's put it that way. I don't know who won it or who loses it. I should say that I like Kubernetes. That's the best way to say it. I like it. I use it. That's where we will have further exercises also, by the way. So that is one of the orchestrators that I think I personally like very much. You might like it. I don't want to call it a winner or loser because that's immaterial. I want to win. I want you to win. These are tools. I mean, who cares about the tools? So Kubernetes is one. SWAR mode is another, which is what I will begin with. Another exercise. There is marathon that I mentioned. This is not really an orchestrator. I don't know why. This is not an orchestrator. I don't know why. This is not an orchestrator. It's Nomad for HashiCorp. Yeah. This is another orchestrator, Rancher. I think Travis is having some fun these days with Rancher. Yeah. And then there is elastic container service, which is a custom implementation of orchestration from Amazon. So this is not strictly open source. Then there is this marathon that I mentioned, which is open source. Then SWAR mode, I think we are going to handle an exercise on this. Docker itself does, on its own, does some orchestration for your containers to function according to what you expect. Then we have EKS, this thing, a new thing coming up, not available yet publicly. I am about to get access to it. If I get that access in time, I will show it to you, but I don't have it yet. So I can sign up for the, which I have already asked them to give it to me. This thing is a competition to Google's container service called GKE, which is another orchestrator. This Google Kubernetes engine, which is what I currently use. So you can see in production, there are machines running Kubernetes cluster, and there are the workloads that are currently running. And you can see that some of these sites that you are familiar with are actually running right here. You can see that the cloud genius sites, the chat site that you may have seen before, the other sites that I'm building are available right here in the same location on the same Kubernetes cluster run and managed by Google cloud. So in competition with this solution from Google, Amazon has come up with EKS, or rather they are coming up with EKS, not ready yet, but if I get access, I'll show it to you. And then there is this Azure thing, which is again in direct competition with Google's GKE, Google Kubernetes engine, which is the Azure implementation of Kubernetes, Azure Kubernetes service. In fact, they should have named it as Kubernetes, but probably they didn't, don't know why. The short form does kind of indicate that it is indeed Kubernetes, but they call it container service. They say it's a Kubernetes environment, but whatever, we'll understand what these things are. And we'll focus most of our time and energy on swarm mode and Kubernetes, actually Kubernetes and swarm, I should say. Some swarm to give you a flavor of what these two tools are and jump to more with live examples on Kubernetes. But I think having a comparison of these two tools will help you understand how the tooling is, how it is done from scratch. And then we'll apply automation onto a bunch of machines, like I mentioned here, the underlying machines here. So we'll take some simple examples of one manager and, you know, worker zero, worker one, and put them together in a cluster or put a swarm on top and have that done through Ansible. So that gives us a ready-made swarm. And on that swarm, we can then play whatever we want to run, whatever application you want to deploy. And we'll use that orchestrator that will be available to us. But I don't want to run Ansible directly to get a swarm ready, because it will take me like 10 minutes and I have a swarm ready, but we'll not understand what swarm is under the hood. That's not what I want to make sure, make sure that I want to understand what swarm is. So that's the beginning point where it describes what swarm is. So we'll read that. And then we have the exercise already available, which invokes like this. So you can see the exercise. It actually does implement Docker swarm on three machines like I described, but we'll run that exercise later. First, we'll do the whole thing by hand. So that gives us a clear idea about what is this one thing? What does it do for us? How does it interact? How does it connect? How does it operate? How do we run services on top? And then we automate the whole thing. That's the idea. If you want us to do something differently, please tell me. But I would like to caution you that I do intend to run this Kubernetes the hard way. And it is hard. So just mentally prepare yourself for that. It is quite a bit of an exercise. We'll do it. I'll do it live with you. But it is, yeah, it is hard. I mean, that that's the target audience primarily is for someone who is planning to support a production Kubernetes cluster and wants to understand how everything fits together. That's the goal of this exercise. There is absolutely no automation in this exercise. It is the hard way. We'll do this the hard way. And then we'll automate it. Or maybe just use a readymade service to quickly get to, you know, what I call, quickly get to something functional. We'll do that easier part also later on. But first begin with the hard way. So this is for another day, not right now. It will probably be some sometime later. I don't know when yet. Today, I want to focus on this swap mode, which is a whole lot simpler to understand, compared to Kubernetes. That's why we begin here, because this will help you understand Kubernetes later on. So let's go read briefly. And you can read this yourself. So I'm not going to read it line by line, but just give you highlights about what this thing is we making us go through. So here actually is a tutorial, by the way, on this page, it's a sequence of steps written down by Docker company for us to understand what the key concepts are. And then we run some actual hands on exercise. There are some bunch of commands here. And some key concepts. So let's go see what the concepts we need to know and what is a swarm. So in effect swarm is think of it very simply. Machines one, two, three, operate together, give you a foundation on which you can operate together, give you a foundation on which you can run containers one, two, three, four, five, and any number of them, as long as this machine set can handle it. That's one way to think about. So it gives you basically compute horsepower for you to run containers. It also gives you the each one of these machines has a disk right under the hood. So it gives you access to the disk space. So these containers can actually connect to disks in wherever these three locations are. So it gives you some storage exported from the underlying machine that you can map to directly in a container and use it. That's the storage element. The swarm also gives you an overlay network. We just think of it as an independent subject that allows you to connect and have these containers interoperate among each other. It also gives you the ability to expose certain services running on these containers onto the overlay network. So you have some service running here. You may want to expose it on the overlay network. And then from outside, let a user access that. That is also a possibility. You can also include a load balancer here and construct a load balancer service such as HAProxy. You can include that and have that interact with any services that you expose to other users outside the actual user that we use, your application that you will run in a swarm. That's the kind of overview briefly. So it gives you storage network and compute horsepower as provided by the underlying set of machines. In this beginning example, we'll begin with one manager, two workers. So one and two, so one and two, worker zero, worker one, and one manager. So three guys, three boxes together gives us the infrastructure needed in this simple example. That is a swarm. We'll run services on top of the swarm. There are nodes. So these machines that I mentioned here, these are nodes, three nodes. We'll run services and tasks. There'll be a method of load balancing to allow external users like this guy to come in. And then once it comes in, it actually wants to interact not with the machines, but with some containers running somewhere, running some services. So this user wants to actually interact with a container that is exposing a service. So you want to somehow let this traffic go to the right location. That's another thing that you will see happen in an example. We will run a reverse proxy to make that happen. Next. I think this is more of readings. I'll keep going, jump straight to the next one. We want to set up three machines right now. So here, let's see how much time we have. 638. I think we can get through the setup parts. I think we should be able to succeed in that manual parts. So here is, we need three Linux machines which can communicate over a network with Docker installed. Okay. We can very easily do that. You know how to do that. We need to get to the cloud location, say for example, this one. And here I say, create in Seattle, give me some Debian machines that run a decent size and give me a private network. This private networking, basically what I'm asking is another Ethernet adapter. So in a typical box you get, you will have an Ethernet adapter, it's zero. That is public IP facing. And I'm asking for another Ether adapter. That is internal. That is what I'm really asking when I say give me internal network. I'm basically asking for another Ethernet adapter and an internal network to have these machines connect among themselves on a private network. They will of course have a public network also, but the internal communication among these boxes should happen on a private network. Private network. That's where this thing comes into play, internal adapters. That's what I'm really asking here in this location. When I say enable private networking. So I did that. Then I will say that you want to give these guys a name. You just unchecked the box for the network. Oh yeah. Thank you. Thank you. So I now check that box and then choose my key. And then I give these guys names. So say manager and then worker and worker. So that's the three machines I'm creating. Debian, Seattle, reasonably big size with like 8 GB memory. I can go smaller. It doesn't really matter too much. So small and name, machine names. These names are irrelevant, but deploy. So I deployed three boxes just starting up. Let's see what the exercise further says. So we have to have Docker installed. You know what to do with, you want to get Docker installed. How do you do that? You want to do it. The previous exercise we just ran, right? We just want to get to the previous exercise we did here. And so this, this late for dinner needs to go break, quit the terminal. And the exercise I want to do is the Docker Ansible exercise we just ran. That same exercise I want to repeat, but this time, why are you terminal not dying? Okay. Dead terminal. And I'm going to get to the Docker, Docker Ansible. Okay. This exercise we just did. I want to repeat that exercise for the three boxes. You know what we did? We ran this inventory on these boxes here. So now I have pretty much like manager zero and two more lines like that. So manager zero, worker zero, worker one. Like that. And I want to make sure that I fix my IP address is currently broken. So I need to fix that. And I should be functional at the end of this setup. So I delete all this. And these are the three machines. I want to really make them Docker capable. So I will do exactly that. I'll grab, first of all, grab the IP addresses from the cloud location. Come on. Where are you? Close these unnecessary windows. Close, close. And this one, close. This one will give me IP addresses. So here is my manager. So copy and put it right there. And then the next one, worker zero is this IP address. So save that. And then the third one, worker one is this one. So three machines, correct IP addresses, correct user, root user. And private key is also correct. And Python three, because this is, I think I chose Debian. So it is Python three. Is it Debian or what? What did I choose? Debian. So I don't have to have Python three, by the way. Debian includes both, as we saw. So I can get rid of these guys. So I have, so I have a slightly simple example. Without the Python three reference, three boxes that go like this. Simple. Now I can run our play. What I will do is go back here and say, I want to play my playbook. So work on. This work on is a method of running Python for me. It is a virtual environment that I'm using. We'll talk about virtual ENV later, if you're interested. But right now, Ansible playbook, and play the Docker play on these three boxes, please. So it will go and set up Docker. And we'll just hang tight for two minutes, three minutes, and it should be finishing it up. On all these boxes, as you can see, it is setting up Docker. Work manager zero, worker one, worker zero. All three guys will be set up with Docker in a matter of two minutes. In the meanwhile, we'll go read further. So Docker is installed. We need to know the IP address of the manager machine and open ports between the hosts. So we have that enabled already. We have three networked host machines. Docker is the latest version. We are getting that. And then we want to use the IP address of the manager machine and connect to it. So we'll connect there. And then we want to make sure that these ports are open. All of the ports are open. There is no firewall here. So it's the easy way out I'm taking. If you're dealing with Amazon cloud, or some other cloud that gives you a complex way of handling security, or even these guys, I think, give you a firewall, you need to make sure that the firewall is intact. I did not choose that firewall by design, by deliberate intention, because I want to keep it simple. But you should use a firewall. And in that case, you should set up your configuration of the security groups to match these ports. Like TCP port number 2377 should be open for cluster management communication. Port number TCP and UDP 7946 for communication among the nodes. So node to node communication, machine to machine, these three boxes we are talking about, they need to be able to talk to each other like that. So that security group has to be enabled. And you want to open this UDP port 4789 for overlay network traffic. And if you want to have encryption enabled, you want to enable encryption. And then you need to also ensure that this IP protocol 50 ESP traffic is allowed if you are yes, what is it? What do they mean by overlay network traffic? Okay, an overlay network is basically something that is a different subnet that you basically make it up and you assign here. And a leg on every machine gets an IP address from the subnet. And every container also gets a leg on this subnet. And that is on top of existing network that you already have here. The private network that is a separate network provided by the cloud company. This is public facing. This is a subnet that you make up, literally make up like making stuff up. That's the concept. You make up a subnet and you make everybody get an IP address assigned by this subnet. That is practically what an overlay network is. And you will see an example when it comes to that point. You will see that a new subnet gets to allocate an IP address and an address shows up in the IFConfig listing on each of these boxes, as well as each of these containers. They will get assigned a separate IP address from this overlay subnet. This requires extra software, which is given to us by default by Docker. But in Kubernetes, somebody else has to do that work. So that's another complexity in Kubernetes. You have to use some third party software to make that happen. There are open source solutions available by I think five or six available solutions that you can use to enable overlay network traffic in a Kubernetes cluster. A cluster basically means bunch of machines together. That's where we are dealing with three machines right now. And that is getting set up with Docker as we know. So we are just making sure that our necessary ingredients are in good shape. I don't have to really worry about open protocols right now because our whole traffic is there. I didn't even bother creating a security setup. But this is something that is necessary if you're doing it for real. You want to make sure that your security group adjusts and meets these requirements. Next, we'll create a swarm. Now that we have three machines running Docker, we want to configure a swarm. Configuring a swarm is simple. Not difficult to think about. It's actually pretty darn simple. Think of it like this. Let's quickly check if our setup is complete. So the setup should, it failed. What? Oh, the user name. Okay, fine. The last step failed because I did not call out a user name, but the YAML file did not have a file for late for dinner. And the other host names have different names like manager zero, worker zero. They all expected a username, but it is root. So we can ignore the failure. It's not really a critical failure. That's what I want to point out that it is looks like a failure, but it is not actually a failure because we don't need to worry about it is already a root user. So having said that, I hope you understand what I just said is to ignore the error and it is okay because the user is root. And what we are really doing is to add that user in Docker group members, but it is the root. I mean, it has already had access to the whole system. So why bother? So this line is not strictly necessary. That line is what failed at the very last step here. The red items is to add user to the Docker group. That piece failed. We can ignore that. Or if you want to fix it, I can tell you how to fix it is to create a file like late for dinner, for master, for worker zero, for worker one, and you're golden. That's what you can see if you, if you want, I can show it to you, but I think you understand. So I'm skipping that piece and actually get our swarm up and running quickly to get a swarm up and running on three machines. We have N zero, W zero, N zero, W zero, W one. What we really need to do is something like this. You have to go here and say, you manager, you become a leader. You set up a swarm. And so this manager says, okay, I'm now a leader. I will give you a secret token. You take that token and you go here and say, Hey, here's the token, the secret token. Please join the swarm, join the party and do the same here. Token, the secret token that these guys generated. And you say, join the party. And as soon as you finish these actions, the whole thing together becomes a Docker swarm. That's what it is. That's, it is as simple as that. Now under the hood, there's a lot of software written by Docker to make this happen. For us, it is literally these steps to go to the first machine that we want to use as a manager and say, Hey, why don't you become initialize a swarm? So it says, okay, here's the token, take it. You go to the other machine with the same token and say, join the party, join the party, bring everybody to the party and everybody becomes a swarm. That's the next action. So here we go. We'll go look at our terminal where we have these three machines that we know already is I think called out in the host file. The three IP addresses is what I want to use one at a time. First, I go to the manager machine right there. So SSH root at manager. So this is the manager machine. You can see it. And now here, I want to do the first step, which is this step. Hey, you become leader and you want to initialize a new swarm. So swarm in it, like get in it, like swarm in it. That's pretty much it. I think that's the command if I remember right, but let's go read. The command is to first connect to the manager box that you intend. And then you say Docker swarm in it, advertise address, manager IP. That's the command you want to run. So we will run it. Pretty much it, it evaluates like this, pretty much like this, except here you want to make sure that you want to advertise the private IP address, not the public IP address, right? You want other people to join the manager, join the party using. So these guys have two IP addresses, like one is public facing, one is internal. Like I mentioned before, ETH 0 and ETH 1. These two Ethernet adapters, there is an internal network that we have constructed. So if you now go to the cloud company and say manager 0, what do you got? So it will show you the settings and there is a public IP address right there, the main IP. And then there is this private network IP address also available, which is what I want to actually use. Because what I want to do is make sure that our communication that happens on the private subnet internal network, not here. You can communicate on this, but I don't want that communication between the workers and managers to happen on the external network. I would rather keep that communication internal. That's the whole reason why I began creating these boxes with a private network. That's what I really want to do is to let these guys talk. So I know that there is a private IP here. I'm going to use that private IP for the manager to initialize the swarm right there. Here it says, I'm going to use private IP here. It doesn't actually say that, but that's what I want to do. So I will do exactly what I have in mind, which is to use the advertiser address as the manager IP. And when I say manager IP, I want to use the private IP. So I'll go take this in the command, copy it, paste it here, something like this. And in the manager IP, I don't want to use this IP address. No, I don't. So what do I use? The private IP from here. Where? This one. Grab it and paste it. Similarly, I would like to also keep a track of all the other IP addresses for worker zero and worker one, the private ones. So I'll go grab that private IP from there. This was worker zero and this is worker one. Come on, worker one. Settings and show me the private network. So I have the other two IP addresses showing up right there. I keep them safe here. I want to now invoke this command, which is to initialize, ask Docker to initialize a swarm using this advertiser address as the private internal IP address of that box. So I will go to the machine first, which I'm there already. I can go check its IF config. I have this external IP address and this is the Docker zero address. And what I don't see is the other address, which is going to be a problem. And that problem I have solved in the Ansible version of this implementation. But this exercise, I would like to change what I just said, because I have done this in Ansible. It Ansible automatically creates a private IP, grabs it, puts the token in the right place and all that. But for this exercise, while we do this by hand, I would like to change and actually use the public IP addresses because I don't want to go through the manual step of making that happen. You can do this manually also, but I don't want to do that. So I'm confused. Why, what is it that, how, how do you get that solved that? Are you, are you manually adding that second ethernet adapter and setting it up? Exactly. That's what I will do in this, in this Docker. And they didn't do that in, in there? Yeah, they did not do it. They did not do it right. They should have done it. When we set up the configuration, they should have enabled another adapter like this and should have given us an IP address, which is mapping the private IP right there. And they did. So you have to manually do that. Yeah. This, this cloud did not do it for me. That is unfortunate. Yeah, that's stupid. Okay. They should have done it. I mean, when I asked for a private network, you better assign an adapter for that, but they didn't. Instead, they show us this detail, which is what it doesn't even describe anything. I mean, that's the unfortunate part, but I should tell you how to do it. If you want to do it by hand, where is that our Docker Ansible exercise that I just pasted the very last link on should show us how to do this in Ansible. I just read the Ansible code and tell you how to do it manually. So quit. This hammer spoon is continuously coming up. I'll keep quitting it, at least for today and fix it later. So this piece of code that you can do manually is sitting right here in the play book where I associate a private IP and this is how you do it. So you have to run a command manually like this. You have to open this file. Let's see network interfaces in that location and there you add a block like this. And in here, you want to change the IP address to match what the cloud thinks that you should have. Meaning you should match this IP address for what machine are we on worker zero. So we should go to the manager IP address, which is this IP address. That's what should be given to the cloud in the address section of that location. That's what you need to do manually. You create an adapter and then save that file. And then what? The remaining step is to IF up ENS7. That's the last step that we invoke and bring up the adapter. And now we go IF config. We should see another adapter right there. ENS7 showed up with the IP address that we expected. That was the manual step that this cloud should have done for me. They did not. Thank you. Whatever. For this exercise, we will use the public facing IP address. By the way, don't do that. Always use the private ones. But I'm for today doing the bad way. So just copy this and use this address. This is the wrong way of doing things. Just remember that. Having said, let's go initialize the swarm. So swarm, I want to initialize on the master. We'll say master, please initialize the Docker swarm for me. Let's see what it says. It says, here's the token. I initialize the swarm for you. So swarm initialized. Current node is now a manager. And to add a worker to the swarm, run this on the other machines. So run this command. Here is a token, by the way. And run that command as is on the other boxes. We grab the entire command. Look at it here. And this needs to run on the other two boxes. You will notice that here is a reference to the IP address in the advertiser address, which is this address. Same address, repeated here, with the port number 2377. As you recall, this port is useful for communication among the nodes. You saw in a previous step, it told us to open the ports 2377 for cluster management communication. That's the same port being used for inter-node communication for us to allow the other machines to join the party. The join command is line number 12. I want to connect to the other machines first. So this is one machine. So we'll say SSH root at this machine. And then we'll say, root at this machine. And then SSH root at the other machine number of worker one. We'll copy that, put it right here. And then run this line number 12 on those two machines. So we'll go first, worker zero. Run it here. Quit from here. Worker zero, please. And then run this command. And it's as simple as, boom, running it. Now it joined a swarm as a worker. Great. Next, other worker, please. Other worker. You come here and join the swarm. How do you join the swarm? You run the same command. And it joined the swarm. Now it joined as a worker in the same swarm. So we come out of it, go to the manager this time. And here's the manager. And you show me Docker worker node list. So now it tells me that it is now you're interfacing with a Docker swarm. And this manager zero machine is actually a leader. The two machines that we have, worker zero, worker one, are now ready and active. And your swarm is functional. You can access the swarm right on the manager zero machine itself. That's what we just did mechanically, manually. And what I would like to do is do the same thing, but through automation in the next exercise, which is the next time. I will now pause recording and go fix my laptop. Misbehaved poorly today. So sorry for that hiccup in the first few minutes. I'm going to stop recording right now. And I'm open for questions. You're still recording. Yeah, I am. My machine is very sluggish today. I don't know why it should stop recording, by the way. I see the recording. It went away. Nope. Still recording. Is it still projecting? Oh, still recording. Okay. So stop recording. Now, finally, it,