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