How to Host a Website on the Amazon Cloud (AWS)

Starting from Nothing, The Quickest Path to Getting a Website Up and Running on Amazon
by Oliver; Jan. 13, 2014
 
aws
 
ec2
         
web
 

Introduction

Problem: you want to get a website onto the internet, and you want to do it yourself completely from scratch.
This tutorial aims to guide you through the process of getting one up and running on the Amazon Elastic Compute Cloud (EC2) in the fastest way possible, starting from zero and ending with a website, avoiding some of the pitfalls that I fell into. Amazon has extensive documentation but much of it gets knee-deep into minutiae and expects you to chase links which scatter like buck shot. It's not always clear what the next step is. If you're a complete novice and just want to get to the finish line in the broadest possible strokes—with a lot of screenshots to help you along the way—here's one way to do it in eight easy steps:
  1. Procure a Domain Name (I got mine from Namecheap)
  2. Set up an Account with Amazon Web Services (AWS)
  3. Get your Amazon "Cloud Computer" Up and Running
  4. Assign a Static IP Address to It
  5. Connect your Domain Name to this IP Address
  6. Enable Permissions on your Computer so the Outside World Can Access It via HTTP
  7. Run a Program on your Computer, such as Apache or Nginx, to Make It Function as a Server Able to Host Web Pages
  8. Visit Page on the Web and Congratulate Self :D

Background (or How the Internet Works in Two Paragraphs)

The internet works on a Client–server_model. When you go to a webpage, you're a client who is accessing information on somebody else's computer, the server. Wikipedia portrays it as follows:

image
(Image credit: Wikipedia: Client–server_model)

You can think of a server as a computer that's always on. Once upon a time, if I wanted to host a webpage I'd buy a computer and set it up as a server. However, if the computer breaks or there's a blackout or my house is burglarized, the site goes down. Enter Cloud Computing. It makes sense to outsource the responsibility of maintaining a computer + data to a big powerful company, like Amazon, who has a lot of money, a lot of engineers, and probably has data centers around the world with armed guards, sophisticated backups, geographical redundancy, etc. I chose Amazon just for this reason—it's a big, reliable company who's probably not going to go bankrupt any time soon. And popularity counts for something because it usually means better documentation and more forum activity.

If I want to get something from your computer—i.e., go to your website—how do I find it? I'm going to go to the domain name associated with your site, such as yoursite.com. This domain name, in turn, is associated with an IP Address mediated by the Domain Name System (DNS). The Amazon help docs describe the situation as follows:
Much like a phone book, the Internet’s DNS system manages mapping between names and numbers. In DNS’s case, the names are domain names (www.example.com) that are easy for your users to remember. Instead of phone numbers, in DNS, these names are mapped to IP addresses (192.0.2.1) that specify the location of computers on the Internet.
There—we know all we need to know to get started.

Procuring a Domain Name

Your Domain Name is the name of your site, such as www.yoursite.com. I bought mine from Namecheap. Another popular company is GoDaddy, but I choose the former simply because it was cheaper (by a factor of 2) and I had no other way to distinguish the two companies. It cost me about $25 for a two year stint. If you go to namecheap.com, you can look up which domain names are available and how much they cost. For example, if we are seeking to register the site www.defenestration.com, we have to look it up and see if anybody has already registered it. In this case we're out of luck:

image

Somebody already has it, but—as of this writing—some other options are available, like www.defenestration.biz (although the .biz extension screams "cheap crap" to me). For domain names that are taken, you can also see the names and addresses of the parties who have registered them. You probably don't want your home address floating around in a freely searchable-database on the internet, so I recommend paying a couple of extra dollars to anonymize your information. The service Namecheap uses to do this is called WhoisGuard.

Update: As long as you're in the Amazon ecosystem (read: monopoly:), Route 53 is a good choice for setting up your domain name.

Setting up an Account with Amazon Web Services

Setting up an Account with Amazon Web Services (AWS) is easy, especially if you already have an ordinary Amazon account. Once you've done this, the magic starts. You get access to: which is your GUI portal into the multitude of Amazon web services:

image

We're only going to focus on the Amazon Elastic Compute Cloud (EC2), which is described as Virtual Servers in the Cloud. With some restrictions, you can use the service free for a year, as described in AWS Free Usage Tier.

Starting with EC2

Let's get our server up and running. If we'd bought a computer to serve as a server, as in the old-school paradigm, we'd have to choose what kind of OS we wanted and make sure it was installed when we got the machine. Now, thanks to virtualization, we choose it as we go by selecting an Amazon Machine Image (AMI). As the help docs say:
An Amazon Machine Image (AMI) is a template that contains a software configuration for your server (for example, an operating system, an application server, and applications). You specify an AMI when you launch an instance, which is a virtual server in the cloud. The AMI provides the software for the root volume of the instance. You can launch as many instances from your AMI as you need.
You can think of the AMI as a virtual machine or, simply, a computer that springs into existence when you click the button.

Go to:
EC2 > INSTANCES > Instances
and click the big blue button that says Launch Instances. We get a screen that looks like this:

image

We can choose our AMI which is tantamount to choosing the operating system and some pre-installed software. Since Amazon is enthusiastically promoting its own Linux flavor, Amazon Linux, I chose that one. The next step is choosing the Instance Type, which determines our computing power—how much memory, how many CPUs, etc. Amazon describes it as follows:
Instances are virtual servers that can run applications. They have varying combinations of CPU, memory, storage, and networking capacity, and give you the flexibility to choose the appropriate mix of resources for your applications.
For the AWS Free Usage Tier you can get a Micro Instance, which has a little less than 1 G of memory:

image

There are a few more steps which we have to complete. We should Add Storage using Amazon Elastic Block Store (EBS):
Amazon Elastic Block Store (EBS) provides block level storage volumes for use with Amazon EC2 instances. Amazon EBS volumes are network-attached, and persist independently from the life of an instance. Amazon EBS provides highly available, highly reliable, predictable storage volumes that can be attached to a running Amazon EC2 instance and exposed as a device within the instance. Amazon EBS is particularly suited for applications that require a database, file system, or access to raw block level storage.
And, finally, we have to Configure Security. You'll see a table like this:
Protocol	Type	Port Range (Code)	Source
SSH		TCP	22			Anywhere 0.0.0.0/0
You should change the Source from 0.0.0.0/0 to your computer's IP address. Think of this as setting the Firewall settings. Secure Shell (ssh) operates over port 22 and, to start off at least, you want only your computer to be able to ssh into your Amazon computer. Read more on the help docs: Authorizing Inbound Traffic for Your Instances.

Return to the EC2 screen and—excitingly!—you'll see that you have an instance running:

image

So you've started your instance but how do you get to it? If you're not familiar with ssh, it's the command that allows you to log into a computer remotely over the network. In the simplest possible terms, it allows you to use a computer that's not physically right in front of you. If you have a Macintosh, go to Applications > Utilities and open the application named Terminal. You should be able to ssh into your Amazon computer now using the key Amazon provided you when you created your AWS account:
$ ssh -i AmazonKey.pem ec2-user@XXXXX
where AmazonKey.pem is your key and XXXXX is the name that's in the Public DNS field in the screenshot above. The help docs note that the user name, ec2-user, might vary if you're not using an Amazon Linux AMI. Upon logging in, you'll see something like this:

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2013.09-release-notes/
and you're in, just as if you'd bought a new computer! An awesome feature of the Amazon service is that you get root privileges to the computer—which is to say, full power to install anything and do anything you want.

Pitfall: One thing to watch out for is the following: the ssh address is based on your IP address and if you start and stop your instance the IP can change, changing the address you ssh into along with it (again, the value in the field Public DNS). If you've re-started your instance and are having trouble sshing, check that your address is correct.

Assigning an IP Address to Your Instance

We just addressed a pitfall regarding IP Addresses in the previous section. Let's get in the weeds with the documentation and learn about Amazon's Elastic IP Addresses (EIP):
An Elastic IP address (EIP) is a static IP address designed for dynamic cloud computing. With an EIP, you can mask the failure of an instance by rapidly remapping the address to another instance. Your EIP is associated with your AWS account, not a particular instance, and it remains associated with your account until you choose to explicitly release it.

By default, we assign each instance in EC2-Classic two IP addresses at launch: a private IP address and a public IP address that is mapped to the private IP address through network address translation (NAT). The public IP address is allocated from the EC2-Classic public IP address pool, and is associated with your instance, not with your AWS account. You cannot reuse a public IP address after it's been disassociated from your instance.

If you use dynamic DNS to map an existing DNS name to a new instance's public IP address, it might take up to 24 hours for the IP address to propagate through the Internet. As a result, new instances might not receive traffic while terminated instances continue to receive requests. To solve this problem, use an EIP.

When you associate an EIP with an instance, the instance's current public IP address is released to the EC2-Classic public IP address pool. If you disassociate an EIP from the instance, the instance is automatically assigned a new public IP address within a few minutes. In addition, stopping the instance also disassociates the EIP from it.

To ensure efficient use of EIPs, we impose a small hourly charge when they are not associated with a running instance, or when they are associated with a stopped instance.
So you should turn on Elastic IP by going to:
NETWORK & SECURITY > Elastic IPs
clicking the big blue button that says Allocate New Address, and associating this new address with your running instance. Here's a screenshot:

image

although you can't see the association since I've expurgated it. You can do this in a couple of clicks.

Connecting your Domain and your IP Address

Now that we have a static IP address associated with our Amazon computer, the next step is to connect this IP to our domain name. Since I did not get my domain name through Amazon, I can't do this part on Amazon. I used Namecheap, as noted before, so they have the authority over my domain name. Heading over to that site, we're going to go to:
DOMAINS > My Account > Manage Domains
which looks like this:

image

In gory detail, click on Manage Domains and you get to a list of your domains:

image

Click on your domain name to get to the Modify Domain screen and navigate to:
Host Management > URL Forwarding
and you'll see a screen like this:

image

A word of background: Wikipedia provides a list of the record types in the Domain Name System (DNS) here. The simplest type of record is called the Address Record, or A Record for short, and it simply connects a domain to an IP address. This Google help page has a nice explanation:
Address or A records (also known as host records) are the central records of DNS. These records link a domain to an IP address ... What are A records? For instance, altostrat.com has an A record that points to 68.178.232.100. This means that all traffic to altostrat.com will be directed to the server with IP address 68.178.232.100. The value of an A record is always an IP address, and multiple A records can be configured for one domain name.
All clear? Good. So we simply need to change both fields of our A records (@ and www in the screenshot above) to be whatever address was assigned to our Amazon elastic IP. Once you've done this—congratulations!—you've hooked your domain up to your Amazon server.

Tip: You can check that your domain is properly linked to your IP address using the unix utility dig. If your domain is your_web_address.com, then try:
$ dig your_web_address.com
It should display the proper IP.

Enabling Permissions

If you go into Safari or Chrome now and enter your URL, it will stall and your website won't come up. What's wrong? There are two things we need to do before the website becomes live: (1) enable more permissions; and (2) get server software up and running. We touched on the permissions bit before when we enabled ssh access. Now we need to enable HTTP and HTTPS permissions. Go to your AWS Console and to:
EC2 > NETWORK & SECURITY > Security Groups
and click on the security group associated with your instance. Click the Inbound tab and allow traffic from all IP addresses (0.0.0.0/0) for the ports 80 (HTTP) and 443 (HTTPS). Here's what it looks like:

image

Read more on the help docs: Amazon EC2 Security Groups.

Pitfall: If you've added more security groups, make sure they're associated with your instance. I stupidly added a couple more and didn't associate them with my instance, so I was enabling permissions but it had no effect. You can double check which security groups are associated with your instance by looking at the Security groups field in the INSTANCES > Instances section. Mine is the one created at launch time: launch-wizard-1.

Running Server Software

We've laid the foundation and the last thing to do is get a web server running on our computer. The big names in this game are Apache and Nginx. I choose the later because everyone's raving about it nowadays, and it's supposed to be much faster and handle concurrent requests more efficiently. Nginx was already installed on my Amazon Linux machine, but in case you have to install these programs (or to check that they're already installed), use yum:
$ sudo yum install nginx  # install Nginx
$ sudo yum install httpd  # install Apache
If you want to go the Apache route, start it as follows:
$ sudo /etc/init.d/httpd start
and you're on your own from there, since I'm not using it. For the Nginx server, start it as follows:
$ sudo /etc/init.d/nginx start
and you'll see a message telling you it's OK. Now, go to your URL and you should see the following:

image

Score! In the beginning—i.e., now, just after we've set everything up—we're only in the position to serve up static webpages, meaning webpages that have not been created programmatically. But that will change soon (see my tutorial on Setting Up Nginx, uWSGI, and Django on Amazon's EC2). In any case, the page you're seeing resides at:
/usr/share/nginx/html/index.html
on my system. You can rename this file to start your own website. For example,
$ sudo mv index.html index.1.html
Then make a file, index.html, such that:
$ cat index.html 
<!DOCTYPE html>
<html>
<h1>hey Mom!</h1>
</html>
And you've taken the first step toward making your own site. This being merely the starting line, you might also want to check out:
Advertising

image


image


image


image