Python for Entrepreneurs Transcripts
Chapter: Deploying to the cloud
Lecture: Let's encrypt
0:01 When our application is deployed and running
0:03 we're going to want to make sure it's secure using an https connection;
0:06 that way our users can pass us information and we know it's going to be encrypted
0:10 from the time they entered into the browser, until it reaches our server.
0:13 This is not only important, but mandatory
0:15 when you're using services such as Stripe,
0:18 you don't want your users' credit card information to be leaked
0:21 because of the insecure http protocol.
0:24 Now it used to be much more difficult to deploy secure applications
0:27 because ssl certificate is more expensive.
0:31 If you'd go to a company like Digicert, and oftentimes
0:35 pay a few hundred dollars a year to get an ssl certificate
0:38 that was certified by a brand name,
0:40 that's all changed with a service called Let's Encrypt.
0:44 As it says right on its home page, at letsencrypt.org,
0:47 Let's Encrypt is a free automated and open certificate authority
0:50 a certificate authority grants the ssl certificates
0:55 that are used to create https connections
0:57 if you self sign a certificate, and you don't use a certificate authority,
1:01 than a user in a web browser like Chrome is going to get a warning
1:04 that the certificate was not issued by a certificate authority.
1:07 The certificate authority provides an additional stamp of approval
1:11 that is accepted by all major browsers, as secure and generated via their process.
1:18 One of the great parts about Let's Encrypt other than the fact that it's free
1:21 is the ability to automate obtaining certificates.
1:25 We're going to add this now to our Ansible playbook,
1:28 switch back over to the command line where you've got your deployment scripts.
1:32 We're going to need a few new variables added to our group vars file.
1:35 Go into group vars and edit the all file, the first thing we're going to need
1:40 is to specify or fully qualified domain name,
1:45 now in my case, this is going to be www.pythondeploymentexample.com
1:50 but you're going to put in your domain name that you registered
1:53 and just set up in the last video, into the fully qualified domain name.
1:57 Second, we're going to need to specify the directory
2:00 in which our web server is going to serve up static files
2:06 we're going to use the default one
2:09 that nginx is going to serve files from on Ubuntu "var/www/html"
2:14 and then one more bit we're going to use our email address
2:17 that will be added to the certificate, so when we request the certificate
2:21 we're going to pass Let's Encrypt our email
2:24 first off so that they have a contact, but second of all,
2:28 that is going to be added to a part of the certificate
2:31 and we're going to call this ssl_cert_email
2:35 in my case that'll be email@example.com.
2:38 Those are the three new variables we need for this chapter.
2:41 Save the file, and then we're going to go back up
2:45 into our roles directory common, go under tasks
2:49 and now we're going to write a new file,
2:53 this one is going to be letsencrypt.yml
2:58 As always, we'll just add a simple comment up top,
3:02 now we've got a few new tasks here.
3:05 The first one is going to be familiar to us, and that's going to be the apt module
3:09 so use apt and the name here is going to be item,
3:14 because we're going to install more than one
3:17 yes we want to update to the latest cache,
3:20 we're going to become Super User when we do this
3:23 and we're going to install two packages,
3:26 the first one will be letsencrypt, and the second one will be nginx.
3:30 The letsencrypt package has some command line utilities
3:33 to make it really easy for us to in an automated way go and grab that certificate
3:39 and nginx is going to be the web server, which will serve up all of our static files
3:43 and serve as what is known as a reverse proxy,
3:46 it's going to be a pass through where any requests
3:49 that are supposed to go to your application nginx is going to pass them on
3:53 so pyramid can respond to those requests.
3:56 Alright, the next module we're going to have is a new one
4:01 and that's going to be the stat module,
4:03 think about the stat module as a check on something,
4:06 as storing the state that we can use in conditional statements
4:10 throughout our Ansible playbook, and execute tasks or not execute tasks
4:14 based on the results that come back from the state.
4:17 So we only want to grab the certificate, the first time that we need it
4:23 we don't want to get a new certificate every single time that we do our deployment
4:27 we're only going to do it if the certificate does not exist.
4:30 The way we're going to check for that is
4:33 we're going to check the letsencrypt directory when it's created
4:36 and it's going to put it under our fully qualified domain name
4:39 and if that path exists, and we'll check for it later in the next few tasks
4:43 then we're not going to go ahead and get a new certificate,
4:47 we're going to skip those steps.
4:49 Again, we're going to use become true,
4:51 so this check as soon as we have finished installing,
4:54 the first task with the letsencrypt and nginx packages,
4:58 we're then going to check if we already have the certificates
5:01 based on the directory that was already set up for this application.
5:05 Alright, next up, were going to stop nginx because
5:08 we can't use letsencrypt unless nginx has stopped.
5:15 And we'll give this the name of nginix for the service
5:20 and the state should be stopped.
5:23 We are going to need sudo privileges for this one,
5:27 and we're only going to stop nginx if the directory is not defined
5:34 and it is not a directory, so the when condition here says
5:41 if the certificate directory that letsencrypt creates when it runs
5:45 is not a directory, it's just not defined, and it's not a directory,
5:48 then we'll go ahead and run this step;
5:51 otherwise, skip it, we've already got our certificate.
5:54 Next up, we're going to create the certificate with the Let's Encrypt command
5:58 if we're going to use the shell module,
6:05 the shell module allows us to execute commands on the command line
6:08 now we're going to pass a bunch of parameters in here
6:11 we're going to pass in our fully qualified domain name
6:15 we're going to pass in the directory in which we want to serve files from
6:21 we're going to pass in our e mail address
6:25 so these are all the variables that we just define in our group vars all file,
6:29 agree to the terms of service for Let's Encrypt
6:33 and we'll renew the certificate by default when it expires.
6:37 We will need to have sudo privileges here,
6:41 and we only want to do this again same thing as above
6:48 we can actually just copy this and paste it if we don't already have the certificate.
6:53 Okay, so we use the shell command, so we drop down into bash
6:58 and we just executed this command straightup on the shell
7:01 and the one thing to note is that there is actually
7:04 a Let's Encrypt module as part of Ansible,
7:07 but it's in a very early state, and it's in a preview mode
7:11 so it's likely that that module is going to change significantly over time
7:15 I just thought it was much easier to use the shell command
7:18 and execute a single command rather than trying to use the Let's Encrypt module.
7:22 This is a trade-off you're sometimes going to make in your Ansible playbooks,
7:25 sometimes it's just easier to do things with a shell command
7:27 now that's not going to necessarily be as maintainable
7:29 as if you have a really clean module that's already been written
7:32 but occasionally this stuff can come up when there's a new module
7:35 that's been added and it can change over time.
7:37 We just need to do two more things here,
7:39 the first is, so now when we get our certificate
7:41 we're going to generate a strong parameter for our ssl file
7:46 that is going to be used during the key exchange
7:49 when a web browser contacts our web server,
7:52 this is something we're only going to want to perform once
7:54 and it will actually take several minutes, even on the latest hardware
7:56 in order to generate a file that will be used in the key exchange.
7:59 But this makes our handshake in https protocol more secure.
8:04 Again I am going to drop down into the shell, use the open ssl command
8:08 and again we're only going to perform this when it's not already been done.
8:15 One last command we need to boot nginx back up,
8:18 we can use the service module, save the file,
8:25 now one more step, we need to go into main yml,
8:31 do the comment that is prepended to the line to include letsencrypt.yml,
8:38 now we'll try to run this;
8:47 we've hit a snag as we wrote our files, so let's go back in and see
8:52 unsupported parameters for the stat module-
8:56 go back in and check out what we just wrote.
9:00 Now the issue here is that the indentation that I used is incorrect
9:05 this springs up a really good point about Ansible which is very sensitive
9:08 to indentation, because the playbooks are based on yaml,
9:12 what we've said here incorrectly and the reason why Ansible ceased to run
9:17 is because register and become are not arguments
9:21 that are passed to the stat module
9:24 they need to be one level up, the first thing is we're registering
9:27 a state known as certs, and we need sudo privileges,
9:32 because only sudo can access the directory that we're looking for,
9:36 so these are two arguments that are run with the stat module
9:40 not arguments that are passed into the stat module,
9:44 we'll save that, and then move up a few directories,
9:48 and we'll kick it off again.
9:51 Once again, we ran into an issue, but we got past the previous one
9:56 that was causing us some trouble.
9:59 We'll go back in, modify letsencrypt, so what we actually want to do here is,
10:04 we want to make sure we only run this when a directory does not exist
10:07 so the way we can do that is with not certs.stat.exists
10:12 so sometimes we need to fiddle around a little bit
10:15 with some of these conditions, just as we are more doing our programming
10:18 and make sure that it maps up to exactly what we would expect.
10:21 So we can delete the rest of these,
10:26 and just replace them with not certs.stat.exists.
10:31 Let's give this a try one more time.
10:48 This time it looks like everything ran fine, but the real test comes in
10:51 when we take a look at our url.
10:57 Now the thing is that this is not actually configured for the url to work just yet,
11:01 nginx is going to answer when something
11:05 contacts on port 80 directly through its IP address
11:09 we have not set up nginx to handle our domain name just yet,
11:13 we'll do that in the next video, for now we can see that we can contact nginx
11:17 through the IP address, so it is up and running
11:20 just by installing a package, but we need to tweak the configuration files now
11:23 so that it will serve up via the domain name.