Good. Good. Good. Oh, excuse me, sorry. I am a question on you here is early. Hey, hello. Good morning. This is Neeraj speaking. Hi, Jason. How are you doing? Hi Neeraj, can you hear me? Okay. Yeah, I can. Hey David, Raj, how are you guys doing? Can you hear me? Okay. Good morning. How's everyone doing there? This is Raj. Hello. Hello. Yeah, I can hear you fine. Yep. Beautiful. Beautiful. So we have a new person today and he is Jason. He is available online with us. He is thinking of joining. I'm not sure how do I describe it? Thinking of joining, joined. What's the status? Uh, just try to, uh, just check out and see, uh, see how the, the class is going. And okay. Yeah. So I think my, my reading of what Jason is trying to accomplish is to figure out if this class is the right one for him to join right now. That's the thing that I read. And so that's what he's attempting to do today. So, uh, the people who have showed up right now are not Boeing employees, by the way. Uh, so, uh, uh, Jason is a Boeing person. There are two people just like Jason that joined a late, like a little bit late, like a couple of days ago. And so what I'm suggesting is that you directly talk to them and see what they believe in terms of, you know, how are they catching up and things like that. So, you know, that would give you an independent perspective on how easy is it to catch up if, you know, if you want to take that route. So I think I would let you make your judgment instead of, you know, putting my ideas on your head. So that's the reason why we have you here. As soon as those other two people who, who joined a little late in the program, as soon as they show up, I will call them out and say, you know what, Jason, you should talk to them. So we'll do that right now. We have David, uh, we have Eric, we have and Kara just joined. So, uh, yeah, it's, it's building up the group is building up momentarily. Let me be oriental a little bit and we can be able to start soon. So new guys are supposed to bring donuts. So Jason, good morning everybody. Hey, good morning, Kara. How are you doing? Doing just fine. Yeah. So we have a new person right now. He is also a Boeing employee, just like you. Who's that? He is Jason as he's visible to you. Hi, Jason. Welcome. And he's deciding, I let you describe Jason, what you were trying to accomplish. So I let you do that. Yeah. Um, I just, uh, learned about this, uh, this, this cloud course. So I just want to check it out and see, um, I also know that this is like the third part of three parts series. So also trying to assess whether or not I can try to learning all this or I should try to wait to the next, the next series to jump on. Yeah. So just Josh just joined. Hi, Josh. Josh is one of those people who joined late in the game. And so, you know, Jason is joining, uh, or thinking of joining late in the game also, so it will be good to speak directly to Josh, Jason, meet Josh, Josh, meet Jason, both of you are Boeing employees, by the way, and both of them kind of started in the midway. So you guys talk and I'm getting ready to start so you can talk. Hey, Josh, can you hear me? Kind of went mute there in the list. I know he was mute. So I'll unmute him. He is, his microphone is not connected. Okay. Fine. So let's proceed. I'm going to share my screen coming up shared. And what I will now do is open my notepad and describe the concepts we want to discuss today. That's what I will be doing. Nilesh. Yes. Hi. I think your mic has to be adjusted. The volume went down after you coughed. Okay. Okay. I see. I know. Thank you for catching that and I will fix that. Yeah. When coughing happens, what happens is the average volume level goes up because of coughing and so it thinks that I am yelling when I'm not. And therefore it attenuates the volume levels. And so right now the volume should be okay because I put the microphone close to me. Yeah. The volume is good now. Yeah. Good to know. Good to know. And one more adjustment I think I need to do to see the screen properly and see all of you also properly, that's what I'm doing right now and that is coming up. I need to disconnect, leave the meeting and come again. I'll do that. I leave the meeting and join again. That should do it. Okay. That did it so I just, uh, came back. Hey, Josh, uh, can you talk? Can you hear probably he's on the phone or something. He's not on a regular microphone. That's why he's not connected properly, but just remember, Hey, Josh, I would like you to meet Jason. Jason is a new person trying to join middle of the game, just like you did. And so both of you are doing employees. You should find each other and talk so Jason, Josh, Jason is his last name is Jan and Josh, you can see the name on the screen and so just talk to each other internally after the, after the session or something like that. So please do that. That will give you a good perspective, Jason on, uh, Josh as well to Josh things about the program, how he's catching up things like that. So you should do that later. And I just wanted to make that introduction so that you know each other properly and that you know each other better. Make that introduction so that you know, each other, both of you are internal to Boeing so you can figure you, you know, figure out where you are and connect using link Skype for business or something like that. So talk, that's what I'm suggesting. Sure. Thank you. Thanks. Sure. And now let us continue our discussion. So we had the last time we were, uh, you know, uh, let me remind myself as to what we were discussing, I keep forgetting what we were discussing. So we were doing the Ansible thing. I think, yeah, Ansible exercise. We did one Ansible exercise. I have created two more Ansible exercises for you and I'll, I'll describe them. Then we'll do it with you and then we'll switch over to Docker. Docker will go, you know, elaborate, uh, examples of how we use it, how we put to work. That's how the industry has evolved. It is using Docker containers and microservices and, you know, a variety of examples you will see as you go and use Docker as well. Uh, we have touched a little bit on Docker already in, I think, uh, just brief examples of creating an image and something like that, that I think many of you have done that already, but, uh, we'll get to Docker when we get to it right now. Uh, let us, uh, open those two exercises where I have made notes for myself and I will see them and then describe to you the first concept. And so the first concept is actually about security. How do you make something secure enough? And so the idea of security can be applied to what I would call just some, some machine that you receive off the shelf, just enough operating system that you receive from some cloud provider. You want to make sure that that box that you get is hardened, hardening, hardening, making it secure according to what you desire. So you have to have, you know, a couple of things that need to happen. Excuse me. Excuse me. So a couple of things that need to happen that is what this particular exercise will accomplish. So our desire that we are trying to describe in an Ansible example will be to make this machine secure. That's the desire. And that's what we will implement that desire of making that machine secure in very specific ways. So when you get a machine, uh, for example, go to some cloud and get a droplet, for example, digital ocean, you go here and get a machine. That machine gives you, uh, what I call, you know, just enough operating system with a SSH access and things like that. However, a bunch of things are, you know, uh, they're candidate for improvement from a security standpoint. That's what I will describe now. And so let's get the machine, for example, and then we'll keep talking. There is a machine already running apparently here. Okay. So I'll need to delete that. This was an exercise I was doing last time, last night. So destroy that confirm and then get a new machine created. And this new machine that I'm creating is essentially, uh, we'll select some operating system, for example, let's say this version and the cheap machine, $5 machine, uh, get, uh, in San Francisco, put my key pair in place. And, uh, then I will give it some name, like some name here, and then I'll say, okay, create the machine. So machine is getting ready. Now, when I get the machine, uh, what I notice is that it has, it has access to root password, right? That root is a user that I would like to avoid using because it has super user privileges across the board. So what I'm going to do is read my notes and describe to you what the security concerns that I am intending to address a couple of things that I would like to have is, is actually listed down in this particular playbook in Ansible. So what I want to do is grab this playbook in our virtual machine. This playbook is available in, in your Slack chat. So it's not on the website quite yet, but I want to, what I want to be able to do is give you a link to this entire. This entire folder, which is what I just did. And so here is what I'm going to plug. I'm going to clone it locally in this machine, one of these machines. So here we go. We start and in that machine, I will bring that entire source code and then read what that desire is trying to express inside that particular example. You will see that there are three things, you know, those three things are in Ansible configuration, a host file reference, and the playbook itself. The three things. That's it. It's not much, not, not complex, but critically important to understand, which is what I will do is open this terminal and clone that thing, which is the one I just pasted in Slack chat. So that thing is what I want to clone. So I will get that link copied over, bring it here and clone it. And so it is cloning that thing right now. When I successfully clone it, I should be able to open that thing. So I'm going to inside that folder, opening up in atom editor and trying to understand what it contains. You will see that it has three files in there, right? Those three files that you look at is what you will see here. One of them is the configuration for Ansible, which says, you know, what my hosts file is that file called hosts. It is very clearly saying that my host file is this file here. And it also has a couple of more lines like host key checking is false and deprecation warnings false. These are just to avoid some of the, some of the, you know, this, this this specifically is to not having to delete our SSH known host file. So I don't have to delete that over and over. It is not going to check for known hosts at all. So I don't have to delete this file. If I'm repeating the exercise, that's the reason why we have this line. And this line is basically using, suppressing some of the deprecation deprecation warnings that you receive when you're using newer versions of Ansible. So for example, the version of Ansible we have installed here is probably new. And yeah, it is the latest. And so this, by the way, is the February machine that I gave out in February as opposed to January. So it's the latest version of Ansible. It has some changes that actually cause deprecation warnings. And so the line here, line number five, actually suppresses those warnings completely the warnings. We don't need to see them. Honestly, we understand that they are deprecated, so we'll not use them going forward, but that's the reason why we have these two lines. They're kind of cosmetic in nature. The most important line here is that my host file is placed in that location called hosts and that location happens to be this. And in that location, I have this machine here. The machine name can be whatever you like, like literally whatever. And the host IP address needs to match. Means to match what? Match the machine that we created here. So we have that, that IP address here. We copy that here from, from the, the some name machine and bring it to this location and paste it. So we now have appropriate IP address provided to the host file reference. The Ansible SSH user will be the name root. As you know, it logs in with the name root and we are going to use our private key. The private key that we have is the one that I don't seem to have in this machine, by the way, it's a new machine, February OVA, and I have it in the other OVA. So I need to provide my private key. Alternatively, I can, you know, basically create another key and give it to digital ocean, delete this machine and use the new key. You understand what I'm saying? I hope. So this is, this is a new OVA file. I don't have my private key in this machine at all. It's a blank new machine. You can see that my keys are missing. See, I don't have my key pair at all. So there are two approaches I can take a couple of approaches. Like, you know, one of them is to use the older machine, but I have my key already. That's easiest probably. The other one is to create a key pair here and give it to the cloud provider, say digital ocean, take my key, and then create a new machine that uses that key and then use that IP address here. I can take that route. So what are the options? But essentially I need to have my key in place with the machine that I'm trying to manage the current key doesn't exist. It's in a box. So my plan will be to actually create a key pair. So here I'm going to create a key pair right now. So it will be SSH key gen. Enter, enter, enter, and it creates a key pair. So now you have a key pair. You've seen this before, so I'm not waiting for you. You know, we have a key pair idea. I say private key. This is the public key. So I want to cat my public key and. Yes. Why are we not using the standard key pair we already generated? I did not generate on the new machine. There is no key pair to begin with on a blank new machine like February OVA file I gave you, there is no key. Okay. When I, when I give you a machine first time, I don't want to give you a key because I want you to generate one. If I give you my key, it will be a problem. No, I was looking at is you normally generate the key pairs in the dot SSH folder creating in the. No, I'm not. I'm creating the dot SSH folder. See that. Got it. Thank you. Got it. Thanks. Yeah. So I am not. This is not local by the way. Local locally. I have the, the git repository. It is in the dot SSH folder where I created, right? That location. And so I'm going to grab this public key, go to digital ocean, give them my public key and delete this machine. I don't want it anymore and then create a new one. So here is me getting my public key out and giving this to the digital ocean. If you don't want to use this route, you know, there's always many other ways to handle the same problem, which is that you want to get your private key from the old machine and put that in the right box. You can do it that way. So, but idea of options, I'm just illustrating the option that I'm doing right now, which is generate a new kid, no new key pair and a new box. So this is the public key. Copy it, go to digital ocean and tell them, you know what? Here is my new key. Please take this. And so here is my security settings. Get a new key pair and paste the content and call this my February OVA. Oh yeah. And so just give it some names. So here's the key added. Now I have created that machine. That machine does not know about this February key pair. So I destroy it. The machine gets destroyed and I'll create a new one, new one right now. So here we go. This machine destroyed, create a new one, create a droplet. And I'll say, you know, give me some older version of Ubuntu because it has Python two already as opposed to this one does not. This one has. So I will go cheap droplet, $5 droplet San Francisco again and get my February key in place and call this some other machine and create. And so that is the name I just chose. I'm going to get an IP address here. I will get it back in our location, which is this machine. The IP address needs to belong. It belongs here. And then the username is root. The private key is in good shape. We know that all we need to do focus on is provide the IP address. And then our host file is ready. And to just cosmetic thing here is some other machine. You can name it if you like, but it's all cosmetic. Namings are cosmetic. Unless it's a DNS name in which it has meaning, these names are, you know, basically lousy and they have no, they have no connotation as such, unless you actually want to put a proper DNS name like this and then create an appropriate record in the DNS server. In that case, it becomes meaningful. Right now, this some other machine has no meaning. This name by itself has no meaning unless you put a proper DNS record. So the machine IP address is now ready. We'll grab it, copy, bring it here and provide that thing right in that location. So now we have our machine configuration with a root username, the root username defined. Now, having done these parts, let's now read what is our desire. So closing this, closing Ansible configuration, and now reading the desire. The desire is, the desire number one is to add a user called Cloud Genius, right? Because I don't want to use the root user. So I'm going to use a different user. And in this example, we are using the name Cloud Genius as the username. I want to use that, create that using Ansible. Then what I want to do is provide super user privileges to that user called Cloud Genius. Next one is I want to add my public key to that remote user. So this user gets my public key as opposed to the root user, which has my public key right now. So if you go to here and say connect, let me make it big. If you go connect directly to that box right now, say SSH root at IP address, you will see that this thing has the public key in place, but that key is associated. Okay, it's connecting. That key is associated. I'm connecting to the remote machine, by the way, and you can see that the key is associated with the user known as root. And it is placed in the root.ssh authorized key location. You can see what it contains, which is basically going to be the public key that I pasted. And this is the public key that I just generated and pasted in the digital ocean. It came down to that root location for this box that I just logged onto right here. And so I want to not use the root user. I want to create a different user called Cloud Genius. And I am doing that thing basically. I'm describing my desire to add a user called Cloud Genius, provide that user or super user privileges, add my public key to that user, the remote user called Cloud Genius. And then once I have these things in place, I would like to disallow root access so that if you want to come in and log in, you better log in as the Cloud Genius user, not as the root user. So I disallow that. Next, what I want to do is disallow password-based authentication. What does that mean? It means something like this. So for example, here is that some machine that we are looking at. And what I'm going to do is set a root password. So my password will be 123. And again, 123. This is the password I chose. So I enter and I know the password now. Now you will see an insecure mode of access, which is go to another machine, another machine, for example, here. And then in that machine, let us see, try to connect. So SSH, root at IP address. And it will ask you for a password. The reason it will ask you for it denied, the permission denied, because password-based access is disabled, by the way. That's why it denied. So it needs to have the public. It's already secured by default somewhat. Sometimes when you don't use a public key, it may be allowing you to access the machine using a username-password combination. Right now, by default, digital ocean policy has prevented accessing this machine by using a password. So that's why I was not able to demonstrate that piece because it's already denied. You cannot access to that machine with a password. You need to have the public key, which is what we have here. And so it is connected. And you can connect again, and that will all work. However, if you attempt to connect using a password when you don't have a public-private key pair on the other machine, for example, then it will fail to connect, permission denied. That's secure by default. It's a good thing. Next, what I want to talk about the remainder aspects here is that you want to disallow password authentication. You also want to disallow some API authentications using SSH-GSS API. And then you want to basically restart the SSH daemon that runs and controls all these characteristics. So what we are doing is essentially describing our desire in this playbook and then letting Ansible do it for us on hundreds and thousands of machines that we have. So we can literally run the same command in a programmatic fashion across all the machines that we provision and sanitize them from a security standpoint. So it is just a quick way of handling a large pool of resources and associating a new user, disabling the root user, disabling certain other things that we don't want people to be using and use our user and that our user, whatever we have, needs to have a specific password that we choose. So for example, back in here, I'm going back to the virtual machine right now. In the virtual machine, what I want to be able to do is that user that I have in mind that I want to use with this box here, this box, I would like to create a user called CloudGenius and that user should have a password. And I need to provide that password to the Ansible script. And by the way, you will notice that I have provided a password for CloudGenius with this name or CloudGenius underscore password, which happens to be a variable by the way. So these double curly braces indicate that it is actually a variable. Its value is defined here. And the value is like really complex thing. What is that thing? And so how do you generate this? This is, by the way, known as a shadow password. And so this shadow password is not something that you actually create by your mind, but you generate through OpenSSL. So I would like to choose a password that I have in my mind and then generate a shadow password. Why do I, this is, oh, go back, go back. What I want to do is generate a password in my mind. So I'll call it some password. Like, for example, my password will be abc. That's the password I choose for my CloudGenius user. So what I would like to do is generate a shadow password pretty much like this. Copy. No, did not copy properly. So copying and pasting. And then I'll say my password needs to be abc. So what I'm really doing is generating a shadow password using this library. And the human readable password is this, abc. And when I do that, it generates the shadow password for me. So I can then grab that shadow password like that and use it. So I'll copy from here and give this string, which is a shadow password for this human readable password and provide that as the variable expression value here. So that is my password, by the way. And I just changed it. I generated that shadow password using the simple method called OpenSSL password. And I want to use the password abc. And I provided the shadow of that in here. And so this is what I need to write. Now, one thing I would like you to note is that this is cryptographically generated based on the human user input, abc. This is what is generated. And that's the value I want to assign to the password for this user in the machine. And basically create a new user. And so there is a question there. Go ahead. Nilesh, when I did the same command on my VM, it gives a different hash key. I know. I know. And so this hash key will be every time you see a new one generates. It has a timestamp incorporated. So it changes over time. But it is still the same value. So don't worry about that part. Got it. Thanks. It is shadow. It will work the way you expect it to work, even though the actual expression may be different. And so the idea here is to create a new user called Cloud Genius. So I want to do that. How do I do that is basically run this play. So what I'm doing is erasing all of these things right now just to simplify. And here I am striking all of it just to keep my playbook really simple. So I just made it simple. Only one play. And the play is the user module. And in that, I have this user, this password, which is basically ABC, and a shell assigned to this. And it is part of the root group. And the user is to be appended. So I'm going to run this play here. And I'll say, OK, Ansible playbook. Please run the play that I have here. The name of the play is user.yml. And so I will run that command here and say user.yml. And it knows where to go and target the play. It knows because the host file contains a reference to the machine here. It knows how to connect using the private key. And Ansible configuration describes that my host file is actually the file called hosts. That's how it knows to go and target that particular box, for example. You can have multiple boxes. This is just one box. So it will configure all the boxes you have in the host file. We are just using one. So now when I run this Ansible playbook command, which apparently you cannot read. So I'm going to break it and type it again by making it a little smaller. And say Ansible playbook, user.yml. And when I invoke this, you will see that the play in line number 15 gets executed on the target. The play in line 15 here. What will happen is it connects to that machine and it did nothing. It did nothing. Why? Hold on. Let me bring my rest of the content that I deleted back and I want to read what's going on. So I'm resetting my Git repository and I see that you have to do the other things also. So you have to do these three things, actually. You have to go to the user, add the user, add the user to super user, privileges users, and also provide a public key to that remote user. Those three things are needed. And then we can delete the rest. So I'll delete the rest here. Come on, stop, please. Oh, this machine needs to be remodified again, apparently. It behaves a little bit weird in how I manage it. So I am keeping three specific, what I call, tasks. Three tasks. One of them is the user task. Another one is a line in file task, and then a task called authorized keys. So three modules getting invoked. User creation, modifying a line in a file to include root privileges to the Cloud Genius user, and also providing my authorized keys. So those three things we'll do in here. And we'll say, okay, run, please. Okay, run, please. So it is permission denied because my user is broken. I think I reset my example. The user name is root, not Cloud Genius. And so you know what I'm doing is in this step here, I reset my Git repository. So my user that I had chosen was root. My IP address is also wrong. This is reset the whole thing. So my IP address was wrong. I should get this IP address again and put it in the right spot. That is what just happened when I reset Git repository. It put this old IP address there, which is wrong. And now I will play again. And it will go add a user to the machine, add a user to the super user privileged users. Oh, it ran the whole exercise apparently. Did it? Yes, it ran the whole exercise. I wanted to demonstrate part by part and it did the whole thing. Ouch. It finished the whole thing because I forgot to delete the remainder apparently. So we'll do the exercise again and I want to really do this part by part to make sure that you get the point across. So doing it again and read that user YAML again. So you will notice that the whole file, I need to delete that in order for you to be able to see these things applied one step, one task at a time. And I deleted those things, but then I reset. So it brought back the old whole YAML file back in place. So when you run that play again, it does the whole thing again. And this time it will not do anything because all of these things will be green colored because they're not changing anything. The user is already created. So it did add a user in that machine, added user to the super user list, added a public key to that list, to that user. And let's go see and examine these things item by item if that actually happened on the target box. So let's go see there. I go open a new new terminal, go connect to the machine. The machine is IP address is the IP address of that box is here. And by the way, you will notice that this will prevent us from connecting as a root user because our play has succeeded. This play is to disallow SSH access for the root user that play has succeeded. Which means if you try to connect to the box using a root user, for example, like this SSH root at IP address, it will fail. And that failure you show up because you're prevented yourself by accessing as a root user because you said that disallow root user. So it is not going to allow you to connect using the root login name. So you need to now connect to that box using the user that you have chosen. And now it will work. And it did, except you will see that the user name is cloud genius as opposed to root. Having done this step, I would like to understand the other items that we have done in our playbook. So let's go compare these two side by side. So here we go one. And the playbook on the left side, let's go see these things item by item. Is there a user created in that in that machine? Let's go see that. So there is a user created, which you can see the fact that you have logged in as that user. And you can see that the user is cloud genius. You can say who am I to find out who you are. And this is the cloud genius user. Next one, is cloud genius a super user? Can we find that out? So we can do that multiple ways. One of them is to just read this file, etc. It's a sudoers file and you can go see that and we can see cat etc. sudoers. And we'll see an entry here called cloud genius. And we also see that it has no password, meaning password based access has been disabled. You can use the cloud genius user as a password that you have chosen, by the way, that will also be prevented. Next one, did we add a public key to the user called cloud genius? Let's go see that. So we will go to our pwd, find out our SSH location and list out. We will see a file called authorized keys right here, by the way. The file authorized key is, let's go see the content. You will see that the file contains our public key. This public key is what was placed inside this location, which location happens to be home cloudgenius.ssh, as opposed to the other location, which happens to be, let's go there. So cd slash root slash dot SSH. And you cannot go there because you have not escalated your privileges to a super user quite yet. It prevented you from going there. So you need to go sudo and then change the user to super user. So we change the user to the root user now. So here we have the root user right there. And therefore now you can see that the folder SSH contains a file called authorized keys. And that file is the same file except this entry is created by DigitalOcean in that location for this location, root SSH. So DigitalOcean placed this public key for us in this location. We placed our same public key in this location through Ansible. We did the same thing except we said, you know what, we don't want to use a root user, we want to use a cloudgenius user. It's a different user, not root, has the privileges, but use only when needed. It's like with great power comes great responsibility. So you want to be secure as well as be responsible and not behave like a precedent. And so that's what you need to really do. So with that understood the root user, you want to come out of that root user back again. And you will see that the access to this machine is only exclusively limited to the cloudgenius user. Even root user cannot log in. That was possible because we did one more step, which is this one. We disallowed root SSH access. What does that do? We had to go in this file and examine what we actually do. So we can go and examine that file, which is SSH configuration. And we go and see it. By the way, I need to go back to super user privileges and then edit that file. And you will see that the file contains a specific entry in where you will find it disallows login as root. So there is an entry called permit root login and that entry is permit root login no. And we were able to modify that entry through this method. Specifically, we are using the module called line in file. This is an Ansible module to change a line in a file. So we are choosing this file, the destination file, using a regular expression that says, beginning with the words permit root login and make that line look like this. So find that line contains permit root login. It was probably yes to begin with. And we said, you know what, strike that, make it no. And if that line doesn't exist, create it. If that particular line in that file doesn't exist, the state is present. It needs to be there. If it doesn't exist, it needs to be there. So how do we know that it actually becomes there? We can prove this one more time by actually deleting that line. So I will actually delete this entry completely. And I'll say, you know what, you should be deleted. So it's gone. Now we don't have that line. So what I want to be able to do now is run our playbook one more time. So in our playbook, we have some extraneous files. I want to clean them up. And I would like to cat our host file and make sure that our host file actually refers to the Cloud Genius user this time, not the root user. So here, I need to go and modify this user to be Cloud Genius. Having done that part, I will also run the same play one more time. So it will be Ansible playbook. Where is that entry? Playbook, user.yaml, and play the play. You will see that one change, line in file change will happen. And there it is. It did happen right there in yellow color as opposed to green. This yellow color shows that it changed something. What did it change? It basically made sure to disallow root access again. And when it changed something, it restarted SSH handler. So that is also yellow color. So these two changes happen. And in this change, what did we do? We go back here. The entry was about disallowing root SSH access. So if you scroll back here and you will find disallow. No, not this, not this. This entry. Disallow root access to the, sorry, disallow root SSH access. That's the entry that was yellow color. And so we said use the line in file module. Find a line like this in this file. If the line doesn't exist, create it. Make it present. The state is line needs to be there. And the line needs to look like this. And if the line is there with a yes, make it no. If the line doesn't exist, create it with no. And then restart SSH. That is what we have accomplished in this yellow changes that you see here. As a consequence of that change, we restarted SSH here. So now you go back to the machine and say I want to connect to the machine. And here I would like to see my SSH config one more time. And you will see that permit root login, that line we deleted is now present at the very bottom. And that line was created primarily because we wanted in line number 43, we declared the state is present. You need to have that line there in that file. If the line doesn't exist, create it. So it created that. You will also see that by default, it is actually this. When you begin something new, it allows the access that for digital ocean policy allows. So it says yes. But right now it is not allowed. And what we can do is make it yes manually. And save. And then restart that SSH service. And then unrecognized service. I think it is just SSH service. It restarted. And then we try to connect using root user. We have removed that line, basically said yes to the root access. It should allow us now. And it did. It did allow because we said be modified by hand. We can come out and run the Ansible play one more time. It will again prevent. And so you can see that that yellow item will show up now right there. And one more yellow item because at the end you restart SSH. So it restarted. And now you try to connect using root login. Fails. It is expected to fail because that is exactly what we are doing in this scripting. And so what we are really looking to do in this example is to go step by step and harden the properties of our infrastructure from a security standpoint. So you can basically structure things like this. Step by step go along the way. And do what you want to accomplish on hundreds and thousands of computers that you may have at your disposal. Centrally manage all of them. And very systematically control what can happen. So a funny example was one of my Google friends brought his laptop one day. And he was basically showing me this. And in here in the list of processes that are running, he saw something called PuppetD. And PuppetD is basically the Puppet daemon that runs in the background. And he was curious to what this thing is doing. And we figured that all the machines in Google, laptops, user laptops are managed through Puppet. So central IT organization is running Puppet daemon. Like we said, Chef runs on every box in your cloud. You can use those tools like Chef, like Puppet, like Ansible to administer your client desktops also. Provided they are supported, like Google people use Linux laptops all day long. And so the idea would be to have these laptops remotely administer and configure and manage on a global scale, all Google laptops in management from a centralized IT department, remotely keeping the patches, keeping them up to date using Puppet in their company. So that's what he noticed. We discussed further as to what is going on under the hood. And that's when I first discovered that Google is actually using Puppet to manage their laptop fleet in the company. Like this is what Siva Shankar was describing the other day, surface as a service, right? This was their Linux as a service to their employees globally managing their Linux laptops using Puppet. So one of those processes that we saw on his machine was PuppetD, which is the daemon for Puppet. And so that's how they are remotely managing administering using Puppet manifests, pretty similar in concept to what you saw here in the Ansible scripting, where we are systematically creating these desired elements which are expressed in form of tasks. Like in here, Ansible calls them tasks and you just follow through the sequence of tasks that you need to accomplish. And when you run the playbook, for example, here, the user YAML playbook, it will execute those tasks not only the first time when you run it, but also when you repeatedly run them, it will execute them in an idempotent fashion, which is to get the result that you want irrespective of any changes that may have happened. So the end result will be exactly to what you designed it to be. And you saw a couple of examples along the way and even today, I modified it by hand and then I ran it again, it corrected the situation, you prevented root access like this. You declined root access because you ran the play again. So more things down below, you will see more entries. So disallow root access, we saw that. Disallow password-based access to the machines. So you want to not allow anybody to use access to the machines using a password. So we have to go again in that same file and disable password authentication. Password authentication is enabled sometimes. If you go back to that machine and connect using the Cloud Genius user, you will succeed. And then if you edit that particular file, which is the SSH configuration, you will notice that it has an entry corresponding to password authentication. And here, there are certain policies defined here. Permit empty passwords? No. And similarly, there is more. For example, here, password authentication is yes. But by the way, there is a hashtag here, which means it is commented out. So you want to say, you know, change this to no to disable tunneled clear text passwords. And so you can basically create a line that says no. And we have done that somewhere. The Playbook must have done it for us. So we'll go and examine it. And here it is, that line that you see at the bottom. It says password authentication, no. Even though there is another line here that says password authentication no, there is a hashtag line that says permit password authentication. This line here that says hashtag, which is commentary. So it's not really useful except for people to read. And so that actually this commented line says yes. But at the very bottom Ansible has added another line that says no. And so therefore, password authentication and accessing a user account using a password is disabled. If you want to allow it, you can say yes. And then find the entry at the very bottom. Okay, let me go find it again. So password and there is now double entry. One says yes and one says no. So we want to remove that entry here, double delete. And so it's gone. Now let's see password authentication. What does it say? E-A-S-S-W-O-R-D authentication. And so we have password authentication, I think, allowed right now. Let's go confirm that. So we can say password authentication is yes, and it is not a hashtag, which means it should allow us to access that using a password. And let us go see if it actually does. How do we know that? We just save this file first and then restart our SSH daemon. And then come out of the box and then go here. And this is the box IP address, different machine. If I don't have my private key there, I'm expecting to connect to that box using password. So I'm logging in as the Cloud Genius user, and it says, okay, give me the password. And I can provide my password here and get connected. How do I know what password was that for Cloud Genius user? Do you remember? How do you know? Password again, this. And how did we send that password? Through a shadow. This is the shadow. The actual password is this. So when I connect here like this, I'm actually typing 123, 123, and enter. So I did that and connected. It allowed us to connect primarily because we had manually modified the file, specifically this file, to say password authentication. Where is that? And we said yes to it. We can say no, and it will disable password authentication, simply. We are doing this thing manually, and I don't want to do manually, but I'm just calling it out that you can to understand it. But when you're done understanding, you can run it like a playbook, like here. And so it will do exactly what we think it should, and it will go and disable password based access. So here is the yellow item, disallow password access. And this yellow item that you modified something in that configuration, you want to restart SSH. You want another yellow item to restart. So we've got two yellow items and no failures. And now on the other machine, you're still logged in because you already have a login session. You're still logged in. You come out of it, and then you try to log in, denied. That's what we're really trying to deal with. And we are doing this thing not by hand, which is, of course, doable by hand, no doubt about it, but we don't want to do things by hand. We want to do it through a systematic method of running, managing multiple number of machines. So closing this out, the idea is disallowing SSH API access, GSS API access, and a bunch of things that you can accumulate that you can think of along the way. What I'm really trying to communicate through this example is that as long as you have your ideas clear in terms of what do you want that result to be, so the result. It is not just one thing or a couple of things. It can be a really long list of items that you want to have accomplished. This is your desire list. And you can accomplish your list of desires and write that down in form of, in this example, Ansible tasks. And that tasks, again, are written down like this. Pretty much you saw in the YAML file. In that YAML file, you describe these things, tasks, which are basically a representation of your desire. And you can have a long list and you write them down, and that when you play that playbook on a collection of machines in multiple locations, clouds, data center, people's laptops, grandmother's laptop, garage, whatever it is, they will manage. In fact, I actually use tools like this to manage my parents' laptop in India sitting right here. I do that. So an example would be to make the pictures show up. Like when my son was young, we used to take a lot of pictures, and then those pictures should automatically show up on their desktop so they can just see it. And so that is what we used to do when I take a picture and automatically goes to India and shows up on the desktop. That was an automation like I did 10 years ago, something like that, or even longer ago. So those things you can put to use. So the idea is to apply this to a cloud scenario, but cloud is just a bunch of machines somewhere, right? You basically rent from somebody and you use them at a cheap, cheap price. And so that's what we are trying to accomplish, is that we get these machines out, but we want to construct something meaningful, something useful, something secure, something according to our specification, according to our desire, and that we need to be succinctly writing that down if it is answerable in form of these tasks that become your playbook. And a playbook is nothing but a YAML file written down in form of tasks. Like this task, the name and the action, the name, the action, the name, the action. And these actions, like I have here line-in-file action, authorized key action, user action, more line-in-file items, line-in-file actions. And these actions are basically answerable modules, answerable modules. And you know how to find them. You can just go to Google and find answerable modules. And there it is, a long list of things that are available in the documentation. You can go read, you know, it's a fairly long list. Each one of them is quite complex and comprehensive. And you can discover the line-in-file module. And there are cloud-specific modules and application-specific modules, Docker-based modules, a bunch of things. So people have done that work for you. What you need to be able to do is use that work in the context that is relevant to you. So answerable modules exist. You need to put them right here or here. These names are really for people to read. You can read whatever you like. This is irrelevant. This is again irrelevant. But it is for you to really make sense out of it. Writing like this doesn't make sense. It has no meaning. It shows up here, like in this, the task definition. It shows up in English language here. So configure a user. That's a play. That play was the very first play. So let's go see. Configure a user. The next play is add user cloud genius. Now that's the play line number 14, the name description. The underlying thing that actually runs and operates is line number 15. This 14 is just a name. Just a name. So that name is for people to understand what this thing is going to do. And this line 15 is a module. And you can refer to any module you like that the tool provides. And there are lots and lots and lots of them. I mean, a whole long list. And so you can just make use of it. And people are still building new segments, new modules that you can make use of. And so they are here. And you can just refer to any one of them. For example, let's go see line in file. So here is a line in file module we just used. So we'll click on it and understand what it does. It does exactly what it describes. Ensure a particular line is in a file. That's one action. Or replace an existing line using a back-referenced regular expression. So you refer to something in that file and modify it according to what you desire. You create the line if it doesn't exist. So the module name is line in file. That's this line in file. We used it a couple of times. You can see examples right here. It gives you examples of line in file. In that file, look for a line beginning with SE Linux equal sign. And make sure that it looks like this. So if you have a line that says SE Linux equals something, make it say that you are enforcing security-enhanced Linux, SE Linux enforcing. You modify that configuration file, this specific file, and that line in file that begins with the letter SE Linux equals, and make it say this. More examples. You have line in file, this file, SE sudoers, and there is a line if it exists that begins with the word percent-wheel, get rid of it. Get rid of it. And how do you describe the get rid part? You say state absent. My end result should not contain a line that begins with percent-wheel. This tilde basically means begins with in regular expressions. And so tilde basically means begins with any line that begins with percent-wheel, find that line in that file, and delete it. Next, more examples. And more. And more. It goes on and on. It is very illustrative. I think it is one of the best written documentations I have seen for any project. Beautifully written illustrations with examples and usage notes. And that is the use that you will make use of in what I call, what is called Ansible modules. And in here, which is a supermarket-like thing, supermarket, like Chef supermarket. The thing is called Ansible Galaxy or Galaxy. And in this Galaxy, what do we have? Let's see. So what is Galaxy? It is your hub for finding and reusing and sharing the best. The ready-made stuff for you to play with. And that is what we are really looking at. And so in this Galaxy, you will be able to find ready-made playbooks that you will just use. Very similar to the idea of the supermarket, where you find ready-made cookbooks to use. And so the idea in supermarket is you just go and search for anything you like, and you just use it. Very, very similar is the next example that is coming up. So the next example, what we'll do is I'll paste a link for you in Slack chat, and you will be able to use that next example. And that example is this. And so I'm pasting a link for you in Slack chat, and the link is... There is a question that I missed, so I'll answer that question also. The question was, David asks, can you incorporate a list stored in a file or a database query? Incorporate a list stored in a file. Yes, you just saw me describe the line-in-file concept. So you have a file, it contains some lines, and it does not contain some other lines, which is obviously... And so it contains some lines, and your goal is to include a line in that file. So you can just add it if it doesn't exist. But if your goal is to make sure to modify that line in a specific fashion, you need to look for that line, edit the way you want, and inject that line in the right place. And that's how you can edit line by line. But doing it line by line can be cumbersome. So there is also another thing called... You actually block in file. The idea is called block in file. So let's go see that. Block in file ansible. And so you will find it here. And this is called block in file. So what does that do? Very similar to line-in-file, but it is a bunch of lines that you change together. The idea is to insert, update, and remove a text block surrounded by marker lines. So you have something like... Let's go see an example. Let me say if I have a bunch of lines that I would like to have. So I'm providing a block. This is the block in file module. And the idea here is to find that file here. csshdconfig. And in that file, create a block that looks like this, two lines. And you define multiple lines with a vertical separator like this. And that key character is above your return button in your keyboard. It's the pipe character also. You can call it pipe or vertical line. This is an expression used in YAML to indicate that the following segment is a collection of lines until the indentation changes. So you see that indentation here and here. It changed here in the third. After this, no, there is no indentation. So it knows to demarcate according to indentation and these two lines is what constitutes the block. And so you can run block in file and it will insert this block in that file if it doesn't exist. Basically insert and update the match user configuration block and this is the block of code or text. More examples, you have three items, which is this, this, and this, three things, three lines, three lines block you want to include in this file, etc. network interfaces. And so if you want to include that network interface, you want to create a new static interface on an Ethernet with this IP address and this netmask, you can insert these three lines into that file by a segment that says block in file and a name in your playbook and it will insert a new entry for eth0 for the Ethernet connector. It will create that stanza. It's called stanza multiple lines basically in that file, etc. network interfaces, and that will succeed. Hold on, I think I adjusted a little bit too much. Let me get there again. Yeah, so examples again. This stanza that you're looking at, this thing will get inserted into the file here because you're using block in file as opposed to line in file. And let's go read the question again. So incorporate a list stored in a file? Yes. Or a database query, not these things, not these modules, but different modules. So let's go see. How do you see, how do you find out what this thing is? You do a Google search. I mean, that's the best way to find. So you say database, so you have to have a name for the database, for example, MySQL and Sybil modules. Let's see what modules are available. So database modules, there are these modules available. And so we can see that it is available for InfluxDB, Elasticsearch, Kibana, MongoDB, Redis, React, MyMS SQL, Microsoft SQL, and MySQL. So let's go stick to this one, MySQL database. Here, what you want to do in this particular module, click. What it does, it's MySQL underscore DB. What the function is to add and remove a database from a remote host. So you happen to have a remote host that contains and runs MySQL server. If you want to add or remove a database in that server, you can do it like the example shows. How do you do that? Let's go read. It says, create a new database with the name BobData in the database server. So it will use the module called MySQL underscore DB, name it BobData, and state is present. And then that's it. It creates. I meant instead of doing it user by user in your other mine in example, have a list of users in like a database or a file, but then it would just cycle through the file or the database. Yes, yes, yes, yes, yes. I understand. Yes, you can totally do that. Let's get back to the question again, which is here. The question that David is describing is instead of one user, can you specify a list of users and have it iterate on it? Yes, totally. Typically, you don't use a database as such, but instead use with plain text files are best. Really, if you think about it, plain text files are the cleanest way of operations. And you may have seen that in our program, we never use anything other than plain text. All of the things that we have run in the program up until now, even at the end, you will see that I will strictly limit myself to plain text processing, TXT files, MD files, or some sample code files, YAML files. You will see more of YAML coming up, by the way, more of YAML. And so that answers this question that I think you asked. And let's go see forward next. So the next one is another example here, which is I'm opening up. And this example, what it does is uses a Galaxy item, this item from a Galaxy. And what I want to be able to do, the goal behind our exercise, the next exercise will be let's check some break time maybe before the next exercise. It's a good idea. So yes, let me define that we are going to change the exercise to do something, a new desire we'll implement. And we will use the Ansible Docker example that I will describe now. And the idea would be to implement that desire using another play that we will run after the break. We'll take a short break right now. And the break starts now. Is Jason still surviving or gone? You must be lost. I totally understand. It's really your call as to what you want to accomplish. So my goal would be to make sure that you actually stand to benefit from the program, make sure that you are able to apply to what you do at work. And it needs to be interesting for you. You need to really, really enjoy the thing. You know, you heard me say this yesterday, that we don't have an exam, right? So that doesn't mean that it is trivial work. It means actually a lot of hands-on thing that you can do. There are tons. You saw the access, right? Online access to the content. You probably saw this website. And in that back end of the website, you will see. Let me go there. You probably saw. I'm projecting my computer right now. You saw this boot camp and cloud technologies. And then you go to the back end and you have access to all these things, by the way. Do you? These are active for you, right? So let me log in and show you what I'm talking about. So I'm going to log in right now as me. And here we go. So I'm logging in, putting my password, putting a token. So I can enter like administrator. And with this, I go inside. Then I will go and see the site and the boot camp. And then in the boot camp, we have these three items. They are one, two, and three. So if you go to the technology segment, you will find at the bottom that these links become active. Or maybe not. Yeah, they're active. So here, these blue links, you can click item by item. There are lots of things to read and do on your own. And I guess I had a question. So I know you are using Linux on the screens that you were discussing. Yes. Yeah, my background is very, very weak on Linux. So do you even cover some of the basic commands? Yeah. So I will give you a thing to read. And you should practice. The idea is that 99% of your devices that you carry in your hand these days are Linux. 90% of cloud is Linux. And 100% of cloud genius is Linux. So the idea is to learn. I was not born with Linux knowledge, let me tell you. And neither were you. So nobody's born with these things. You can just learn. So figure it out. And I'll tell you what to read. I'll give you a link. You should do on your own. It is not that complex. Yes, we are running Linux commands. Let me tell you something. These commands are not important. It is not important as to what you type and how you do things because the how part is trivial. You know what? I don't remember anything. And most of the time, I don't tend to remember things. I don't have to because we have this thing. The thing is called Google. So we use that all the time. The reason we have structured this program is to not have to focus on remembering anything, but instead focus on things that you cannot do by Google searches. Anybody can do Google searches and figure it out. There are tons and tons of programs available on the internet that you can do for free for yourself and learn. You can do Google searches and find answers to most of the questions. Not most, but any questions, I would say. You can Google search and find a reasonable answer to something. It is possible. It is doable. So my focus is to not focus on the how to do things, but instead focus on why to do things. Why do we do certain things that way or some way? What is the goal? What are we trying to accomplish? Why do we do things? And then comes the thing about what do we do? And the third step is how to do it. Now, when I type Linux commands, people tend to get scared. But I don't want you to get scared because it is not scary. You can always Google it and you will find the answer. So what's the point of remembering these things? Nothing. I don't remember. Since I do it so much that I have it in my finger memory, so I seem to type so quickly that you will be amazed. But yeah, forget all that. It's not that part. The part is not about how to do things, but about what and why we do certain things. That is the most important thing that you will take away from the program, not how to. Yes, you will learn how to and you will eventually figure it out by Google searches or by watching my videos or doing hundreds of other things. But that is a byproduct. That is not what we train in the program. We focus primarily on thinking bigger picture, understanding how, why and what in that order of why from first, then come what, and then how to. So don't get scared with Linux commands because they're not supposed to be scary. They're supposed to be Googleable. So you have Google access all the time. You just search it. What's the problem? So now about learning Linux, I'll give you a link. You take that learning program. It will be easy. It's not a big deal. Don't worry. So Linux and Windows and all these things that you see on the command line can be scary. Yes, I agree. It is not scary, scary. It is actually unfamiliar. You've not seen it before too much. That's why you find it strange. And that's OK. I mean, that's how it works. Things are new. At some point, you get familiarized yourself and you will know these things, like your back of your hand or palm of your hand, whatever that is. What I would suggest is go back to this location here in the cloud technology segment and begin reading these things. See if they make sense to you. If they make sense that you can actually think that you can catch up, you're welcome to catch up. If not, by the way, also at the bottom of this, there are these videos. I think I gave you links to you on your phone. I gave you some links to videos. So those videos are already here. So watch these things and see if it makes sense. See if you feel comfortable right away catching up. If not, you can join next time. No big deal. OK. So you think this is probably a good point for me to drop off and then I can actually start talking? Yes, you are welcome to drop off. Make sure to talk to Josh Wiggins. He is inside your company. So go find him in your internal tool. Talk to him and figure out what makes sense to you. And you let me know. Did you pay Bellevue College already through a voucher or what? Yeah, I already submitted the voucher for the cloud architecture class. So if you decide to not take this program right now, I would like to know that so that I can reduce it. You know, ask them to send you a voucher back or discard it, not process it. Right. Otherwise, you get the voucher process for no reason. And that's not a good thing. Yeah. You know, I think the biggest thing for me is I really want to make sure that I come away with working knowledge versus, you know, it's one thing to get a certificate and a piece of paper. But, you know, if I don't really understand or know how to have that working capabilities, then that's one of my largest areas of concern. So I just want to. So I know how we've talked earlier about trying to expedite, you know, the option for expediting the class. I'm just wondering if it's a better fit to just, you know, jump in on like the next wave, you know. Totally your call. I don't want you to just get a piece of paper. That's not my idea. No, no, we don't. We don't do that. Getting a piece of paper is meaningless, honestly. Yeah. We don't do that. If it is just a paper, we don't offer it. Yeah. We don't do that. So I suggest, you know, do it. Do the way you like it to be most beneficial to you. Most beneficial to your company that is sponsoring you. Most beneficial to the work you want to do going forward. Actually learn. And yes, as a consequence, you will receive certificates. That's byproduct. It's a byproduct. Certificates you will receive at the end, but nobody honestly cares about them except the people who pay for it. Like LTP program, for example, they care for the certificate. Nobody else does. And so you will give them certificates at the end of the course whenever you do it. But that's the only place I think which will ask you for a certificate. Nobody else will do. They will all ask you, can you do something for me? Can you get this done? That's the most important thing. I think we timed out. So let's go. You can drop off if you like. No, no problem. Okay, I will. Thank you so much. And you need to email me about the, if you want to remove your voucher, you need to email me that. And so call me, email me or tell me about after 11 o'clock. Call me and tell me about what you have in mind so we can make sure that Bellevue College removes your voucher. Yeah. You need to drop off basically. You say we come next time, right? Yep. That's what I think you should do, honestly. Okay. Okay. Bye bye, Jason. Great. Thanks. Bye bye. Bye. So let's continue. What we intend to do next is to use a galactical item. The item is available in this galaxy. And what do we have in there? Is a segment that I would like to reference. So before I find it, I would like to bring this entire collection of code that I have written already here into our repository. I want to bring that down, download it, use it. So I will clone this, by the way, and clone this locally on that virtual workstation we have here. And I'm closing out on these things. So one step back and cloning that new repository, which I just pasted in Slack chat. So it is cloning that thing. And that project is Docker Ansible. So we will go inside that project, open it in the editor, and read. In the editor, we will find that there is a readme file that says, you know, step number one, two, and three. So what does that do? It says open the inventory host file, which is this file, by the way, here. And in that file, add the IP address of the box. OK, we will do that. So we have to have a box and put that IP address right in that location, somewhere here. And we'll do that part. Next, pull down this role from the Galaxy. Now, what is a role? Role is, there's a question. Go ahead. Vilesh, is that a module which you already written for this, or this is a new one? No, nothing of this is written. These are fresh exercises I created. So then there is nothing on the website. All you see is these links that I pasted in Slack chat. The website, you don't find them because they are fresh exercises. I'm creating them. So this is focused on using Docker and using Ansible and eventually migrating. So some of these newer technologies that we have, we don't have the website content supporting our ideas, our discussions. So it will only be in me describing it to you until I will have time to write this down on the website, in which case you will see something new pop up on the website at some point. And I'll paste something on Slack chat when I do that. Until that time, there is nothing on the website that describes this because it is new. I just made it like a couple of days ago. So primarily for new content that I'm creating. So the exercises will work. You have access to the code in form of a Git repository. So you see those links there. I just cloned them. You can also clone it and they will work. But the write up that you expect to see that you have come to expect, I should say, on the site here on the back end is not there yet. It's not there yet. So it will eventually come when I will have time. I will write that down by the way. It will pop up somewhere in the DevOps segment at some point. You will see it eventually update. I don't know when, but I'll do it. If I have volunteers in you, I'm just kidding. I'll do it myself. I'll write that myself. And so Galaxy. In this location, what we do is find ready to use playbooks. A collection of ready to use playbooks are called roles. And a ready role is available to browse. You can browse roles and use them. So one of the roles that I have in mind right now is this role. I want to install it. Install that role. The role is called angstward.docker underscore ubuntu. That's the name. That's the name of the creator angstward. And his role is called docker ubuntu. And so that's the role I want to install it locally. So when you install a role from the Galaxy, it needs a place to go and sit. And so that role will get downloaded in a folder called roles, obviously. And so you have to tell Ansible that I will store my roles in a folder called roles. And you do that in this file, line number three. You tell Ansible configuration that I will store my roles in the roles location in that folder called roles. That folder doesn't exist, so it will get created. Or we'll create by hand like this. And so I will store my roles in the folder called roles. And that's where roles will come down. And that is defined in line number three. And what I want to do is here in the readme, run line number seven. It will pull that role from the Galaxy. And so that role happens to be this name, docker ubuntu. And let's see what it does and why it is relevant to us. So I will search it. There is this role from this guy called docker underscore ubuntu. And this is the gentleman who created that role. Paul Durievage, his handle is angst ward. And he has created this Ansible role. And what this does, let's go read. It says this role will set up a machine for you to become a docker host. Basically take a machine that you need to be either ubuntu or debian. And then it just makes it a docker host. So you can run docker there very quickly, very easily. How do you accomplish that? You will basically invoke that role, first download it, and then invoke it. So you want to be able to run this thing called docker underscore ubuntu. You want to play this role on a target machine. And then when you play that role on the machine, it becomes a place for docker. It becomes a place where you can run docker containers. And so the idea would be something like showing you, coming up. Let me stop sharing screen from here and show you another screen that will get you a clear idea about what I'm talking about, which is, I think, relevant. Starting share here, starting share there, and here we go. This is what I want to create. It's a place for containers. So you can put your containers on top and then ship them and run them. And that is what we are really trying to build. So you can put containers there. So that was a good pictorial example. Back here. So effectively what we will do is get that machine and make it a place for containers. How do you do that? You play that role. That's what the exercise will be primarily. So first thing first, I want to bring that role down. So I will copy that and invoke in that folder like this. And it will bring down the role. And we'll put that in the roles folder right here. And it did. So now we have a role here. It's called Anx Toward Docker Ubuntu. And that role is all these things. So we'll just make use of it and then understand what it does later. So when we want to run the Docker play, it will play this playbook. The playbook is called this. The playbook is pretty darn simple. It has no task but roles. And the role that you want to run is this. And the role is placed in the roles folder by that name. And what you're really doing is making sure that you convert an Ubuntu machine into a Docker host. And you want to run it on all the hosts you have in your host inventory. Your host inventory is this, which is only one machine right now. And that IP address needs to be changed. So we'll change it, for which we need to get a machine. So we'll go to the cloud and here destroy this one and get a new one. And here we get a new droplet. And we can choose either Debian or Ubuntu droplets starting from version 12 onwards. So you can choose any of these versions. Some of the older versions do not have the kernel packages needed to run Docker correctly. And so that role that you have here in here specifically will have this capability to include, even if the older versions for Ubuntu 12 does not have AUFS, for example, the layered file system. But no worries, the role is smart enough to handle that. And you know that it does because we can see that there is this capability to add kernel packages and make sure that they are present. So these kernel packages will be added if they are missing specific things like AUFS, for example. In the kernel, without which Docker will not run efficiently, it will not be able to use the layered file system. So it will create regular files and makes the disk bigger for no reason. And some of the other capabilities are required in the kernel that may be missing in the older versions. So it will install those things in the kernel. As you notice, line number eight says that. It will also include the user that you have that you define in a host variable here, for example, root user. And that root user will become a Docker user. And that here is defined as a root user for DigitalOcean. In Amazon Cloud, you have the name Ubuntu and things like that. The idea behind Docker YAML and this reference in line number nine basically makes that group member of the group called Docker. It will be able to run Docker without having to become a root user. That's the idea behind line number nine. So it's a very small play if you look at it from that perspective. It's very small. But under the hood, it's quite elaborate, as you can see in lots of things here that will actually happen when you invoke that particular role. It will target that box that we have prepared in here and we are going to grab that IP address of that box or we are not created yet. So Ubuntu, let's say 14.04, choose a cheap droplet and provide San Francisco location, put my keys in the place. And this is my Docker host. And so I created the droplet. Now I get an IP address. I'll use that IP address back in the machine in the host reference here and put that IP address right in that spot. And then invoke the play. The play invocation is simple. Ansible playbook. Refer to the YAML file. YAML file is this one, Docker YAML. It knows to operate on the host that you have, which is all of them. All the hosts in the host file. And we have only one here. We can have more, just add lines. Right now it's only one. The other one is commented out. So it's not active. But you can uncomment and use it on Amazon Cloud also, for example. So it's just a reference. So the idea would be that we would get the IP address, place it right here before we can proceed. So the IP address is available now. So we'll bring it here, paste it in that spot, and off it goes. So we have now IP address in place. The username is root. The private key reference is correct. And so we are ready to run. We should be able to close this window and play this particular role. What we will see at the result is that machine that we are dealing with right now, which is this machine, SSH. Do that IP address. That box that we have in the Digital Ocean Cloud. Does it have Docker right now? No. It is just enough operating system, barely just enough. So you say Docker, enter, not found. A bunch of other things may not be there because it's a fresh new machine. But we exit. We say I'm going to run the play on this machine. So I will run my play Ansible Playbook and then run the play called Docker.YAML and let it go. So it runs. What it is doing right now, a bunch of things. For example, install the Linux image extra package, which was missing to enable a UFS driver. So that file system that we need, which is a layered file system, is missing on that box. So it is installing it. Then in that YAML file, basically it's running that role right now. Adding kernel components and then install Docker, enable the root user to become Docker user. And that's all. So we will see that. And let us adjust the window a little bit while it runs. And we should be able to see this finishing in a minute or two. And then the installation of Docker finishes and we will have a place to run containers efficiently. And this is how I prefer to begin with nothing. Just enough operating system machines and then convert that into a Docker host and then move on to using Docker. This is just one approach. There are many approaches to accomplishing the same exercise. I'm just telling you my approaches to making it happen. So I begin with always begin with nothing and add exactly the things I want. And I'm going in that direction right now. So I'm installing Docker packages. I have already made sure to install the AUFS file system driver. And then it is installing pip and Python and a bunch of other things. And it is basically elaborately maintained. So this guy that you saw actually maintains this particular role in a fashion that it takes care of any changes that may have happened with Docker and its iterations. So it will get you the latest Docker installed on your box pretty much like that. So you will see that it is happening. And as soon as it finishes, it will report back success saying that, yeah, I did it. And so I think it's just finishing up. It did finish. Now let's see what we have. So we'll go and connect to the box pretty much just like this. We are now connected remotely and we should be able to run Docker right there. It runs. So we have a place to run Docker containers. Now we can extend the idea that we just did before this exercise. We did the other exercise here, right? We did this other exercise called, what was that exercise called? Ansible example, right? That exercise in which we hardened our box, made it secure and good stuff. So we'll do that exercise on the same box at the same time. We'll run two plays. One is the hardening play. The other is the Docker play. So we'll run both plays. Right now, our idea would be to get this IP address from here, from this box that we have, that we are dealing with, this IP address. We want to grab that IP address. So copy and go to this other folder we have here in which we have this IP address, which is an old one. So I'll paste it. Now I have the previous user hardening thing in play, right? So what we can do is apply this playbook to that particular target machine. And I will play the user play. And you will see that it enforces all the things we expect, which is use a user called CloudGenius and disable the root user and all that good stuff. It will happen. And it did not because of permission denied, public key. Why is that so? Okay. It is because the host reference has a reference to CloudGenius. It should be root. We are not ready with CloudGenius user yet. And so that failure was there because of the name reference CloudGenius. And it is not there. It doesn't exist quite yet. We need to create that user like that. So we're creating that user. And now it gets created. The user becomes ready. And the root user gets disabled. So we're running two plays on the same box. And it finished. So now going back to our other example. In here, we tried to connect to that machine directly using root access. It will fail. You know, it's expected. You try to connect to that machine using CloudGenius. It will work with this name. We expect that. However, you will see that Docker doesn't run. Because this user does not have privileges to run Docker. Only the root guy has. So let's go sudo root. And now you can see Docker running. And so how do you fix the situation? I want to run Docker with the user CloudGenius. So what I would like to do is run that other play again, which is this play in the role that we have defined, this collection in which we have the Docker YAML. And I would like to have the CloudGenius username become a part of Docker user, which means I need to change this root user to the CloudGenius user. In the host references, I will also change a reference to the user to become CloudGenius as opposed to root. And then save. So what you now see is the reference to CloudGenius came. The DigitalOcean variables also say CloudGenius. The host reference is CloudGenius. And now if you play this Docker play again, it will change one thing, which is to let the CloudGenius user use Docker. And that is what I want to do now, is to go back to run that play that we had run before, which is Ansible and Docker YAML. So run that play again. It will basically do all those things that you expect to begin with, but skip most of them because they're already taken care of. So it is skipping, not doing anything except adding the very last one, which is line number nine. And so that piece, line number nine, will happen by providing CloudGenius user the privileges to operate Docker. That will be the last step. And there it is. So it did. The last step was add users to the Docker group. Item was CloudGenius. So it added that item to the Docker group. So now we should be able to connect to the machine like this as the CloudGenius user and run Docker. And we succeeded. So what you're noticing is that we ran two different playbooks on the same target node a couple different times and modified some characteristics and tried to accomplish a goal that we have is to be able to run like our user and install Docker to make it a Docker host, to make it a place for us to run containers. And that is what we just did. We used Ansible as a tool to enable these things so that we can move on to bigger things or using containers in our example, in our life, to be specific. So we finished two exercises. And I would like to recap two exercises today. One of them was about creating users, hardening them, hardening the box, hardening the box, making it not prevent root access. Then we had another example exercise in which we converted that box that we had. By the way, I keep referring to this one box, but it's just a metaphor to a collection of boxes. All you need to be able to do is to manage them in a list of some sorts like a node list in Chef, host file in Ansible, or other various methods in collecting all these boxes that you might have in some cloud, some place, somewhere. You're basically collectively managing your target machines, preventing root access, allowing a specific user, making your desire come true to make this infrastructure operate collectively as a place to run containers, like the picture I showed you, the ship picture, ship with containers. That's what we're really trying to build in a foundation. So we'll begin with scratch, begin with nothing, add exactly the things we want, add our users, remove root user access, add file system capabilities, add Docker capabilities, build out a comprehensive infrastructure as we go along. And in the process, we are using Ansible to accomplish a target, a goal, a desire, a design, a specification, whatever you call. But essentially, we are accomplishing something using these tools. And the second thing we did was Docker on the box. Create a place for Docker. That's what we just did in two-step exercises. And we ran these things a couple of different times, and you saw the result as you did. Okay. There is more to Ansible, by the way. There is always more. And you can keep tweaking to what you want. For example, this machine that you know, this OVA file, is also created using Ansible, by the way. I will show you how. The challenge I have is that I cannot demonstrate it live because it takes a little bit long time, about, say, about one hour or so. It's kind of boring to watch it build, but I'll give you a link that you can make use of yourself and run it on your own. It's boring to watch that build process finish, but here is how you build the Cloud Genius Workstation. So I'm opening it up, pasting it in Slack chat, and opening that in the browser. So this is how to build the Cloud Genius Workstation using Ansible. Now, you need a Linux box to build this workstation, or you need a Macintosh box to build the workstation. You cannot be able to build it on Windows easily. I mean, this is not designed to run on Windows to begin with. So there are these steps, and they're very cryptically written. They're written for me. So only I use this, by the way. This is only for me. But I'm giving you that this is how I construct. I define my inventory of things that I want to target on. And so here are a couple of things that I target against in the inventory. Then I have these playbooks defined here. So lots of different playbooks that do specific things, like create a user, create dependency, this and that, and a bunch of things happen. And so at the end, there is a miscellaneous stuff. So all these playbooks run one after the other. And when they do, you will have a machine created. Then another script comes up and wraps that, packages it up in the form of an OVA file. And then send, as in push it out to you using the ResilioSync method. So you see that I have created a February OVA file, and I push it to you, and you receive it, and all that good stuff happens. This is exactly how I ran. It takes me about one and a half hours to finish the process. It's mostly automated. And I need to inspect it before it goes. So I do that inspection manually. But rest is automated. And that is how I use Ansible to build something for you. So it's a tool that is actually very nice. You can call out step-by-step things that need to happen, and it will do it for you as soon as you invoke it. So that is just a link of how I construct the CloudGenius workstation. There are more comprehensive examples. Like David saw yesterday, briefly, David noticed that this CloudGenius site died for like two minutes, three minutes. And so he immediately caught that and pinged me. And I got alerted immediately. And thank you. So David, thank you, David. And I said, you know what? Let's move. So I basically took the whole site and literally moved it in a matter of a few minutes to the other cloud. And at some point, you saw that it was working here. Now, after three hours of running it in this cloud, I did not actually like it. So I went back. So you'll notice that in the Slack chat, I mentioned there is a little hiccup in the site this afternoon with Vulture Cloud. And David noticed. So I live migrated the site to another cloud on bare metal machines. And please ping me if you see any issues. So that migration finished. And then in three hours, I did not truly like the scaleway setup in Amsterdam. By the way, the cloud is in Amsterdam. So I did not really enjoy. There are certain things that did not work the way I want in that cloud, because I think the image that they use is slightly different, nonstandard. So Ansible was failing in certain cases in backing up and restore successfully. And so I did other tests after the fact. The site went up running just fine, no problem there. But when I want to now migrate away from that cloud to another cloud, I want to be able to take a backup and restore, I tested that. That piece failed. And I said, I'm not wasting time on it. I just moved. So I just moved back to Vulture Cloud again. And now we are back to Vulture. And I'm OK. I'm OK spending money. I just wanted to cheap out here. And so that was cheap. I mean, yeah, I choose this. $12 per month, 12 euros per month, which is cheap compared to $40 per month. So I said, why not? And it's also like four times bigger box. So four CPU cores and eight gigs of memory. So it's multiple things extra. Unlimited bandwidth, all these things. Unlimited data, I shouldn't say. Not bandwidth. Bandwidth is limited. But metering is missing. So they don't meter you. And so that's a decent feature set that they are building. It's a new cloud. I wanted to mess with it. I did. Did not like it. Come back. So I'm back in where it was. And I'm happy. But this movement of live migration also is run through an elaborate, a fairly elaborate multiple, let's say, let me open it up in terminal. It's not in the virtual machine. It is designed to run directly on my Macintosh. So let me go there. And in that folder, you will see that it's an elaborate repository. It is not public. So it is not on GitHub. But this is where my inventory is. My backups are stored. My playbooks are stored. If you're interested in understanding great depth in terms of how I live migrate from the actual site, you will see, if I run this right now, you will see that I can take my cloud, my site from one cloud, download it, put it to another cloud, make it up and running, test it myself, feel comfortable with it. And then I'll say, OK, go ahead. Proceed. And none of you will notice any blip. And you will see the site migrate to another location. That is what this thing does. And I can show it, demonstrate it to you live if you're interested. If you want that demonstration to happen in a closer inspection, if you want to actually truly understand what this does, it is a fairly elaborate thing in itself. It might take like three to four hours to go through what I have done in here. This is like a two-year-long project. I've been building it. So it's a fairly elaborate thing, and it is not open sourced because it contains my private information, so I don't give it out. But if some of you may be interested, please tell me, and I will do a specific one-on-one session if you like. If you are interested in seeing this live demonstration, I can show it to you in 10 minutes or so any time you feel like live migrating a real site. You can always do that any time. That migration itself finishes in 10 minutes. But going through this content of Playbooks, which I have collected a lot of them, there are about 11 or so Playbooks, some roles, some scripts, some variables, some configuration, and a bunch of other Docker things, because all of these things actually run in Docker containers. I have like 13 or 14 containers that run that collectively create that site. So we have to understand those things. But I think later in the game, when we get through more Docker examples, I will illustrate these things to you that make sense in piece by piece so that you will understand how we build it in your context as opposed to reading this may not make sense directly. So I'm just giving you an option. If you're interested, let's do a one-on-one. Okay. So having understood that part, what I want to now do is go do some Docker exercises with you. So the last time we did Docker exercise, I think we were able to basically create a Docker file. And in that Docker file, we were able to put item by item, which is the Docker file. Hey, no problem, Swami. I understand. No problem. No issues. I'm recording this session already, so you can always watch if you miss something. Let's check time on it. Time right now is 10 o'clock. So, yeah. Okay. Close this window. And yes. Can we take a five-minute break? I think it's a good idea. Why not? So I will take that break right now here and say timer. Oh, I selected 10 minutes. But I think that's okay. So 10. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. Okay. you you you you you you I guess you're back or coming back as I should I see some of you not all of you but I'm assuming most of you are back yep okay let's continue yep so what we're discussing is this idea that we once we have a place to run Docker ready right a place to run Docker is basically the infrastructure that we constructed in the previous example and so once you have Docker running like for example it also runs on this machine directly if you like it is totally doable to run Docker right here it is there installed already so you see that it's there you can install and get Docker to run on any cloud anywhere you like that is also possible you can configure that using the previous exercise we just demonstrated but once you have a place to run Docker you need to then think about what do you want to run in Docker to run something inside a container you need to have an image and an image you can instantiate in did I spell it right probably not instantiate in a container so it's a runtime called container that is what is actually running when an image runs it becomes a container for a running image sorry for the running image is basically a container for a container that is running you can create an image if you add something here you can capture that in the image and then this becomes a new image not not the same as this one and then using this image you can create more containers and when containers run an image they're basically a runtime representation of the image but how do you get to some image you saw that in a previous exercise we did a while ago we created a file called Docker file and we had a reference to beginning point begin from this location at this run that and that is how you define a Docker file once you have a file defined you can then build an image using this file the output is an image you see this examples I think we ran it before already I'll run it quickly is I'll create a folder let's call it you know hello and go inside there and in that hello folder I will create a Docker file basically like this and create a new file called Docker file like this and save it in the hello folder by the name Docker file it's an empty file right now but right now I'm saying from Ubuntu and then I want to add something to this so like you know you probably remember add this file or other copy this file to the root location and then I create this file here and then save it as this file and that is this file which becomes that file inside the container so when I build it I'll say Docker oh Docker build build what build this location but whatever I have right here in here build it so it builds tries to build it doesn't find Ubuntu so it downloads Ubuntu to begin with otherwise you notice that here Docker images Docker images contains no images to begin with in our Docker host we do not have any images to begin with it's a fresh new machine February OVA new machine so no images there so when I say build this dot it attempts to look at the Docker file and attempts to build it and so it does not find the Ubuntu reference on which it needs to build it the foundation of that the foundation is actually line number one that's the foundation you build it on top of and then you keep adding other things copy this file to that file and this is the this file it becomes that file inside and so in here what you now have is that images are downloaded and used that step number one finished up to this point step number one started here finish here downloaded Ubuntu step number two is the line we have in our listing here which is in the Docker file is this line copy this file to that file so we see that happening right here copy this file to that file and that is this step number two finished so we now have an image ready and that image is this number 35 and 359 number so we will say Docker images and you will see that new image right there this was created a minute ago it was based on the Ubuntu image and that is this image so now we can run either the Ubuntu image or this image we have two images available we can run any one of them we like we'll do both one at a time first we run the plain old Ubuntu image and to run an image you have to run Docker so Docker run Ubuntu and then in that image I want to run it interactively so I put a dash IT option and then execute to give me the bash prompt so I said bash prompt and then I get the bash prompt on that Ubuntu box and I see that it has Ubuntu there so that's good but that's what I did so it's plain old boring Ubuntu machine ready for us inside a container I come out of that I want to see my changes that I made so I want to run my image so I'll say Docker images and I see that Docker images and I see my image right there that is the number I will copy that number here and say you know Docker please run that image that I have and give me a bash prompt in there and when I do that I see that I have a that file showing up and this that file contains the file that was this file which is what we said that we will do so it did it so that's a concept of creating a image this is interesting but not super useful directly so I want to get to something that actually becomes useful how do we do that so we will like to use some ready-made images for example there are lots of images available in the market one of them that I would like to use today is this example image called Tutum WordPress it's a ready-made image made by somebody for us so that's the image I want to use it is available in source form here and in image form here so I'll use the image this was published a year ago and source repository not available but the tag should be available I think I'll just quickly check the tag if it's available for us it's an old image but I will run it pretty much pull it first so bring the image down so Docker images right now does not can we are inside the container so I'll exit and then say Docker images and say that we have two images I want to get this Tutum WordPress image also so I'll say Docker pull and it pulls that image if it is ready and available so it is available so it's coming down so I will as a consequence I will have three images now the one that I created which doesn't have a name just an ID number this ID and then the Ubuntu image and a third one is coming down right now which is the Tutum WordPress image Tutum is I think means attitude in in Turkish so that's the name of the company called Tutum Tutum.co got acquired by Docker and they have a new service we'll talk about that service also in in just a few so this Tutum thing is now available in form of an image that we have used that is that image so how do I make use of that image it seems like it has WordPress in there I want to make use of it how do I see it so I'll go read the documentation behind it and so here it is so it basically says that you want to run that image pretty much like this so what does that mean it basically want to run that image so I will say something like this what does that mean I want to run this image that I have downloaded here and I want to run it like a daemon not interactive not dash IT option but like a daemon in other examples you probably have seen the dash IT option and a bash prompt reference which gives you interactivity to that box that that container in our example that I'm going to execute right now the idea would be to run that image in a daemon form so it runs in the background all the time as opposed to letting you interact with it on a command prompt it's a different mode of running same thing in a previous example you saw me run something like here I'm running this image and asking to give me a bash prompt being the options were dash IT interactive teletypewriter mode and I want to now do it differently I don't want to run it interactive I want to keep it running like a daemon background mode and that is what I intend to run so I'll run it like this so slight differences dash T versus dash I IT versus dash Delta daemon and then the image reference you will notice that there is no bash at the end you don't need it because you don't want to interact with it you want to let it run and you when it runs you want to see what it is doing so you're mapping those ports port mapping happening port mapping is basically mapping a port between the actual machine and the container port yes Raj go ahead can you show the content of this WordPress image where is it located and what's the content this image yes image is constructed in open source it is available in Docker Hub no I was talking about locally on the locally okay you want to see where the image is stored so there are a couple ways to do that so Docker images is where you find a listing of the images the actual location of this is here so images are here containers are here a UFS file system is here networks are here plugins are here swarm is here trusts and many certificates are here volumes are here so they'll be here in one of those items so go images and you see that there is image in a UFS in there there are these images it's a complex location where Docker manages it so it's where it's keeping those metadata I will have a reference to that and it's managed by code so that's why it's so complex nobody actually goes like this inside not ordinary users so you can see that there's a hash reference there three five and that is the image reference to the parent that you can read the metadata about it so we'll see what it does it contains references to these images now that was the metadata part let's go see the volume part the content part will have more content there is a SHA reference let's see what we have in there and the other three images are stored right there the image tags you can match them here so this three five nine zero matches this this f-49 echo echo Charlie is this this seven echo seven f-97 is this so these are the image hashes that are stored locally in a large file of this size and that is this particular image which is the Tutum WordPress it is the biggest image we have which is this it is about 477 MB and represented by this number here this other two images are similar but small 129 MB the this image is Ubuntu image which is matching your f-49 echo echo Charlie and this image three five nine is your constructed image which matches this hash and that's the hash that you're looking at these are raw files stored where actual images are stored in deep locations like where lib docker images AUFS image DB content SHA-256 that's where it stores the images but nobody goes here to look I mean except me and you so we'll come out and stick to not going there but instead look at images like this this is how you deal with images it's much easier you can delete images if you don't like get new images Docker pull like that so our idea is to run that image in demon mode and expose the port number 80 on the machine here with the port 80 inside the container that you will run when you run like a demon so when I run it it shows you running and it comes out because it is running in the background like a demon you see that this container ID not the image ID it's a container ID by the way 0 8 delta 7 is a container ID this is the image ID this is the container ID its full expanded form is this 0 8 delta 7 this 0 8 delta 7 right there that's the expanded form SHA-256 this is a short form container ID and that's what you're looking at it is running right now and it is showing you that the physical machine port 80 is directed to the container port 80 what does that mean it means we have WordPress here on this machine directly running right now and we should be able to see it local host book number 80 show me WordPress and here it is it's there it is running because that is what we did in this step Docker run like a demon match the ports to tomb WordPress and I can kill this process that is running with this container I can say that you know what you container die die it kills and then I can open up here and see what we have go to local host and unable to connect expected totally expected let's go see a couple of other things like in our example we know that this matches to port 80 on the real machine to port 80 inside so I would like to now run it slightly differently and say you know what instead of port 80 I will run on port 81 I did it so I can see that it I can see that it shows me that port number 81 on the physical machine is matching mapping to port 80 on the container which means my local host will still not work however my local host colon 81 will work 81 on the machine matches port number 80 inside the container compare that with port number 80 matching 80 inside the container in a previous run we had P 80 colon 80 whereas in this time we have P 81 colon 80 subtle difference different port the idea that I described to you just now is one of the ways that you can run multiple services in one box and expose them on different ports and so so the scenario of usage will be that you have one box and the box can have only one thing running on a given port whatever ports you decide you can have only one thing running on that port you cannot run two different things in the same port will be a conflict so you want to run now two things I will run I would run a and B I can totally do that I'll run a map it to this port B map it to this port and I will have two things running how do I accomplish that very very simply like this I'll go first of all kill my Docker containers and now I have nothing no running containers there are two dead ones I'll kill all of them so let me kill both them both Docker RM minus F 7 C 0 E and kill them so we have now nothing so empty no containers running night now I want to run two word presses one on port 80 one on port 81 can I do that yes how this is how you do it this is the port number 81 mapping to port 80 inside the container and I will give it a name just like this so dash dash name this is 81 let's see if the syntax is correct yeah it is correct so now I have the name called 81 assigned to the one that matches 81 port so I can see that visually oh doctor PS dash a I can see this container called 81 is created that uses this image and is actually mapping machine port 81 to the container port 80 now I will run another example this time I will run or 80 mapping to port 80 machine port 80 container port 80 different container different name run it runs now we will have two word presses running one is called 80 the other is called 81 this is just names by the way just for you to understand what is what the thing that to remember is that this machine port 80 is mapping port 80 on this container this machine port 81 is mapping port 80 on this other container so there is no conflict what does that mean it means we have two sets of WordPress going right now one on port 81 you can confirm that by the way so I will I will basically close the browser and open up new one and go open two windows side-by-side one is this another one is this I'll put them side-by-side or rather attempt to move at least somewhat side-by-side and then okay and one window I will say localhost colon eight zero and in other window I will say localhost colon eight one and I have two word presses I will prove it to you it they're actually different so I'll go login and I'll call this 80 E I G H T Y username is a password is one and I confirm weak password oh come on I need to tweak the graphics properties of this VM a little bit install WordPress and that is this machine with a login a password one and I log in and off we go we have a WordPress running on this machine which is called 80 and that's the site is called 80 here now I will run this second WordPress on a different port this is called 81 username is something different password is something different and confirm and install Nilesh question yes so I ran three word presses 81 on 81 and 90 90 yeah your choice port number is totally your choice your call 90 did not work aha okay can you tell me why can you tell me why did not work is it a reserved port for something no no maybe it is so you go go show me the error then I'll understand what the error is paste the error in slack chat and we'll be able to figure it out let's see the paste the error what do you see the error as it's a server not found when I load it on Firefox okay now show me that command line error like what do you see when you run the container or rather type this here type like this Docker ps-a and show me what shows because that's you can tell whether the ports are conflicting or not you can tell right there you see that do you see three entries or just one or two I see three okay what do you see in the port's description that's what I want to see so paste it I paste it on the okay refresh your browser you should do it nope didn't like it okay try different port or we'll see it later as to what's going on okay thanks so let's go the the takeaway from this is that you are able to run multiple services these are basically what I what I am describing a concept called micro services what you want to be able to do is run variety of small little things that constitute together to construct a big thing that you may want and each of these elements will run in a container that will do one thing like in our example do the port number 80 run of WordPress or here port number 81 of WordPress and you can avoid conflicts by mapping it to a different ports on the same box this is one way to think about there are other ways that we should be able to handle on a larger scale when you are dealing with just one box right now what if what if we you know want to use a infrastructure which runs multiple boxes and spreads out these containers across multiple boxes and have that configure in form of a cluster of these boxes so not just one box but multiple boxes operating together in form of a cluster multi box cluster multi machine cluster that all collectively operate as one unit are able to have these containers migrate from one location to another something like this so for example I'll just give you a quick illustration on a different projection I'm changing that right now so here we have the projection changing over to a different machine projecting here and show and share my screen and you're looking at this window which has this window maybe yeah so here is a visualizer and you can see that I am running two different boxes one box is called leader the other box is called worker one and I can create more such boxes put them side by side by the way this is a live site running so it's a test site I have which has two boxes running and I'm basically giving you this uber picture as to what we are really trying to accomplish using Docker in a multi machine scenario constructing a cluster of Docker containers cluster of machines that will host this I want to really host this and run bunch of containers running bunch of different things for our cloud for our application deployment and have this underlying ship be not just one box but multiple boxes and that is the beginning step that I'm trying to illustrate with just two boxes right now there both of them are showing up in a visual representation you have a box called leader another box called worker and what I want to be able to do is show you that it has a two site sorry a two container solution and a traffic controller running there you will see in the screen here this thing is called traffic it's a bad spelling but that's the name so the name is traffic and it manages traffic it manages port access and controls and DNS names and things of that nature so think about that later for right now stay focused on these two containers at the bottom they are this LFW DB and LFW WP so basically these two containers at the bottom that you look are two separate things running two different ideas one which is this one LFW DB is running a Maria DB database and the other container LFW WP is running WordPress and what these two containers are on two different boxes by the way as you see them and they are configured in a fashion to connect among these two boxes and this what you're looking at is an example of what is known as a swarm swarm is a new feature in Docker started two months ago let me let me my projecting on the right screen no I'm not so let me change my projection screen so changing my projection screen back to the right one showing you this screen my whiteboard where I'm sharing my screen and what I'm talking about is this thing called swarm is a new feature in Docker started a couple months ago this Docker swarm mode was released in 1.12 1.12 was a couple months ago so right now we are running Docker version 113 so this is 112 so just a little while ago this version of Docker is 113 one and this swarm was released in 112 so it's a it's a mode of operation what this swarm mode does is allows you to run Docker infrastructure across multiple machines and treat all of those machines together as one that's the core idea so this swarm mode competes with another such tool that will allow you to do a multi-machine orchestration that thing is called Kubernetes another competing kind of sort of competing product that also uses Docker by the way but it constructs a cluster to run Docker containers pretty much like the picture I showed you there are more such tools by the way there is a thing called mesos or mesosphere also known as DC OS and like that there are a bunch of other open source tools that allow you to orchestrate your micro services in bunch of machines operating collectively together that's the core idea behind it and we'll get to these points but we had to get to build these things step by step so I cannot just jump into a swarm mode and start showing you without having you understand the nuts and bolts so we are going to the next logical step in our building step process towards thinking about what we are really trying to accomplish is to be able to construct a large number of machines collectively operate Docker on them and treat that entire unit like a common pool of shared resources pretty much goes back to the original definition of cloud computing right so we will have our own bunch of machines our own bunch of machines will run a Docker cluster using either swarm or Kubernetes or God knows what other new technologies come up in the play in the future but our goal is to run whatever services we want to be able to run and have them run you know have them run in a fashion that are resilient so something like this for example I will now show you what I just said a word resilient and scalability so those two words I will describe now in another quick display sharing here and then going to my cheat sheet and in that cheat sheet what I'm basically doing is cleaning up and so what you look at in this there are these two containers LFW database and LFW WP you saw that and what I want to be able to do is this time remove them so I will go to the terminal and absolutely get rid of them so you see that those two containers disappear and it's gone they're gone by the way so I want to bring them back again to life I can totally do that I can bring them back to life pretty much like this so when I run it here and invoke they will come back to life right now in this screen you will see them visually popping up WordPress popped up DB popped up and it is started and running and as a consequence of this you saw two new containers pop up magically show up in that display the dynamic visualizer that actually looks at the cluster the swarm cluster and shows you visually what these containers are doing you'll notice that this WP thing is only one container right now and this DB is only one container if I want to grow it a little bit I can very easily do that what I can do is first of all remove my stack so our Docker stack RM LFW so it goes away and you can see that it disappeared and what I want to be able to do is maybe put them side by side and so trying that right now put it side by side and now I want to change my stack layer design a little bit and make two word presses as opposed to just one so I'll change a little edit in the stack for this LFW thing and say that I want to have two units of WordPress and go back here and invoke my stack one more time like this and you will see that now you will have two word presses one DB there we go so you see right now I have an LFWWP another container LFWWP two containers serving one database container here and both of them together balancing the lower if I have more containers like worker two worker three worker four like that I can spread them out across multiple machines if I have them right now in my swarm cluster I just have only one worker and one leader the idea is to just illustrate a point right now these things by the way are actually live and running WordPress site as let me just shrink it back again so I'll remove my stack and then go back to my edit here and reduce my number of replicas that I have to one and then come back here to my display you see that my stack has gone I will deploy my stack one more time and you will this time see there is one database container and one WordPress container popping up as a consequence I have shrunk back and by the way these are real live functional sites that you will see in a matter of change of a browser and this is that site that I'm looking at right now it is a functional fully functional site that shows up as this website running WordPress it has live data in there and I was able to scale it quickly show it to you the container expansion from LFWWP making it one to two and back to one the database container was only one I kept it at one I'm able to change my design in form of what I just illustrated to you are these stack files there is a YAML file here that I look at and then I'm running these two services so one of them is this service block which is the database related service and the other one is a WordPress service block which is related to the WordPress scaling out and that's the idea the two blocks of code are written here and I would like to describe to you what these things do and have you do construct something similar and run it so the building block of this thing what we just saw this thing is known as by the way a stack and so you can run that command called Docker stack it will not run on your virtual machine because it's not a swarm this is a swarm command Docker stack and sorry Docker sorry it's Docker stack LS it shows you a list of all the stacks running and right now the answer that you receive is only one stack running and that's what you have you can run more stacks on it if you like it's just a cluster it will run any number of stacks that it can accommodate and these commands will operate only on a swarm cluster not on your virtual machine by the way just so you know these are not VM commands I'm actually dealing with a cluster for real and it is running what you see in the in the right half of the screen and the actual site looks like this this is the actual functional site that you saw in the real example that we are building right now and so the thing the reason I showed this to you is this is the end result you will see but we want to get to this point to understand what goes in constructing those things and that is the reason why I showed you this so now we'll come back to the virtual machine and construct elements that are needed to make these things happen so how do we get to that point that's the result we want to accomplish so the next building block of what constitutes what I just showed you is a stack stack is a collection of services right so we have a thing that I just showed you called stack and stack contains services services contains your running containers or service you know running containers and containers are basically derived out of images so derived out of images images and images are built using Dockerfile you know you have done this part you're done created a Dockerfile created an image and created a container you know how to do this by now we are we are expanding our our function towards higher level of constructing an application stack constructing a collection of services and running them in a cluster of machines as opposed to just one box we will get to that point but right now we are beginning with just one box so the next logical thing that I want to talk about is a collection of containers together so the idea would be to define what is known as Docker compose so there is this construct known as Docker compose dot YAML this construct is a simple expression that you have to write some things in that file and then say Docker compose up so basically literally you say something like this Docker compose up so as long as you have a file there called Docker compose which we don't have so I'll have to create it by the way so I will create a file here called Docker compose save it as Docker compose dot YAML so it's an empty file we'll begin with nothing and build stuff as we go along so this file is Docker compose file it's empty right now it's a YAML file and we will like to add components to it so we have the file now sorry in the wrong location so terminal again and come on Docker PS what do we have running those two guys I'm to kill them Docker RM minus F and those are gone we had Docker PS showing nothing Docker images showing those three images we have and that's good so what I want to do next is to look at what is the folder we are working on is called hello and in that folder we have this file called Docker compose dot YAML which is by the way empty zero right it's exactly how we begin right now with nothing and in that compose file I want to compose something and describe my goal so here is a good way to read Docker compose and in there you will see some examples so here is an example of a Docker compose file and the idea here is this is not a good example let's go see more examples so I'll bring my own examples by the way and this is not a good example that they have given it's not functional it will not build so I want to get a functional example no this is not gonna build so let me go switch and find my own examples so here we go Docker compose example we should be able to find a quick example of something like for example here yeah this should work so here is an example of a Docker compose file that I want to just use so I'll bring it to our workstation in our workstation we have this file called Docker compose so I want to put some things in there and I just copy paste it from Google what do we have here let's go read we have a couple of things here described one of them is a place to store data that item is defined in line number 26 27 it's a place to store my data and that is this that's how you define you remember indentation is extremely important here extreme I cannot understate that indentation has to be systematic and absolutely correct if you miss an indentation it will not work so lines number 25 26 27 are referencing the construct of what I would call a Docker volume now in our example in this machine do we have any Docker volumes yes we have a bunch of them so since we have running we've been running this bunch of exercises the Docker volumes have accumulated I want to clean them up all so I'll say Docker system prune and just clean them everything so they are gone let's see the Docker volume listing shows empty yeah it's empty now so we cleaned up and I will like to now continue discussing what this compose file will do for us what this file does is defines two service blocks two of them one block begins here line number four all the way to this point and the other one is another block line number 15 all the way to 24 and so let's go look at these two service blocks separately so the the item called line number three is a reference to a services block which begins from line number two and ends in lines 24 so that's the block for services right 2 through 24 is all the services defined inside that services block we have two blocks one defines the database service which begins at this point and goes all the way through this point the second service we have is this item that begins in line number 15 and goes all the way through this point so two blocks of services right so called out like this and at the bottom the third reference here is volumes definition so we have made sure that in our Docker setup we have Docker volumes come on Docker volumes I show nothing what about Docker services do we have any services no okay service LS so we have this is not a swarm manager so no services there which is understood having said that what I want to be able to do is run these two services like that so let's understand these two services one at a time first one is this block our focus on it's a service defining a database service it's a going to be a container that will basically use a ready-made image in line number five number five says use the MySQL server image the version number is five point seven that's the tag five point seven and next is line number six and seven that say that you know what Docker container for MySQL server I would like to use your data volume that I have defined in line 27 use that place to store your stuff not store it inside the container but store it outside the container like don't go mess with because you know containers will come and die and go and die and come again to life and die and they will store their data in that location that's where MySQL stores the stuff but I am saying you know what don't store it in your container store it outside here so then I can access it like here I should be able to access that data myself outside the container so don't store it in the container here but instead store it here so this is the actual physical thing in the machine this is the reference to the container you map them just like port mapping you do a volume mapping like dash P 80 colon 80 or dash 8000 colon 80 that's a port mapping here in case of WordPress here you're doing a volume mapping physical volume on the machine maps to that folder inside the container that's volume mapping if the database dies for some reason I would like you to restart it please automatically so the restart always basically refers to that line here and then we are defining some environment variables such as password this that whatever we have chosen that's the set of password we chose for the root password database password user password okay that's the database service and it will use this image and construct a database container with its data stored outside in this location that you can access it like this outside the container so not inside next container we have is a container running WordPress that uses the WordPress image and it exposes port number 8000 on the machine mapping to port 80 you can change it to what you want so I want to use 80 so I'll leave it like that and when the WordPress container dies for some reason I would like to restart it and I'm using the environment variables for the database to be able to connect using the same methods and I'm depending on the database so this database dependency is called out in line 16 and 17 17 refers to this unit at the top number four 17 refers to number four so now I have a link established between these two services that are WordPress service and the DB service and I'm storing my volume data here and mapping my ports to the WordPress container physical port on the machine 80 mapping to the WordPress port and this is my compose file I save it now we have a two container stack ready for us to execute how do we execute that very simple actually it is just this doc compose up and run it like a demon dash D go so do it it'll do it and it will pull down those two container images that are missing we don't have the MySQL image so it pulls it down we don't have WordPress image so it pulls it down we have to do more press which is a different image this is the library image called WordPress that's a different one it will be pulling it down as well this is the WordPress colon latest as opposed to two to WordPress different WordPress different image but both these images are coming down and you will now see that we have WordPress again except this time we have it not by the name 80 but actually a blank WordPress starting up as soon as this refreshes we should have come on there we go so we have a new WordPress coming up and we continue forward and set it up we can call it compose and a username and a password and we are going to install WordPress and that's it pretty much so we have a new WordPress right now what you're looking at give me second I'll get this dog out he's really making noise somebody just showed up the man outside and so the dog was crazy he wants to meet everybody so if you happen to come here he will meet you love to meet he loves to meet people and so back here what we did was using this construct to construct two containers one called WordPress one called DB and we linked them up like this and we were able to visit this container port number 18 we saw a new WordPress site how do we see these things inside the container we go here and check we say Docker ps-a what do we have we have two things running let's go see them in greater detail so we'll go and examine we have do it again we have a container ID that uses the WordPress image it maps port number 80 on the machine to the port number 80 inside the container and another one port sorry this this container ID called 53 echo 30 echo 3 this running my sequel image in a different container and it exposes no ports on the physical machine at all it exposes a port on the container level so that this box or sorry sorry this container can connect to this container at that port that connectivity is possible because this port is open on the container level not on the machine level so you don't see a reference like this zero zero zero zero colon three three zero six you don't see that because you don't want to expose that port to the machine level you keep it only at the container database container level and that is where it is open this container connects to that container through the construct where we have we have defined which is in the Docker compose file and you depend on this and so this depends on basically makes that link happen between this container and that container and that's how this WordPress container is able to operate on this database using this password that you have defined here and it stores the data here which means which means if you now delete these two can these two containers completely for example let's say Docker RM minus F I delete both containers right they're gone so now both of them are dead which means our site is not working anymore but no worries we are storing our data outside so our Docker volumes are intact the volume called hello DB data is there so I can basically bring the Docker stack up and it comes back to life and now I can see my two processes they are there and I can go back to my WordPress and refresh and you will not see a fresh fresh deployment but you will see a ready deployment that I can just log in and see that it is not a fresh one it contains the data from the previous execution the compose execution we had so it preserves your data because you're storing your data outside like this and you're telling it to use the data not store it in the container but store it outside in a volume like that so this is a quick example to illustrate building something a little bit more complex than just one container two containers and we'll build more we'll build more as we go along we will meet again next time which is on 21st at 4 o'clock yes 4 o'clock pacific time 21st and that's when I will see you guys next these exercises that I just did are not on the website but you have a video recording you have github link so you can actually play with it yourself use the recording until I write these things up and put it on the website eventually which I would do eventually I don't know when but until that time use the recording as a reference and with that I'm stopping to record