Python for Entrepreneurs Transcripts
Chapter: Deploying to the cloud
Lecture: The deployment playbook

Login or purchase this course to watch this video and the rest of the course contents.
0:01 We just wrote a whole bunch of code in the last video to create our initial configuration for Digital Ocean droplet.
0:08 You may want to take a little break, but as soon as you ready, we're going to dive right back into creating our second playbook,
0:14 we are just going to form the foundation for us to deploy our application to our server, not only once, but every single time we make changes.
0:22 Let's switch back over to the command line. We've already got some of our files set up, from writing the initial configuration.
0:27 Modify the hosts file, and we're going to create a new configuration. I'll just call this one common, and again,
0:35 specify the IP address to your Digital Ocean droplet. We're also going to specify the Ansible Python interpreter as Python 3, save that.
0:44 Next up, create a file named deploy.yml, write out a quick comment here,
0:50 now just like we had our init_config.yml, we are just going to write a few lines here, we'll apply this to a common host and this time
0:57 and this is the really important part, that the user is going to be deployer.
1:01 Now, this user should be whatever name that you've named in your group vars file for your non-root user, and the roles we're going to apply
1:07 just common, so common will be the name that we use under roles for this playbook. Save that file and quit out, now head under roles,
1:18 and instead of init_config, we're going to create a new folder named common, move under common, and we're going create
1:27 three directories here: templates, handlers and tasks. Now templates are going to be files like our configuration files for supervisor;
1:36 handlers are used for services, for example if we need to restart nginx after many different tasks that we do, we can just call
1:44 a handler to do a common operation over and over again. And then task, we've already been introduced to, that will form the backbone
1:49 of all the instructions we want for applying our configuration to the server. Head into tasks, and this is where we'll start things off
1:56 create a file, name main.yml, start out with little comment and now we're going to take advantage of the include statement,
2:02 so rather than just writing every single task in here, like we did in the previous playbook, for initial configuration
2:07 we're going to essentially import other yaml files that Ansible will use as instructions for setting up our server. First one we'll call Ubuntu,
2:17 now throughout the remainder of the videos in this chapter, we're going t be creating several other yaml files,
2:22 in this video we're just going to flesh out a Ubuntu, but let's go ahead and add the other includes just as comments,
2:28 so that we can see how this entire deployment will come together. The next one we'll call letsencrypt, and this is going to be
2:34 setting up our SSL certificates for our web server after that, we'll set up the web server itself, which will be nginx,
2:41 we'll be configuring that with https; the next one will be our source code, which will happen and git and these should all be yaml, not HTML.
2:49 Next up, we'll handle application dependencies, then we'll handle running as a wsgi application and finally, we'll just create a notification process,
2:58 because as you build out your deployments, sometimes these deployments can take up to 5, 10, 15 minutes to complete
3:05 so it's nice when you can walk away from your computer and get a text message when it's finished or something like that,
3:11 or get an email or post to a Slack channel. Notifications are really simple modules, but they let you take your attention away
3:18 from what's happening with the playbook and go work on other things. Alright, save this file, and now we'll create ubuntu.yml.
3:24 In this playbook, we're really just going to do a couple things, we're going to install some basic Python packages,
3:30 system packages through Ubuntu, and we're going to set up the firewall, we really only want to have two ports open in our case
3:37 the first one is just going to be port 22 for ssh, and the second one is going to be 443 for https connections.
3:43 And then, port 80 it for http connections, even though we're not going to respond over http, we will redirect to the https version of our application.
3:50 Alright, the first task we're going to write, ensure Python packages are installed, again use that apt module,
3:57 and we're going to use a slightly different syntax here, we're going to use a variable, but we're not going to declare this variable
4:03 in or group vars file, we will say update_cache before we install each of these items and here we're going to specify become is true
4:11 what this does is use a sudo in order to escalate privileges so we can install the system packages, without using sudo
4:18 deployer is not going to have the appropriate permissions in order to install these packages and our deployment would fail;
4:24 when we write become true, we can become any user, we can use this to become a postgress user for using a postgress database
4:32 but if we don't specify who else to become, it'll just use the sudo mode. Alright, now we're going to use with_items
4:39 and this is how we can avoid creating multiple tasks when we need to install multiple packages,
4:45 in our case, we only need to install a couple of packages the first one will be Python-virtualenv, the second one will be Python3-dev.
4:53 What happens here is that with_items think about it like it's plugged into the variable item for the apt module, pretty much just a for loop
5:02 and this is the list of items that we're going to use and it's going to run this task with each of these items.
5:08 Put that out of the way, let's enable our firewall, we can use the ufw module we'll say allow port 22, and again we need to use become true
5:18 and now we can copy this a few times, this time http port 80 copy it again, https 443, and one more bit we need to write
5:28 is to actually enable the firewall, ufw module and we're going to specify state enabled and become true.
5:38 There is something slightly different about the way that I wrote these tasks compared to the ones we've seen so far.
5:44 What you'll see here is in this module this ufw, the only thing we needed to specify here
5:48 is that our state should be enabled, here we only had a couple things we need to specify, so instead of writing them on their own lines,
5:55 what we could do is we could say rule out and port 443, this would work just fine, but if you're writing a bunch of tasks at once,
6:03 it's often easier just specify it all on a single line and this is the format we would use, we would use a key and equal sign and then the value,
6:11 rather than a key and then s colon and then the value. So it's just another way that you can specify with Ansible in a more compact fashion
6:20 and we'll use them interchangeably throughout, we don't need to edit the group vars all file, we probably should create a shell strip
6:27 just to make it easier for us to kick off this file, just like we did with
6:31 So copy, or create a new file, and I just typically call it prod_deploy so a production deployment, we'll modify prod_deploy,
6:41 and instead of initial_config, this will be deploy.yml, we will use the same private key, but the root will be deployer, as opposed to root.
6:50 Save that, let's give it a try, see if it works. So we kick this off, looking good so far,
7:04 ok so we did run into an error here, so what seems to be the issue? Well, the connection timed out, couldn't connect, that's kind of odd.
7:11 But if we go into hosts, one of the things is that I mistyped an IP address and this happens frequently, take care if you are modifying files by hand
7:22 especially when you're typing out certain digits, this was 234 and it should be 243 little things like this can trip you up, so if it doesn't seem
7:31 like you're able to connect at all with Ansible, double check the IP address or the host name,
7:37 make sure that your private key exists and that you are pointing to the correct one
7:41 and make sure that you're specifying the appropriate user name like deployer if you have already locked down root.
7:46 Those are things that have often tripped me up as I am using Ansible. Let's try this again.
7:51 Alright, now this time it looks like it was able to connect successfully.
7:54 Alright, looking good, now let's just make sure that we can connect to our server
7:57 because we did change the firewall rules, so again we'll just manually connect to make sure everything looks good-
8:10 and it looks like we're still able to connect even though we've got the firewall rules in place, awesome.
8:16 So now we have the start of our new deployment playbook, and we can add new tasks, new files to it, build it up over the next few videos,
8:23 until we've got our completed deployment and our application is up and running.

Talk Python's Mastodon Michael Kennedy's Mastodon