Tania Rascia

Skip Navigation
Getting Started with AWS – Setting Up a Virtual Server

Getting Started with AWS – Setting Up a Virtual Server

 /  30 responses

Amazon Web Services, or AWS, is a set of web services provided by Amazon.com. If you’re looking for web hosting through AWS and have only had experience with managed hosting services before, there’s a lot to learn. In this tutorial, I’m going to highlight some of the most important features and services of AWS.

AWS is a veritable alphabet soup of acronyms, so I highly suggest you give AWS in Plain English a read through before attempting to tackle the beast.

The way I go about setting up a server is far from the only way to do it, but it will be a complete guide. The AWS Documentation is absolutely massive, so you should be able to find any additional information there.


  • Basic command line knowledge – if you’ve never used the command line before, trying to set up AWS will be a bit terrifying. I would recommend reading through the first few chapters of The Command Line Crash Course and getting comfortable before moving on to AWS.
  • Ability to set up a website – you should already know HTML and CSS, and have set up a live website at some point.


  • Make an AWS account and learn about the key services
  • Configure AWS Security
  • Set up and configure virtual server
  • Set up a LAMP stack (Linux, Apache, MySQL, PHP)
  • Set up virtual hosts

Where Things are Located In Linux

This will come in handy as you read the article.

  • Public HTML/var/www/html
  • Apache Configuration/etc/httpd/conf/httpd.conf
  • Hosts/etc/hosts
  • phpMyAdmin Configurationetc/httpd/conf.d/phpMyAdmin.conf
  • SSH Configuration/etc/ssh/sshd_config

Making an AWS Account

Here’s the good news – AWS is free for a year, so you can run through this or any tutorial to get an idea of how it all works, regardless of whether or not you want to use it.

Go to Amazon Web Services and sign up for an account. If you already have an Amazon.com account for something else (Kindle, buying stuff online) it will be the same account. You’ll choose the Basic (free) account, be prompted for your credit card and phone number, they’ll call you to confirm, and you’re in.

No opening preamble – here’s the dashboard.

Key AWS Services

There are currently 53 services, with more being added all the time, but you most likely won’t even use close to half of them. I’ll take a moment to highlight the absolute most essentials.

An EC2 instance (Elastic Compute Cloud) is a virtual server in the cloud. You have complete control over the server, what gets installed on it, the configuration, and so on. Since we’re setting up LAMP, Apache, MySQL and PHP are going to be installed on a Linux EC2 instance.

Amazon S3 (Simple Storage Service) is a static file storage service. It’s like a simple web interface for FTP, in which you can host static files and also host static websites – so images, HTML, CSS, JavaScript, PDFs, mp3s, and so on, but nothing that requires a server. S3 containers are known as buckets.

IAM (Identity & Access Management) will contain all the settings and security configuration your for your account.

There are many, many useful services here, but we should be able to get started with just these three.

Securing Your Account

A good idea when first creating your account is adding some additional layers of security. Go to IAM on the dashboard.

Activate MFA (Multi Factor Identification) on Your Root Account

Download Google Authenticator on your phone, and click Manage MFA. Select Virtual MFA Device. You’ll scan a QR code with the Google Authenticator app. Type the random numbers that pop up into the input, and your device will be associated with the account. Now no one can log in to your root account without also having your phone.

Create Individual IAM Users

Go to Users and Create User. Make a username for yourself. User Security Credentials will also be generated when you create the user, so save or download the Access Key ID and Secret Access Key they give you. At some point, these will come in handy, so it’s a good idea to make them right off the bat. Create a password for your user under Security Credentials.

Reason for users, according to AWS:

Create IAM users and give them only the permissions they need. Do not use your AWS root account for day-to-day interaction with AWS, because the root account provides unrestricted access to your AWS resources.

Create Groups

At this point, I’m going to go to Groups, create a group called Developer, and grant AdministratorAccess. Obviously, if you had a bigger team, you could allow access only to certain services, but since it’s just me, I’m going to give it full access.

Create a Password Policy

In Account Settings, you can set a password policy (or leave it as is), and your security setup is complete.

Create an Account Alias

Finally, how do we log in with the user we just created? You’ll notice at the top of the IAM dashboard, there’s a horrible link:

IAM users sign-in link:

Change it to something you’ll remember. Log out of your account, and go to https://your-alias.signin.aws.amazon.com/console. From here, you’ll log in with the credentials of the user you created before – you should no longer log in as root user.

Hopefully you feel pretty secure at this point, so we can finally move on.

Setting up an EC2 Instance

We’re going to set up a Linux EC2 instance. The default settings for a Linux server do not allow access via password – they use Key Pairs. If you want to change that later you can (although it’s not recommended), but it’s necessary to generate a key pair to begin.

Generate Key Pair

Go to EC2, and click on Key Pairs. Generate a key pair, and call it whatever you want. Your_Key.pem will get saved to your downloads folder. Move the pem file from your Downloads folder to your .ssh directory, located in your main user directory. The whole URL to your pem file should be:


You can technically move this file anywhere, it doesn’t need to be located in the .ssh directory to function.

Create a VPC

An instance requires a VPC (Virtual Private Cloud). Your region might contain a default VPC – mine did. You can check this by going to the EC2 dashboard and checking the settings on the right side for Default VPC. If it doesn’t exist, set one up.

Create Security Group

In the EC2 dashboard, click on Security Groups. You will see one already created by default, but we’ll make a new one to get accustomed to it.

Set a name (such as username_SG_region) and apply it to the default VPC (should be the only one).

On Inboard, add rule:
Type: HTTP
Source: Anywhere (

Source: Anywhere (

Type: SSH
Source: My IP

You can select the My IP option, or type “whats my ip” in Google to get your IP and type it in. These rules are telling the EC2 instance to allow inbound access to the internet ( but only allow SSH access from your IP. You can technically set SSH access to the internet as well, just know that it’s a reduction in security.

Launching an EC2 Instance

The setup for creating an EC2 instance is complete, so now we can launch. Go to Instances. It will tell you there are no instances set up, so click Launch Instance.

This will launch a quick start guide.

Choose an AMI

An AMI (Automated Machine Image) is a template for an instance. Later you can save your completed instance and launch new ones based on your configuration with an AMI. For now, we’re going to use the first option on the list, which is an Amazon Linux AMI.

Screen Shot 2015-12-21 at 9.02.14 PM

Choose Instance Type

Different instance types will provide different specs for CPU, memory, performance, and so on. The free-tier instance type is t2.micro, so select that and click Next – Configure Instance Details.

Configure Instance Details

Number of Instances: 1
Network: Default VPC
Auto-assign Public IP: Disable (we’ll set an elastic IP in a second)
IAM Role: Create New IAM Role – you don’t need to do this, but you can’t set a role after you create an instance, so I’m going to create a role and give it AmazonEC2FullAccess.
Shutdown Behavior: Stop

You can protect against accidental termination if you’d like.

You can skip past Add Storage and Tag Instance for now.

Configure Security Group

Select the security group you created before, with full HTTP and HTTPS access, and SSH access only from your IP.

Review and Launch then Launch. You will be prompted to enter a key pair, which will be the one you created earlier. Accept the terms and launch.

Connecting to an EC2 Instance

Back in the EC2 dashboard, if you go to Instances you’ll see the new instance set up with all your specs. It takes a few minutes to initialize.

You can right-click on the empty space under Name and set a name to your instance. This is how it will look when it’s ready.

Create an Elastic IP

Earlier I didn’t create a public IP for the instance. Now I’m going to go to Elastic IPs. Click Allocate New Address. Under Actions, select Associate Address and apply it to the instance you just created.

An Elastic IP will remain yours even if you shut down the instance, while a regular public IP won’t.

Now we can SSH into our instance and start installing services. Open Terminal. Find your “Public DNS” in your instance description. It will look something like ec2-00-00-00-00.us-region-0.compute.amazonaws.com.

The default user for AWS Linux is ec2-user. At this point, many people attempt to SSH to the server with the following:

ssh [email protected]
The authenticity of host “xxx” can’t be established.
ECDSA key fingerprint is “xxx”.
Are you sure you want to continue connecting? (yes/no)

At this point, you will enter:

Warning: Permanently added “xxx” to list of known hosts.
Permission denied (publickey).

As I mentioned before, the default settings for Linux require a public and private key match to log in, not password authentication. Now type the following:

chmod 400 ~/.ssh/Your_key.pem

Permissions need to be set to 400 before you can use the key.

ssh -i ~/.ssh/Your_Key.pem [email protected]

And you’re in!

__| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2015.09-release-notes/

First thing you can do is update the packages.

sudo yum update -y

You will install all the security packages that have come out for AWS since the AMI was launched. Now your instance is secure and up to date.

If you’ve never used Linux, yum is Yellowdog Updater, Modified, and it’s the primary package manager for Linux. You can easily install many services through yum.

With one command, you can install Apache, MySQL, and PHP.

sudo yum install -y httpd24 php56 mysql55-server php56-mysqlnd

You can also install them one at a time – yum install httpd24 installs Apache 2.4, yum install php56 install PHP 5.6, etc.

If you simply ran yum install php, you would end up installing PHP 5.3, the default version of PHP, which came out in 2009. I’d prefer the instance to be more up to date, so I’m using the AWS LAMP stack recommendations.

Now start Apache.

sudo service httpd start

And make sure it starts on each boot.

sudo chkconfig httpd on

Paste the URL of the Public DNS into your browser, and you’ll get this:

I’m also going to install git because it will come in handy.

sudo yum install git

Start MySQL. Later, you might decide to use RDS (Relational Database Service) for your database needs, but for now we can install MySQL on the server.

sudo service mysqld start

Now we’ll configure MySQL safely according to the AWS specifications.

sudo mysql_secure_installation

It will prompt you for the root password, which is blank, so press enter. You’ll type y about 5 times until the configuration is complete.

Prompt MySQL to load on boot.

sudo chkconfig mysqld on

Install phpMyAdmin.

sudo yum-config-manager --enable epel
sudo yum install -y phpMyAdmin

Edit the phpMyAdmin configuration file.

Find this:

<Directory /usr/share/phpMyAdmin/>
  <IfModule !mod_authz_core.c>
    # Apache 2.2
    Order Deny,Allow
    Allow from All
    Allow from
    Allow from ::1

If you want to be able to access phpMyAdmin from any IP, change it to this:

Order Allow,Deny
Allow from All

The preferred security method would be to add your IP to the bottom of the list and leave the other settings as is.

Allow from YOUR_IP

Also modify this configuration.

  #Require ip
  #Require ip ::1
  Require all granted

phpMyAdmin should work now when you go to http://PublicDNS/phpmyadmin.

You can login with root and the password you set earlier.

Create a new user

Let’s create a new user so we’re not using the default ec2-user. Log in as sudo (root) user.

sudo su

Create user. I’ll call it your-user.

useradd your-user

Set a password for the new user.

passwd your-user

Enter the password twice.

Now, if I’m using SFTP as well as SSH, I’ll want to be able to access the Public HTML folder (/var/www/html) with my user. You can’t sudo in SFTP, so we’ll need to assign a group to the www directory as well as the new user.

Modify New User Permissions

Create a www group.

groupadd www

Add group to new user.

usermod -a -G www your-user

Run the following commands.

chown -R root:www /var/www

chmod 2775 /var/www

find /var/www -type d -exec sudo chmod 2775 {} + 

find /var/www -type f -exec sudo chmod 0664 {} +

Now user your-user will be able to write in the www directory.

Give New User SSH Access

Open a new local Terminal window. Run this command to get the public key from your pem file.

ssh-keygen -y

When it prompts you for the URL, ~/ssh/Your_Key.pem won’t work. Instead, write out the full path.


Now the public key should come up. It will start with ssh-rsa and include a long string. Save it.

Back in your AWS Instance Terminal, change users to the new one you created.

sudo su - your-user

You’ll be in the /home/your-user directory. Make a directory for your public key to live and set the proper permissions.

mkdir .ssh
chmod 700 .ssh

Create authorized_keys and give it the proper permissions.

touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

Add the public key to the authorized_keys configuration.

nano .ssh/authorized_keys

Paste the keys, CTRL + O, Enter, CTRL + X to save and exit.

Now your-user has permissions to SSH into your instance!

Give User Sudo Access

An easy way to give your new user sudo access is to run this command as root:

sudo usermod -aG wheel your-user

Press i on the keyboard to enter Insert Mode. Find # %wheel ALL=(ALL) ALL and uncomment it (remove the #). Save and exit by pressing exit, and typing :wq! plus enter.

SFTP into Instance

If you want to SFTP into the instance, you can use the same Server (Public DNS) and username (your-user), and select key instead of password, linking to Your_Key.pem.

So you want SSH and SFTP access without using a keypair?

It's possible to enter SSH and SFTP with a password instead of a keyfile. This way you can access the server on any computer without special credentials. Obviously, this is usually advised against, but here's how to do it.

Back in the Security Groups, ensure that SSH has access from (, and not just your IP.

Edit the SSH configuration file with nano /etc/ssh/sshd_config. Find #PasswordAuthentication yes and uncomment. There might be another PasswordAuthentication below it, make sure it's set to yes.

Restart SSH by running sudo /etc/init.d/sshd restart. Now you can log in from any IP with the command ssh [email protected], it will prompt you for a password, and you will be entered.

Setting Up Virtual Hosts

Your public html folder is located in /var/www/html. Anything that is visible to the public should be located there. I've created a folder through SFTP called example. I'm also going to create a 000 folder, to be the localhost directory.

Edit the Apache configuration file.

nano /etc/httpd/conf/httpd.conf

Find AllowOverride None in <Directory "/var/www/html"> and change to AllowOverride All.

Add virtual hosts by adding this to the bottom of the file.

NameVirtualHost *:80

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot /var/www/html/000

<VirtualHost *:80>
  ServerName www.example.com
  ServerAlias example.com *.example.com
  DocumentRoot /var/www/html/example 

Save and exit. Now edit the hosts file.

nano /etc/hosts

And add as many hosts as you want.    dev.example.com    example.com

Remember to run service httpd restart after any Apache configuration change.

This will send the Public DNS to the 000 folder, and example.com and any related subdomain to the example folder.

You can create index.php in the 000 folder, and make it something simple to ensure php is functioning, and the localhost directive is pointing to the right place.

<?php echo '<h1>AWS Linux</h1>'; ?>

Easy enough.

Maybe you already have a DNS located somewhere that you can make a test with. I'm going to make dev.example.com point to AWS. I can do this by going to my host, finding the DNS settings, and creating a DNS Resource Record.

Name: dev.example.com
TTL: 300
Target: PublicDns

If you don't have a DNS or host already around that you can play around with, Route 53 on the AWS dashboard is where they take care of all DNS related entries.

Transferring Files to EC2

At this point, I have SFTP set up, so I can transfer files over the old fashioned way, with Transmit or Coda. But I'm going to do something even easier, and pull the code from a Git repo, since it's already up there.

git init
git remote add origin https://repo.git
git pull origin master

Now when I go to my site, all my files are there and the site is live.


You should have been able to run through this entire article without once referring to StackOverflow or Google to look up a command or explanation. If that's not the case, then I need to revise and improve the article.

Hopefully some of the aspects of setting up a server in AWS have been clarified, and you feel excited to explore more of AWS. If this article provides helpful, I'll look into making guides for setting up static hosting with AWS, databases in the cloud with RDS, setting up WordPress, setting up a CDN with CloudFront, load balancing multiple instances, and so on.


Get updated when I create new content.
Unsubscribe whenever. Never any spam.


I'm Tania. I turn down every ad, affiliate, and sponsor request I get. I write free resources that help thousands of people successfully become devs. If you enjoy my content, please consider supporting what I do.

Support my work

Write a response

Your email address will not be published. Required fields are marked *

All code will be displayed literally.


  • treddinWater says:

    Great intro to AWS. I think I have read every tutorial on this site. Even when I (think) already know the subject. Now I have wasted a day getting an Ubuntu instance up and running — an instance I will probably never use. Thank you 😉 For myself, the most difficult part of AWS was understanding the relationship and configuration route53. Hint, hint. Getting a domain name to resolve to AWS was indeed a maze of linking the AWS services: vpc, ec2, elastic ip, load balancers, and route53.
    I never realized until now how valuable a tool cPanel is. Bravo Tania!

  • calfre2020 says:

    very good information a bout Aws thank you for sharing this valuable information

  • Chris says:

    Hi Tania,

    will you do a tutorial for running lightsail instances as well any time?

  • Ganesh says:

    It's simply great.

  • MacPlatform says:

    Hi Tania, I just want to say thanks for your helpful neat tutorial & publication. It will be helpful for beginners if you can add SSH instruction to access Amazon Linux from windows in this tutorial. I’ve spent a good number of hours say day after creating instance to get inside after seeing this error page ec2-00-00-00-00.us-region-0.compute.amazonaws.com/cgi-sys/defaultwebpage.cgi. Thank you.

  • Ubirajara Escudero says:


    Thanks a lot for this great and clear job!

    Keep going on!

  • Kacy Hornbuckle says:

    Hello there! Quick question that’s completely off topic. Do you know how to make your site mobile friendly? My site looks weird when browsing from my iphone. I’m trying to find a theme or plugin that might be able to resolve this problem. If you have any recommendations, please share. Many thanks!|


  • Philip says:

    Really superb and clear. The virtual hosting is the most confusing subject. I have seen so many different conventions. Some approaches use a vhost.conf. And probably add an include line in the default httpd.conf.

    I have yet to see really clear and concise approach to virtual hosting. Because it involves so many pieces.

    Otherwise, your outline here is excellent.

  • Alan says:

    In my case this command:

    find /var/www -type f -exec sudo chmod 0664 {} +


    sudo: unable to execute /bin/chmod: Argument list too long

    I solved it with this alternate construction:


  • Alan says:

    This was a great help Tania, thank you. Just the right amount of detail.

    Only thing I remain stuck on (I came here having failed to solve it from a prior EC2 instance setup following Amazons docs) is permissions for the www/… folders.

    If I install a PHP app in a domain and it runs a script that tries to rename some of the folders under it, create log files, etc – it fails (reports an error along the lines: “File system is not writable by this installer…”).

    After all the help your article has already provided I totally do not expect you to tell me the answer…but if you *happened* to then I would be even more ^_^

    PS: I’ve Googled this a lot but I am scared to ‘break’ a well setup system plus there are just SO many answers I can’t find a safe consensus.

    Either way, thanks for the great help and brilliant article!

    Cheers, -Alan

    • Alan says:

      Replying to myself, I found out more…

      If I upload a tar ball of files and ssh in (as myUserName) and expand that tar ball, then the resulting PHP files can’t run via Apache in a way that allows files to be modified (such as the PHP app creating log files).

      But, if I follow the 6 steps under “To fix file permissions for the Apache web server” here:
      after the tar extract, then 100% AOK.

      So the shorter question is: if I upload files in a tar and expand them, how can they have the correct permissions given *I* uploaded them, not user `apache` (etc)?

      Hope that made sense.

      Cheers, ^_^

      • Tania says:

        Thanks for replying to yourself! It definitely helps people from the future.

        As for your question, I haven’t experienced that problem, so I’m not sure, but I’d assume it would involve putting you and Apache in the same usergroup with the same permissions.

      • Alan says:

        Thanks Tania for the quick reply.

        I’m sure your suggestion is part of the answer, I’ve sort of tried a variation on that, but not solved; yet.

        I will post here (another reply to myself (first sign of madness)) if I fix this. Cheers, -Alan

  • DJ says:

    I just finished up with this article, which was very well written and helpful, and I started to read your bootstrap article, is there a good way to integrate the bootstrap framework with my ec2 instance?

  • Tanner says:

    I edited the phpMyAdmin.conf file based on the required changes. I can’t pull up the phpMyAdmin address following the http://PUBLICDNS/phpmyadmin. This is the Public DNS of the ec2 instance correct?

    • Tania says:

      Did you do this?

      Order Allow,Deny
      Allow from All
      • Tanner says:

        # Apache 2.2
        Order Allow,Deny
        Allow from All
        Allow from
        Allow from ::1
        Yes I did

      • Tania says:

        There are two instances of this code, so if you only did it on one of them try doing it on the other as well.

      • Tanner says:

        # Apache 2.4

        #Require ip
        #Require ip ::1
        Require all granted

        # Apache 2.2
        Order Allow,Deny
        Allow from All
        Allow from
        Allow from ::1

        I have made this change to both instances of the code. I’m getting a forbidden, you don’t have access to /phpmyadmin on this server. any ideas?

      • Tania says:

        Have you restarted Apache after making these changes? sudo service httpd restart.

      • Tanner says:

        Restarting the service did the trick. I’m having trouble with logging into the PublicDNS/phpmyadmin. I’ve edited the /etc/phpMyAdmin/config.inc.php and changed

        $cfg[‘Servers’][$i][‘user’] = ‘user’;
        $cfg[‘Servers’][$i][‘password’] = ‘pass’;

        I’m unclear as to which credentials are used to login phpmyadmin. is it the new user created by root instead of using ec2-user?

  • olidev says:

    Nice guide, but I would like to add something to it. It also possible now to install and update PHP on EC2 without going directly to AWS. You can use a PaaS which makes the process much easier and quicker. Here is an example: https://www.cloudways.com/blog/host-php-on-aws-cloud/ This method is much better as it saves developers time which would have otherwise spent in setting up the server, OS and stack. This way developer spend their time and efforts on building the app instead of worrying about server.

  • Anonymous says:

    Great post, most informative, didn’t realise devops were into this.

  • Heidi says:

    Can anyone explain or give a hint for the problem: “Edit the phpMyAdmin configuration file. Is not self explanatory, also could not make phpMyAdmin to work.” Would be great, thanks!

  • Anonymous says:

    excellent well presented article.

  • Alexander Sedov says:

    Edit the phpMyAdmin configuration file. Is not self explanatory, also could not make phpMyAdmin to work.

  • Lisa Lim says:

    Thanks for this article, it definitely saved me a lot of time setting up my LAMP stack! A few suggestions:
    – putting the list of “Where things are located in Linux” before the instruction set. I wasn’t aware of this at first, and went to google to search for the location of the phpMyAdmin config file. The rest of your instructions included the location of the relevant files, so they were non-issues, except for the phpMyAdmin.conf instructions.
    – “The preferred security method would be to add your IP to the bottom of the list and leave the other settings as is.” When I left everything as default in phpMyAdmin.conf and added the line “Allow from xx.xx.xx.xx” (and then modifying the lines within ), I was still denied access to phpMyAdmin. I had to comment out “Deny from All” and restart httpd to reach phpMyAdmin. Not sure if this is the correct way of doing this.
    – adding sudo passwd for new user would be helpful too.

    • Tania says:

      Good points! The way you have phpMyAdmin set up would allow anyone to open your phpMyAdmin page, as opposed to only your home computer. I can put the list of files at the top.

  • Txema León says:

    Great tut, I suggest you to search for ServersForHackers videos to improve security over SSH and users.

    This would have been great some months ago when I wanted to use AWS for a project, anyway great work.

    Also, take a look at ansible if you plan to manage several instances of AWS to manage projects.