CS373 Summer 2018: Travis Llado, AWS Tutorial

Introduction

    This tutorial covers the process of setting up a basic website using Amazon Web Services. We'll cover the process of creating a host, building and deploying a web server on that host, and configuring a domain name to direct to the web server. At the end of the tutorial you should have a functioning website operating on AWS. This tutorial assumes you are using Linux or MacOS.

The Part about EC2

    The first part of our hosting setup is the configuration of our host computer. The host computer contains the web server program that serves our website to visitors. Instead of using a physical host computer, we will use a virtual machine provided by Amazon Web Services (AWS) Elastic Compute Cloud (EC2) service. This machine will not actually exist. No one will be able to point to its physical location. It will be completely virtual and will exist only as a program running on Amazon's cloud infrastructure, but we will be able to access and control it like any remotely-accessible machine. This gives us a lot of freedom. Instead of having to buy and maintain physical machines, we can conjure up new machines as needed through our web browser. When we no longer need a machine, we don't have to recycle or repurpose it, we just delete it. When we want to reproduce a machine, we don't have to clone the HDD, we just copy the EC2 instance. And we can version control the entire machine the way we would version control a single program, reverting or forking as needed.

    Amazon provides a very detailed and thorough tutorial that walks a new user step-by-step through the process of creating and deploying a web server on an EC2 instance. They don't skip a thing. However, free products and advice are never free. Amazon's tutorial is as much advertisement as tutorial and includes many optional AWS products. The purpose of this tutorial here is to pare the process down to the essentials and save you some time. When you have time to spare, it might be worthwhile to go back and review Amazon's tutorial, which provides basic instruction on the use of many optional services that could enhance or expand your web product. That tutorial is available at https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html.

    Our basic tutorial starts at the AWS Dashboard. If you haven't already created an AWS account, do so. Then go to https://aws.amazon.com/ and click "Sign in to the Console". Under "All Services" > "Compute", select "EC2". You are now at the EC2 Dashboard (console.aws.amazon.com/ec2), which will show you a list of items of which you have zero and, underneath that, a big blue button labeled "Launch Instance". Press the big blue button.

    Our first major and probably most consequential decision is selecting which operating system to run. All of Amazon's tutorials will instruct you in the use of Amazon Linux 2, a Linux distribution created and optimized by Amazon specifically for EC2. However, I recommend selecting Ubuntu Server 16.04 LTS. Though Amazon makes documentation for Amazon Linux readily available, this documentation is limited and it won't be long before you start asking questions that aren't covered in the Amazon tutorials. Amazon writes the tutorials for Amazon Linux. The rest of the world writes tutorials for Ubuntu. I recommend Ubuntu.

    After selecting your OS, you are presented with several pages of configuration details for your instance, all of which we are going to skip. Click "Review and Launch". The Review page will list the default configuration of your (hopefully Ubuntu) instance, and the bottom of the page you will see the "Launch" button. Launch.
 
    Pay attention here, because you only get to do this once. The popup that just appeared is asking you how you will connect to your new virtual machine. You need to create an SSH key that will enable you to remotely log in via any SSH utility. If this is your first EC2 instance, select "Create a new key pair", enter a descriptive name for your key, something along the lines of "<myServerName>Key", and click "Download key pair". Before continuing on, open your Downloads folder and verify that your key file is there, because this is the only time you will ever be able to download it. It should be named "<theNameYouChose>.pem". Make a copy of the key file in a safe and secure location. If you have a password manager, open the key file in a text editor and copy its contents into your password manager. Just don't lose it. If you lose it, it's gone forever. Now move your key file to a standard location that you can remember, such as ~/.ssh. Then open a terminal, navigate to the key's location, and enter
    chmod 400 <theNameYouChose>.pem
This labels your key as being accessible only to you.

    Back in your web browser, you can now click "Launch Instances". After a few spinning logos, you will be redirected to the Launch Status page, where you should be told that your instance is now running. Your virtual Linux machine is now booted and operating inside Amazon's cloud. Return to the EC2 Dashboard and you should see that under "Resources", instead of zero, you now have "1 Running Instances". Congratulations. Click on "Running Instances".

    Now that our instance is operational, we need to access it. Currently it's locked up, unavailable to us. We need to configure AWS's security rules so that we can contact it and login. Go to the EC2 Dashboard and in the list on the left side of the screen, select "Security Groups". Click "Create Security Group" and enter a name and description. Click "Add Rule". Underneath "Type", from the drop-down menu, select "SSH". Underneath "Source", from the drop-down menu, select "Anywhere". Now create a second rule, this time selecting "HTTP" for "Type". Click "Create". Return to the EC2 Dashboard, select your new instance, click "Actions" at the top of the screen, and select "Network" > "Change Security Groups". Select the Security Group you just created and click "Assign Security Group". Your instance is now accessible via SSH and HTTP from anywhere on Earth, based on the rules that you just created and assigned.

    The table on this "Running Instances" page will list your instance, but it doesn't have a name. Click on your instance under "Name" and give your instance a descriptive name. Now scroll to the right and you will see the column "IPv4 Public IP" and, under that, the IP address of your instance. Your virtual computer is active and accessible at that address. So copy the address.

    As mentioned earlier, we'll connect to our virtual computer using any SSH utility. For Linux or MacOS, that will just be "ssh" at the command line. Open a new Terminal and enter
    ssh -i "~/.ssh/<yourKeyName>.pem" ubuntu@<yourRemoteIPAddress>
replacing <yourKeyName> and <yourRemoteIPAddress> with the name of the key file we saved earlier and the IPv4 address we just copied from the EC2 instance list. Press Enter. The first time you connect, you will receive a warning message saying that the authenticity of the remote computer cannot be established. This is fine for now. Type "yes" and press enter.

    You should now receive a welcome message beginning with "Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-1061-aws x86_64)" and you should have a terminal prompt of "ubuntu@ip-<yourRemoteIPAddress>:~$". That means you've logged in successfully. You now have complete access to and control of your remote virtual computer. You can do anything here that you would do on any other Linux terminal. You can run
    sudo apt-get update -y && sudo apt-get upgrade -y
to update your system. You can install whatever terminal apps you like. Just don't get carried away, because the free, default settings we used earlier provide us with only a few GB of storage space. That's it for our virtual host computer. It's running and we can access it.
     
    Now it's time to set up our web server. For this tutorial we're going to use a standard React web app server in accordance with the tutorial provided by React (https://reactjs.org/tutorial/tutorial.html). Install nodejs by entering
    curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
    sudo apt-get install -y nodejs
and then create a React app by entering
    sudo npm install -g create-react-app
    create-react-app my-app
This might take a minute or two. After React setup completes, you can enter
    cd my-app
    npm start
to run your React server. But ... you won't be able to access the website. The React demo website is running on your virtual server and if we could connect a monitor to our virtual machine we would be able to load a web browser and navigate to "localhost:3000", but your current port configuration won't allow you to access the website remotely. That's easy to fix. We just have to modify our routing tables.

    As I said, your website is currently available at port 3000, but that's using unoptimized execution. It's preferable to serve a compiled web app, and that will have it served at port 5000. So let's configure for that. When we configured our Security Group earlier, we made our instance accessible via HTTP. That means we opened up port 80 to incoming HTTP traffic. So we need to redirect traffic that arrives at port 80 to the port 5000 where our website is located. To do that, we'll us the Linux "iptables" command. In the remote terminal, enter
    sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000
This adds a new rule for how your instance handles incoming traffic, redirecting traffic that arrives at port 80 (incoming HTTP) to port 5000 (where our compiled website is served).

    Now that incoming traffic is directed to port 5000, we need to put our website at port 5000. Again in your remote terminal, enter
    npm run build
    sudo npm install -g serve
    serve -s build > stdout.txt 2> stderr.txt &
This builds a compiled, optimized, faster version of our React website, installs it as an application, and runs it in the background so that our terminal is still usable for other purposes and the website doesn't shut down when we close our terminal. When you want to shut down your web server, enter
    killall node
This will shut down all running React server processes.

    That's it for EC2. We have
- created an EC2 instance,
- configured it for remote access and logged in to it,
- installed nodejs and created a demo React web server, and
- configured iptables to redirect incoming HTTP traffic to the React web server.
If you go to any browser and type in your instance's IP address, the one we copied earlier, you should see your React demo website.

The Part about Route53

    Now that our server is up and running, we need to create a domain name for it. That means selecting and registering the domain name, then forwarding traffic that arrives at our domain name to our host machine.

    Go to the Route53 Dashboard (https://console.aws.amazon.com/route53). Under "Register Domain", enter a name you would like to use, select a suffix that fits your needs (.com, .org, etc), and click "Check". If your domain name is available, click "Add to Cart" and "Continue". Enter the contact information that will be associated with the domain and confirm payment. You now own a new domain.

    Return to the Route53 Dashboard, and under "DNS Management" select "Hosted Zones". Select your new domain from the list and click "Create Record Set". Ensure that under "Type" you have selected "A". This creates an A-Record, a very basic dns routing rule. Enter "www" for "Name" and enter our EC2 IP address for "Value". Click "Save Record Set". This will direct all traffic arriving at "www.ourdomain.com" to our EC2 instance. But what if someone types in just "ourdomain.com" or "somethingweird.ourdomain.com"? Click "Create Record Set" again, enter our EC2 IP for "Value" again, select "Type" "A" again, but this time leave "Name" blank and then click "Save Record Set" again. This second rule is a catch-all so that any incoming traffic that doesn't specify a subdomain will be directed to the regular site.

    That's it. It will take a minute or two for Amazon to update its forwarding rules, but all future traffic attempting to reach "anything.ourdomain.com" will be directed to the IP address of our EC2 instance.

Conclusion

    In this tutorial we have stepped through the process of creating and deploying a demo website using Amazon Web Services EC2 hosting and Route53 domain registration. We have
- created and configured an EC2 virtual machine instance,
- deployed a demo website on that EC2 instance,
- registered a domain name using Route53, and
- configure our domain to redirect to our EC2 instance.
All visitors who type "www.ourdomain.com" into their browsers will arrive at our React demo website. Presumably, visitors will grow bored with the demo site fairly quickly, so you should consider creating a more interesting offering to replace it. A searchable tutorial for this is available at www.google.com. Good luck.