Getting started with Amazon Web Services (AWS)

I’ll be walking you through getting started with Amazon Web Services.  Before we begin, I’m going to assume that you have some experience with setting up websites, even if they are simple static ones.  In this particular example I’ll be setting up a WordPress site using services from AWS.

While there are many different ways you can host WordPress, I chose AWS because;

1) AWS would allow me to start and stop servers based on my traffic needs.  Scalability is a big selling point with AWS, they have micro instances that can support up to a few hundred concurrent visitors to large cluster environments that can be used for high throughput applications.  http://aws.amazon.com/ec2/instance-types/
2)  The AWS suite of services complement each other and are easy to integrate into an environment.  For instance, you can spin up multiple micro instances in different regions and put them behind a load balancer in a few seconds.
3) The free tier of services allows developers to experiment building out environments without having to pay setup fees for bulky equipment or services.
http://aws.amazon.com/free/
4) More and more businesses are realizing the benefits of moving their data centers and infrastructure into the cloud.  Long gone are the days when it took a few days for a data center to build a traditional virtual server, in AWS you can spin up a new instance within a matter of seconds.

Step 1 – Sign up for an AWS account
Go to http://aws.amazon.com and sign up for an account.  You’ll have to provide credit card details, but the example I’ll walk you through qualifies for their free services, so you shouldn’t get charged.  I hold no responsibility if you do!

AWS Console
AWS Console highlighting the services that will be used for WordPress.

Step 2 – Overview of AWS Services
For the WordPress proof of concept (POC), we’ll be using the following AWS services that I have highlighted in the above image.

  • EC2 – The computer/server that will be used to host the WordPress files.  You’ll have the choice to determine the operating system (OS), and instance size.  There are many different flavors of OS that you can use with AWS.  Some are standard, but 3rd parties have also provided pre-installed software based on typical kits that are used.
  • S3 – Is Amazon’s content distribution network (CDN).  This is similar to Akamai or other CDN’s that are commercially available.  One of the benefits of having a CDN is that it frees up the main servers resources to handle requests.  The other benefit of having a CDN is that services like Akamai replicate files across their network, so if you wanted to download a huge file from a site, Akamai would allow you to download it from the server closest to you, instead of a server on the other side of the coast.  We’ll be using S3 to serve images and static files from our WordPress site.
  • RDS – Is Amazon’s database service.  Typically, databases are housed on a separate server because of the resources it requires.  In data rich applications, databases are housed on clusters, which are multiple servers.  For the WordPress site, we’ll be using RDS to house our MySQL database.
  • Load Balancers – This Amazon service is bundled in with EC2.  For a typical WordPress site, you won’t need a load balancer, but for high traffic sites, the load balancers help route traffic so user experience is unaffected.  The best way to utilize a load balancer is to setup smaller instances behind it and have the load balancer spread the traffic across multiple sites.  This way, you can pay a lower amount of money for smaller instances.  It can also help avoid outages.  If you are expected to have your site up for advertising reasons, or other reasons, having 2 smaller instances behind a load balancer instead of 1 larger instance will be cheaper and more resilient.
AWS Architecture
Proposed AWS Architecture

Step 3 – Launch EC2 Instance #1
Let’s launch the first server for the WordPress installation.  Jump into your AWS console by going to http://console.aws.amazon.com and click on EC2.  I just want to point out a few things on this screen.  First, I’ve selected Oregon as the region in the upper right of the screen.  When we setup the second instance, we’ll select Virginia.

EC2 Console
EC2 Console – Oregon

Click on Launch Instance, and in the window that pops up, select Quick Launch Wizard and fill out the following fields;

  • Name of instance – this is a friendly name and can have spaces.  I chose WordPress-Oregon.
  • Choose a key pair – this generates a file that you have to download to your computer.  I chose wordpress.
  • Launch configuration – This is where you choose your operating system.  I’m going to be building an Ubuntu server LTS (long term support) 64 bit that runs NGINX web server.  Alternatively, you can choose the standard Amazon Linux AMI (Amazon Machine Image) and use Apache.  I’ll have a comparison of both environments in another post.
EC2 Instance Quick Launch Wizard
EC2 Instance Quick Launch Wizard

The next window will allow you to edit the details of the server, but I’ll just use the defaults.

EC2 Instance Details
EC2 Instance Details

You’ll then get a confirmation window stating it could take a few minutes for the instance to be available.  Click on “Instances” from the Navigation pane and you should see the instance you just created.  Click on the check box to the left of it and the details will populate the bottom half of your screen.

EC2 Instance with Elastic IP assigned
EC2 Instance with Elastic IP assigned

Click on “Security Groups” under Network & Security and check “quicklaunch-1” to see the details.  In the lower section of the screen, click on Inbound, so you can open up ports to allow for incoming connections to the server.  Create the following inbound rules and remember to click on “Apply Rule Changes”.

  • Port Range: 20-21
  • Port Range: 80
EC2 Security Groups
EC2 Security Groups

Port Range: 22 (SSH) should have already been there.  Port 20-21 will be for FTP access (used by  Wordpress auto installs) and Port 80 is used by the web server to serve content to web visitors.

Let’s generate an Elastic IP and assign it to the instance.  From the left Navigation, click on “Elastic IPs” and click on “Allocate New Address”.  Now, click on the IP address and assign it to the instance we just created.

Step 4 – Connect to EC2 via SSH
SSH can be a little complicated, but I’m going to give you the basics so you can get started.  If you want to learn more about it, Google it!

I’m using a Mac, so I can SSH by opening the Terminal app.  If you are on a PC, you can SSH by running the CMD (Command) prompt from Run.  Alternatively, you can download graphic interfaces that will allow you to SSH into the server.  For Mac, I’m using Cyberduck (http://cyberduck.ch), because it has a minimal interface, and allows me to open an SSH terminal connected from the app, so I won’t have to remember the login.

Remember that Key Pair you downloaded when you were starting the instance?  It should be in your download folder somewhere.  I called mine “wordpress”, so the file is in my download folder and it is called “wordpress.pem”.

Open Terminal and type in “cd /downloads” to go to your downloads folder where the “wordpress.pem” file is located.

ssh -i wordpress.pem ubuntu@ec2-54-245-241.20.us-west-2.compute.amazonaws.com
sudo -i

These two commands will get you logged into your Ubuntu instance and changed as the root account.  As the root account, you will have access to install new software and change the configuration on the server.

Now lets install a firewall to protect the server from unwanted incoming connections.

ufw allow ssh
ufw allow http
ufw logging off
ufw enable

Now, lets install any updates on the Ubuntu server.  You’ll be using the APT-GET command, which is the command on Ubuntu to use the advanced packaging tool.

apt-get update

Next, we will install and configure the PHP framework with additional modules that we’ll need such as MySQL.

apt-get install php5-fpm php-pear php5-common php5-mysql php-apc php5-gd php5-curl

Let’s configure PHP to use APC (Alternative PHP Cache), because we’ll be able to take advantage of it with a WordPress plugin called W3 Total Cache.  We’ll have to use the “nano” command to edit the /etc/php5/fpm/php.ini file to add these 3 lines at the bottom.

nano /etc/php5/fpm/php.ini

Now you’ll see an editor window, with a bottom row of command keys.  I used “Control+V” to page down to the end of the file and found the last entry and typed in the new APC code.  Then I used “Control+X” to close the file and when I was prompted to save the file, I said yes and I overwrote the existing “php.ini” file.  Add these lines to the bottom of the php.ini file before the close.

[apc]
apc.write = 1
apc.slam_defense = 0
Nano command prompt
nano /etc/php5/fpm/php.ini

Next, let’s edit the “www.conf” file to use NGINX.  Open the /etc/php5/fpm/pool.d/www.conf” file using the nano command.

Find the line that says;

user = www-data
group = www-data

And replace it with;

user = nginx
group = nginx

Next, find the line that says;

listen = 127.0.0.0.1:9000

And replace it with this line;

listen = /dev/shm/php-fpm-www.sock

Add these 3 lines right after the “listen” parameter.

listen.owner = nginx
listen.group = nginx
listen.mode = 0660

Type in “Control+X” and overwrite the file.

Install and Configure NGINX

Now, we need to install NGINX, the web server, but unfortunately it’s not part of the native Ubuntu APT package, so we’ll have to add it.

First, we need to download and verify the NGINX package with our server.

cd /tmp/
wget http://nginx.org/keys/nginx_signing.key
apt-key add /tmp/nginx_signing.key

Next, we need to add the URL of where the packages are to the “sources.list”, so when we tell the server to install it, it knows where to download the files from.

echo "deb http://nginx.org/packages/ubuntu/ lucid nginx" >> /etc/apt/sources.list
echo "deb-src http://nginx.org/packages/ubuntu/ lucid nginx" >> /etc/apt/sources.list

Now, if these new entries to “sources.list” were correct, we should be able to install NGINX by using the APT-GET command.

apt-get update
apt-get install nginx

You should see a message in your window that says “Thanks for using NGINX!”.

We’re going to edit some of the NGINX config files so WordPress will run when we install it in the next few steps.  In your terminal screen type in the following;

nano -w /etc/nginx/conf.d/default.conf

What you want to do next is “Control+K” everything in the file and replace it with this;

server {
 ## Your website name goes here.
 server_name domainname.com www.domainname.com;
 root /var/www/;
 listen 80;
 index index.html index.htm index.php;
 location = /favicon.ico { access_log off; log_not_found off; }
 location = /robots.txt { access_log off; log_not_found off; }
 location ~ /\. { deny all; access_log off; log_not_found off; }
 location / { try_files $uri $uri/ /index.php?q=$uri&$args; }
 location ~ \.php$ {
 fastcgi_buffers 8 256k;
 fastcgi_buffer_size 128k;
 fastcgi_intercept_errors on;
 include fastcgi_params;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_pass unix:/dev/shm/php-fpm-www.sock;
 }
# BEGIN W3TC Page Cache cache
location ~ /wp-content/w3tc/pgcache.*html$ {
 add_header Vary "Accept-Encoding, Cookie";
}
location ~ /wp-content/w3tc/pgcache.*gzip$ {
 gzip off;
 types {}
 default_type text/html;
 add_header Vary "Accept-Encoding, Cookie";
 add_header Content-Encoding gzip;
}
# END W3TC Page Cache cache
# BEGIN W3TC Browser Cache
gzip on;
gzip_types text/css application/x-javascript text/x-component text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
location ~ \.(css|js|htc)$ {
}
location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
}
location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
}
# END W3TC Browser Cache
# BEGIN W3TC Page Cache core
rewrite ^(.*\/)?w3tc_rewrite_test$ $1?w3tc_rewrite_test=1 last;
set $w3tc_rewrite 1;
if ($request_method = POST) {
 set $w3tc_rewrite 0;
}
if ($query_string != "") {
 set $w3tc_rewrite 0;
}
if ($http_host !~ "domainname.com") {
 set $w3tc_rewrite 0;
}
set $w3tc_rewrite3 1;
if ($request_uri ~* "(\/wp-admin\/|\/xmlrpc.php|\/wp-(app|cron|login|register|mail)\.php|\/feed\/|wp-.*\.php|index\.php)") {
 set $w3tc_rewrite3 0;
}
if ($request_uri ~* "(wp\-comments\-popup\.php|wp\-links\-opml\.php|wp\-locations\.php)") {
 set $w3tc_rewrite3 1;
}
if ($w3tc_rewrite3 != 1) {
 set $w3tc_rewrite 0;
}
if ($http_cookie ~* "(comment_author|wp\-postpass|wordpress_\[a\-f0\-9\]\+|wordpress_logged_in)") {
 set $w3tc_rewrite 0;
}
if ($http_user_agent ~* "(W3\ Total\ Cache/0\.9\.2\.4)") {
 set $w3tc_rewrite 0;
}
set $w3tc_ua "";
set $w3tc_ref "";
set $w3tc_ssl "";
set $w3tc_enc "";
if ($http_accept_encoding ~ gzip) {
 set $w3tc_enc _gzip;
}
set $w3tc_ext "";
if (-f "$document_root/wp-content/w3tc/pgcache/$request_uri/_index$w3tc_ua$w3tc_ref$w3tc_ssl.html$w3tc_enc") {
 set $w3tc_ext .html;
}
if ($w3tc_ext = "") {
 set $w3tc_rewrite 0;
}
if ($w3tc_rewrite = 1) {
 rewrite .* "/wp-content/w3tc/pgcache/$request_uri/_index$w3tc_ua$w3tc_ref$w3tc_ssl$w3tc_ext$w3tc_enc" last;
}
# END W3TC Page Cache core
}

Let’s make a directory on the server called “/var/www/” where we’ll install WordPress.

mkdir -p /var/www/
chown nginx:nginx /var/www/
chmod 775 /var/www/

What we did was make a directory “mkdir” called “www”, and gave it ownership rights to NGINX and changed the read/write permissions.

Now, lets actually download WordPress and install it.

cd /tmp
wget http://wordpress.org/latest.tar.gz
tar zxvf latest.tar.gz
cd wordpress
mv * /var/www/
chown -R nginx:nginx /var/www/
cp /var/www/wp-config-sample.php /var/www/wp-config.php
chown nginx:nginx /var/www/wp-config.php

Let’s generate a salt-key using the WordPress API by going to http://api.wordpress.org/secret-key/1.1/salt/, copy all the text into your clipboard, because we will be editing the “/var/www/wp-config.php” file for WordPress and will need to paste in the new key.

nano /var/www/wp-config.php

I found the first line to replace and used “Control+K to cut out the lines, then used “Command+V” to paste in the salt-key that was generated.  You can “Control+X” and overwrite the file for now.

We should also be inputting our DB information, but we haven’t spun up the Amazon RDS MySQL instance yet.  So, lets do that now.

Step 5 – Spin up an RDS instance and install MySQL

Let’s go back to your AWS Console and go into RDS and Launch a DB Instance.  We’re going to install MySQL Community Edition on a micro instance with Multi-AZ deployment is No.

RDS Instance with MySQL
RDS Instance with MySQL

Within the instance, I’ve created a new database named “wordpress”.

Next, we’ll have to update the security on the RDS instance to allow incoming connections from our EC2 instance we created earlier.

From the left Navigation, click on “DB Security Groups”.  From the drop down under Connection Type, select “EC2 Security Group”.

RDS Security Group
RDS Security Group

Now, that we’ve created the RDS instance with MySQL and the initial WordPress database, we can go back to the terminal window that is connected via SSH to the instance.

nano -w /var/www/wp-config.php

I updated the MySQL settings area of the file and updated the following;

define('DB_NAME', 'wordpress');
define('DB_USER', 'root');
define('DB_PASSWORD', 'password');
define('DB_HOST', 'wordpress-oregon.cbbbsis4us1j.us-west-2.rds.amazonaws.com');

Substitute anything you might have different in regards to database name, username, password and database host (which is the Endpoint of the RDS).

Step 6 – Finish WordPress Install

Wow, if you are still with me, we’re almost there.  Not really, we’re about half way through with what we were planning on doing, but this is definitely a milestone.

Let’s open a new browser tab or window and type in the URL, which is your Elastic IP of your EC2 instance.  Mine for example was 54.245.241.20.

Wordpress Welcome Screen
WordPress Welcome Screen, a sight for sore eyes.

I’ll continue the setting up of WordPress in a different post, stay tuned!

 

Leave a Reply