Securing an AWS Virtual Private Cloud for Django Deployment
Into your secure VPC
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Serverless Django with Zappa course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Serverless Django with Zappa, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

[00:00 - 00:15] Now that we've set up our AWS networking environment, we're going to go back to our console, make some changes to our configuration, and try to deploy our Zappa project into the cloud once again. Let's go to VS Code first. We're going to have to edit our settings file.
[00:16 - 01:13] We're going to have to edit our allowed host. Since we won't know what the auto -generated URL is going to be, we're going to have to remove this for now. Also, we're not going to have the custom domain set up, so I'm removing all those from the local hosts. In terms of the database, let's verify that the host is accurate. If we go back to our AWS console and click on our database identifier, we can see that we have the correct endpoint configured in our settings file. Finally, because I'm using white noise and I'm not using a custom domain, I have to change the white noise static prefix to include the stage name as well. One more thing, make sure you update your database credentials with your password. Now let's move on to our Z appa settings file.
[01:14 - 02:05] Because we currently don't have a custom domain set up, we're going to comment out certificate ARN and domain. We're going to add a new configuration section called VPC config. And we're going to take the subnet IDs of the private subnets and paste them in here. If you recall, our private subnet one and our private subnet two have unique IDs, we 're going to make sure we cut and paste them into our zappa settings.json. In addition, the security group IDs, which we can find under the EC2 management console, we want the default security group name for the newly created VPC ID. And we're going to put that, and we're going to put that here.
[02:06 - 02:39] Once we've done that, we can save this file. Let's go to our console and deploy our project. You'll notice I'm using the deploy command because we need zappa to set up all the infrastructure for a brand new project. However, this time when it's setting up the project, it's putting everything in the proper subnets that we've set up.
[02:40 - 03:10] Okay, that's finished. You may be a little concerned that we got a 500 response code. Don't worry. The reason we got a 500 code is that we've enhanced our Django application to leverage and depend on a database. And right now the database is brand new and fresh.
[03:11 - 03:25] We can verify the Django application is working by checking inspect DB. Okay, it appears that Amazon is a little slow this morning during my recording of this session.
[03:26 - 03:46] You can see that the invoke operation failed because the function is not yet created. So we need to wait a few minutes while Amazon completes the setup. In the meantime, I can use the zappa status command to get the automatically generated URL so that I can edit my allowed hosts.
[03:47 - 04:03] Let's do that now. The status has returned the URL I need to put in my allowed host. So let me do that now.
[04:04 - 04:23] Remember, you can't put the HTTPS in front. You just need the domain name. And we definitely don't need the stage name at the end here.
[04:24 - 04:53] Okay, let's go back and see if our function is complete. Well, that was a success. You can see that we've invoked the manage command to see if it can connect to the database and it can. So let's go ahead and set up our database.
[04:54 - 05:05] We'll follow the same steps we did in the database module. First, we apply the migration to establish the schema.
[05:06 - 05:39] Next, we need to create the super user. In the earlier database module, we created the super user from our local machine. We don't always have access to the database from our local machine. I'm going to show you a way to create a super user using the zappa utility to create the super user on our behalf. In order to do this, we actually have to tell our Django instance to run some Python code. The way we're going to do this is have the zappa utility actually run a Python script.
[05:40 - 06:28] Here we're showing a method to have the zappa utility invoke our AWS landup function to run an arbitrary Python script. And the script that we're running is getting in the user model and inserting a super user object. We'll walk through this step by step. So the first is you run the zappa utility and use the invoke command. Then the dash dash raw flag tells zappa that you want to run direct Python scripts from the command line. The Python script is between these double quotes. And it's a pretty straightforward Python script. You're importing the get user model from Django.
[06:29 - 07:21] You're getting the user object from get user model. Then you're creating a super user invoking the create super user method. And then the three parameters are the values of your super user, the username, the email and the password. For now, I'm going to use a random password as my super user's password here. And let's go ahead and run this. You can see the output of the raw command is successful. In theory, you can use this raw invoke command to run arbitrary Python scripts. But it's best to keep this to a minimum.
[07:22 - 07:59] Okay, before we run our zappa update command, I want to do a quick collect static. It's always a good habit to run collect static to make sure that you have the latest and greatest static files. The last thing I need to do is run the zappa update command to ensure that the Django settings file has the most current auto-genade URL in our allowed host file.
[08:00 - 08:37] Okay, that's finished. Let's check out our site. It looks good. The front end is working. Let's check our admin site.
[08:38 - 08:50] Oh, looks like I made a mistake in my white noise configuration. Static files aren't showing up. Let me fix that real quick.
[08:51 - 09:11] And then I do another update. Okay, that's finished. You may notice that I'm editing the video to skip the waiting.
[09:12 - 09:22] Sometimes it takes a few moments for the updates to complete. Let's check our live site now. That's much better.
[09:23 - 09:49] And here we go. Our site is now live and working perfectly. The only step we haven't covered so far is adding a custom domain name to our URL. Fortunately, that process is identical. It's unchanged whether or not you've deployed to a VPC. So congratulations.
[09:50 - 10:01] Now your zappa deployment and your database are no longer accessible from the Internet and much more secure than when we did it last time.