How to Deploy your Flask app to AWS Elastic Beanstalk

1Apr- 2019
Python flask
AWS Elastic Beanstalk

Three years ago, I was a new developer trying (and failing) to deploy my simple Python Flask application to Amazon Web Services' (AWS) Elastic Beanstalk. In the process, I reviewed this documentation from the makers of Flask on how get started making simple Flask apps, this documentation from AWS on Elastic Beanstalk, and this blog post on using the two together. All were helpful, but I was so new to development that even with these and other resources, I found the process horribly frustrating, and I ran into one maddening error after another.

These days when I deploy my Flask apps to Elastic Beanstalk, I still run into some of the same hurdles that I encountered back then. Fortunately, over time I've learned how to power through each error more quickly. In an effort to continue making this process easier for myself, and to assist others who may still be struggling, I've created the following step-by-step guide on deploying Flask apps to AWS Elastic Beanstalk. A few notes about this guide:

  1. Depending on your comfort level with the language and tools presented here, it will take you at least an hour to complete this tutorial from start to finish.
  2. I use Python 2.7 throughout this tutorial. If you are using a different version of Python, you may need to make adjustments accordingly.
  3. Be sure to check out the icons throughout this post for screenshots that will help you confirm that you're seeing what you're supposed to be seeing in each step.

With that, let's get started!


Step 0: Create a virtual environment!


Ok, to be fair, you can totally deploy a Flask application without using a virtual environment. However, I feel so strongly that you should run your app in a virtual environment that I'm including this as a step in this tutorial. Every time I've tried to deploy a Flask app to Elastic Beanstalk outside of the safety of a virtual environment, I've encountered at least one vexing error that ate up valuable time, the most recent of which was this one —an error about about the Python six package that I didn't even know was needed for what I was trying to accomplish. Believe me, you do not want to spend time debugging this or similar errors that can easily be avoided by using a virtual environment. To spin up a virtual environment:

  1. Install pip, if you haven't already. Pip is a package manager for Python that makes it quick and easy to install Python packages. There are a few different ways to install pip, as documented here, but the easiest way is, arguably, to just run:
    $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python get-pip.py

    If you run the above command and get an error about how you need to run it with sudo, just change the command to:
    $ sudo curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python get-pip.py

  2. Install virtualenv, if you haven't already. Virtualenv is a package that allows you to create virtual environments. Once you have pip installed, you can install virtualenv by running the following on the command line: $ pip install virtualenv  

  3. Now that you have virtualenv installed, you can create a new virtual environment by running: $ virtualenv name_of_env
    Be sure to replace name_of_env with whatever you actually want to call your virtual environment. In this example, I call my virtual environment   flask_app_env.

  4. Activate your virtual environment by running   $ source flask_app_env/bin/activate.
    Be sure to replace flask_app_env with whatever you named your virtual environment. You will know if you are in your virtual environment (as opposed to just in a general directory on your computer) when you see the name of the virtual environment that you created in front of your cursor, as seen here: 

Now you're ready to start building your Flask app! Within your virtual environment of course.


Step 1: Make a Flask app!


If you're a true beginner, just getting a Flask app up and running locally might be a project in and of itself, even before you attempt to deploy it to Elastic Beanstalk. Fortunately, there are lots of great tutorials like this one from the makers of Flask that will walk you through making your first app step by step.

Since this blog is a Flask app too, if you don't want to go through the trouble of making an app from scratch right now, you can clone the repo for this blog and just use that. You can find my blog here. If this is your first time cloning a repo, and you need assistance, check out this helpful reference. If you do choose to clone my repo, be sure to install all of the requirements in the requirements file in the repo. If you don't, the app won't run. To install all of the requirements in my project's requirements file, after you've successfully cloned my repo locally, within the highest level directory of the project, run:
$ pip install -r requirements.txt

Regardless of how you make/acquire your Flask application, ensure the following for a smooth deployment to Elastic Beanstalk:

  1. Flask is installed inside of your virtual environment. To install Flask inside of your virtual environment, run $ pip install Flask on the command line. If Flask is already installed, you'll see a message confirming that it's already installed.

  2. The app's application file is named application.py (as opposed to, say, app.py). This is the file that contains all of the routes for your app. The first line in this file is likely something like: from flask import Flask, render_template

  3. Flask(__name__) is assigned to application (as opposed to, say, app) in application.py.

  4. "__name__" is assigned to "__main__" in application.py, as seen at the bottom of this file.

Once you have your application and it has all of the attributes detailed above, I strongly advise running your app locally before you go any further, to identify any issues that could be harder to debug further in the process. To run your Flask app locally, cd into your application's Main directory. Then, on the command line, run $ export FLASK_APP=application.py, followed by $ flask run. Then, in your desired browser, navigate to http://127.0.0.1:5000. At this point, you should see your app in the browser. If you see an error instead, go back and review what you may have missed when creating or cloning the app.


Step 2: Make an AWS Account and Create a New User!


One note about AWS accounts if this is your first time creating one: If you're just deploying a simple Flask application (like the one you may have cloned from my GitHub repo) to Elastic Beanstalk, then AWS will only charge you $1.00 per month for the first year. However, after that first year, AWS will charge you upwards of $10 per month.

To create your first AWS account (which will be awesomely cheap for the first year, depending on everything that you choose to use it for):

  1. Create an account here. Note that you may be asked to enter a credit card to create a new account. If you are not asked for a credit card, then I strongly suggest proactively adding one to your newly created account, as the deployment will just fail later in the process if you don't have a credit card linked to your account. Instructions on adding a credit card to your AWS account can be found here.

  2. Once you've created and logged into your new account, navigate to the search bar on the main landing page, type in "iam", and select the option presented in the dropdown: 

  3. On the resulting page, select "Users" from the left hand panel, and click on the blue "Add User" button towards the top of the page: 

  4. Enter your desired username (in the screenshot, I use my name, "Alyse"), and be sure to select the "Programmatic Access" type from the two access type options. Once complete, select the blue "Next: Permissions" button in the lower right hand corner of the page:  

  5. Enter your desired group name. In the screenshot, I use the group name "Admins". Then, select the "Administrator Access" group from the list of available policies. Once done, select the blue "Create group" button in the lower right hand corner of the page: 

  6. The resulting screen will confirm that you are adding your newly created user to the "Admins" user group: 

  7. Continue clicking the blue "Next" buttons on the lower, right hand corner of each page until you get to the final confirmation page that the user has been successfully created with permissions: 

Step 3: Deploy to AWS!


Even though we created a user and permissions via the AWS UI, from here, will use the command line for the actual deployment. You'll want to do all of this from within your virtual environment. Again, you know if you are in your virtual environment when you see the name of your virtual environment in front of your cursor, as seen here: 

To deploy your Flask app to Elastic Beanstalk:

  1. Install AWS command line tools if you haven't already. These can be installed by running  $ pip install awsebcli --upgrade via the command line.

  2. cd to into your application's top level directory. This will likely be one directory level above your Main directory. This is important. If you don't run everything from your top level directory, when you go to deploy your application, you will encounter errors not covered in this tutorial.

  3. In your application's top level directory, run eb init. This initializes Elastic Beanstalk. It will also create a git-ignored directory in your Main directory. Do not delete or move this directory. If you do, your deploy will fail.

  4. After you run eb init, you'll be prompted to enter your default region. This is effectively AWS asking you where you want your servers to be physically located. If you hit enter, AWS will choose for you. Or, you can enter the number associated with your preferred region. If this is your first time doing this, I'd suggest just letting AWS decide for you. Since I live and work in New York City, I always enter a 1 here because I like manually confirming that the servers that I get are the ones that are physically closest to me: 

  5. You'll be prompted to create a name for your application. I use the name 'first_flask_app', but you can call it whatever you want: 

  6. Next, you'll be asked to confirm if you're using Python, and if so, which version. Enter the appropriate responses based on what you're using. You may also be asked if you want to set up CodeCommit, and/or if you want to use SSH for your instances. I suggest entering 'n' for all of this for now, just to keep it simple. You can make updates later. 

  7. Next, you'll be asked to enter a keypair for your application. If this is your first time doing this, no options will be listed and you'll want to select the default of creating a new keypair. If you've done this before, you'll have the option of creating a new keypair, or selecting a keypair that you've made in the past. Regardless, for our purposes, enter whatever number is needed to create a new keypair. You'll also be prompted to enter a passphrase, which you can do, but I never bother with. 

  8. Now, we have to set up the environment name and DNS for our app by running eb create. You'll be prompted to enter an environment name, DNS name, and load balancer type. It's fine to use defaults for all of this. Once you finish stepping through the prompts, you'll see some output in the terminal while Elastic Beanstalk deploys the application. It generally takes between 5 and 20 minutes to deploy, and the console output stops when complete. 

  9. Once complete, sign back into the AWS UI, navigate to the search bar on the main landing page, type in "elastic beanstalk", and select the option presented in the dropdown: 

  10. In the Elastic Beanstalk dashboard, in the left hand panel, select the 'Configuration' option. On the resulting page, in the 'Software' box in the upper left hand corner, select the 'Modify' text towards the bottom of this box.

  11. On the resulting page, update the value of WSGIPath to Main/application.py, and update the value of Directory to Main/static/.

  12. After you've made the changes above, your application will update again. This update will take another 2-10 min. Once complete, navigate back to the main Elastic Beanstalk dashboard. Towards the top of the page, you'll see a 'URL'. If everything has completed successfully, click on this URL to be directed to your site: 

That's it! You've just successfully deployed your Flask application to Elastic Beanstalk! That was a lot, but now that you have it deployed and out into the world, updating it is easy. Every time you want to deploy your latest changes to Elastic Beanstalk, simply run the same eb deploy command that you ran earlier. Happy Pythoning!