p2-insta485-serverside

AWS Tutorial

This tutorial will walk you through setting up AWS to deploy a web application.

In EECS 485, each team will deploy with one team member’s account. In other words, it’s not necessary for each team member create an AWS account.

You’ll create and configure one instance, and then reuse the same instance for each project. That means you’ll follow the create, launch and configure instructions once, and the deploy instructions multiple times.

Table of Contents

Create an account

Go to https://aws.amazon.com to create an account. When creating a new account, you are free tier eligible. This means that you will be able to run an instance for free for the duration of the course. In addition, you may browse to https://aws.amazon.com/education/awseducate/ to redeem extra benefits as a student. These include $100 in credits, which you can spend on any AWS charges.

You will need a credit card on the account, even if using free tier resources. This is how Amazon charges, in case you request more resources than provided in the free tier. Do not launch any additional instances other than the one we specify in order to avoid additional charges.

Launch an instance

Once your account is created and you are logged in, look for a dropdown at the top of the page that says “Services.” Click the drop down and then click “EC2”.

Console Image

Now click the blue button that says “Launch Instance.” On the following page, we want to select the Amazon Machine Image (AMI) that has the appropriate operating system we want for the instance. We will select Ubuntu 16.04.

Console Image

Next we select what instance type we want. Select the “t2.micro” instance type and click the “Next: Configure Instance Details” button. (“t2.micro” should say “free tier eligible” underneath it). Do not click launch yet. We still need to adjust some options. If you do accidentally launch the instance, you can skip the next steps regarding these options and then adjust the options after, or delete the instance (and any created volumes) and start over.

Console Image

Click “Next: Add Storage” to get to the “Add Storage” page. The default provided storage is 8GB. If your account is new, then you can get up to 30GB for free. You may follow the link provided on the page to receive more info on what you can get with free tier. The default size and selections should be fine here. AWS does have a minimum volume size requirement and you must be able to run your web application. Click “Next”

Console Image

Click “Next: Add Tags” and “Next: Configure Security Group” to reach the “Configure Security Group” page. Click “Add Rule” and from the “Type” dropdown select “HTTP”. The result should look like the screenshot below, with one rule for SSH and another for HTTP. Click “Review and Launch”

Console Image

On the next page, you will just see a review page detailing the settings you chose. Click the blue “Launch” button. A modal will pop up and ask you to create a key. Select “Create a new key pair” from the drop down and type an appropriate name in the box below. Then, click “Download Key Pair” which will download your pem key. Finally click “Launch Instances.” Then, click on , “View Instance”.

Console Image

Configure an instance

Using your terminal, navigate to the directory with your downloaded key. Change the permissions with chmod.

$ chmod 400 <name_of_key>.pem 

Now, after your instance state says “running” in your EC2 console on the AWS website, you may log into it via ssh. Your instance’s public domain can be found by clicking on the instance, from the “Instances” list in the EC2 console page on AWS, and looking at the “Description” at the bottom of the page.

$ ssh -i <name_of_key>.pem ubuntu@<Public DNS (IPv4)>

This logs in with root access. Right now, you can only log in with this <name_of_key>.pem key. If you want to add users to the instance for each of your teammates, with password protection, see the instructions at the end of this doc. Alternatively, you can restrict the use of passwords by following the instructions here http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/managing-users.html.

Now we need to install ngnix:

$ sudo apt-get update 
$ sudo apt-get install nginx

Copy paste your public domain into a browser tab and attempt to browse to your instance. You should see a default page with a message from Nginx

Console Image

Now let’s edit this default page to point to what will end up being our application. Open the file /etc/nginx/sites-available/default for editing. Note that the default editor specified by the $EDITOR environment variable will be used.

$ sudoedit /etc/nginx/sites-available/default

Modify /etc/nginx/sites-available/default. Replace the current default server settings with the settings specified below.

server {
  listen 80;
  server_name <Public DNS (IPv4)>;
  
  location / {
    proxy_pass http://localhost:8000;
  }
}

Open /etc/nginx/nginx.conf,

$ sudo vim /etc/nginx/nginx.conf

In /etc/nginx/nginx.conf, uncomment the line saying, server_names_hash_bucket_size and change its value to 128.

Restart the nginx server:

$ sudo systemctl restart nginx

Next we’ll install the rest of our dependencies:

$ sudo apt-get update
$ sudo apt-get install python3-venv python3-wheel python3-setuptools git tree default-jre sqlite3

You are now ready to deploy an individual project.

Deploy a web app

Use these deploy instructions for every project.

Once logged into your instance via ssh, clone your project repo into your home directory:

$ cd ~
$ git clone https://gitlab.eecs.umich.edu/your/project/repo
$ cd p1-insta485-static/

Install back end

Create a virtual environment in the newly created directory.

$ pwd
/home/awdeorio/p1-insta485-static
$ python3 -m venv env

Activate the virtual environment and install python package dependencies, including your project. Also, install gunicorn, which will be used for server deployment.

$ source env/bin/activate
$ pip install gunicorn
$ pip install -e .

Initialize database.

$ bin/insta485db create

Install front end

Skip this subsection if you’re not using JavaScript.

Install node and npm.

$ pip install nodeenv
$ nodeenv --python-virtualenv
$ source env/bin/activate  # again, after installing node

Install JavaScript packages, including obfuscator.

$ npm install .
$ node_modules/.bin/webpack
$ npm install javascript-obfuscator

Compile and obfuscate JavaScript.

$ node_modules/.bin/webpack
$ node_modules/.bin/javascript-obfuscator insta485/static/js/bundle.js
$ mv insta485/static/js/bundle-obfuscated.js insta485/static/js/bundle.js

Run server

Make sure that no old gunicorn processes are running. (Side note: on OSX, the equivalent is pgrep -lf.)

$ pkill -f gunicorn
$ pgrep -af gunicorn
  # no process should appear here!

Start gunicorn in the background (-D for daemon mode).

$ gunicorn -b localhost:8000 -w 2 -D insta485:app

Browse to your Public DNS name, (or refresh) and you should see your web app.

After successfully deploying, go back to the project spec and follow the deployment submission instructions. After submitting, be sure to kill your gunicorn process using pkill.

You may exit the ssh session with the ‘exit’ command.

$ exit

Debugging

Run gunicorn without the -D flag. The -D flag runs the process in the background. Removing -D runs in the foreground an shows errors.

Appendix

Add Users with Password Authentication

Password authentication is disabled by default on your EC2 instance. If you do not want to enable this when adding other users, then please refer to the linked instructions from AWS for adding the users and authorized keys.

To enable password authentication, please open the sshd config file as root:

$ sudo nano /etc/ssh/sshd_config

Find the line with “PasswordAuthentication”, make sure it is uncommented, and set the value to “yes”. It should look like this when you are done:

PasswordAuthentication yes

Next we want to restart the ssh service so that these changes are reflected by the ssh service:

$ sudo /etc/init.d/ssh restart

Now let’s add each user that we want. Run this command for each user you are adding

$ sudo adduser <username>

Provide a password when prompted. You may leave the rest of the requested information blank by pressing Enter.

Assuming that each team member will have admin priveledges, we will give all of these users sudo access:

$ sudo usermod -aG sudo <username>

Removing Team Members

In the case that you have a team change after a project and need to remove a student from your ec2 instance, you can run the following command.

$ sudo userdel -r <username>

Be sure that you do not remove the “ubuntu” user and that you keep your pem key from setup, just in case you need to log back in directly with the “ubuntu” user.

Alternate Config Files

Often when deploying to production servers, developers will have alternate config files, based on where the code is being run. You may or may not need such an extra config file for these projects, but to use a different config file, you simply need to specify this in your __init__.py file.

app.config.from_object(my_config)