Create a web server and an Amazon RDS Database instance

Nick Rondeau
Geek Culture
Published in
12 min readAug 2, 2021

In the tutorial that follows, you specify the VPC, subnets, and security groups when you create the DB instance. You also specify them when you create the EC2 instance to host your web server. The VPC, subnets, and security groups are required for the DB instance and the web server to communicate. After the VPC is set up, this tutorial shows you how to create the DB instance and install the web server. You connect your web server to your DB instance in the VPC using the DB instance endpoint endpoint.

We are going to complete the following steps:

  1. Create a VPC with private and public subnets
  2. Create an RDS Database Instance
  3. Create an EC2 instance and install a webserver.
our completed configuration

If you don’t have an elastic IP address to associate with our NAT Gateway, allocate one now. Go to the EC2 section, and choose Elastic IPs

Then choose the option to allocate one.

Now let’s set up our VPC. Go to the VPC Dashboard, launch the Wizard. We’ll need to set a few values in this process.

  • IPv4 CIDR block: 10.0.0.0/16
  • IPv6 CIDR block: No IPv6 CIDR Block
  • VPC name: tutorial-vpc
  • Public subnet’s IPv4 CIDR: 10.0.0.0/24
  • Availability Zone: us-east-1a
  • Public subnet name: Tutorial public
  • Private subnet’s IPv4 CIDR: 10.0.1.0/24
  • Availability Zone: us-east-1a
  • Private subnet name: Tutorial private 1
  • Elastic IP Allocation ID: An Elastic IP address to associate with the NAT gateway
  • Service endpoints: Skip this field.
  • Enable DNS hostnames: Yes
  • Hardware tenancy: Default
Choose the configuration for Public and Private Subnets

Enter the information above during step 2. Choose the Elastic IP we created earlier. Then Create VPC.

And now you’re VPC should be created successfully. A warning: It costs money for however long you are running your NAT Gateway.

You must have either two private subnets or two public subnets available to create a DB subnet group for a DB instance to use in a VPC. Because the DB instance for this tutorial is private, add a second private subnet to the VPC.

We’re going to create additional subnets. You’ll see the Create subnet button, as well as the two other subnets we specified when we created the VPC.

On the Create subnet page, set these values:

  • VPC ID: Choose the VPC that you created in the previous step, for example: vpc-identifier (tutorial-vpc)
  • Subnet name: Tutorial private 2
  • Availability Zone: us-east-1b

Note: Choose an Availability Zone that is different from the one that you chose for the first private subnet.

  • IPv4 CIDR block: 10.0.2.0/24

Now we need to ensure the second private subnet uses the same route table as the first one we created.

Go to the VPC Dashboard, choose Subnets, then choose the first private subnet that you created for the VPC, Tutorial private 1.

Below the list of subnets, you’ll see the Route table tab.

We need a VPC security group for our public web server.

Create a security group for public access. To connect to public instances in your VPC, you add inbound rules to your VPC security group that allow traffic to connect from the internet.

Go back to the VPC Dashboard, choose security groups, then Create security group.

  • On the Create security group page, set these values:
  • Security group name: tutorial-securitygroup
  • Description: Tutorial Security Group
  • VPC: Choose the VPC that you created earlier, for example: vpc-identifier (tutorial-vpc)

Now we add some inbound rules.

Add rule, SSH and then MyIP. then HTTP and source 0.0.0.0/0

Once, completed, Create security group.

Now, We need a security group for private DB access.

  • On the Create security group page, set these values:
  • Security group name: tutorial-db-securitygroup
  • Description: Tutorial DB Instance Security Group
  • VPC: Choose the VPC that you created earlier, for example: vpc-identifier (tutorial-vpc)

In the Inbound rules section, choose Add rule.

  • Set the following values for your new inbound rule to allow MySQL traffic on port 3306 from your EC2 instance. If you do this, you can connect from your web server to your DB instance to store and retrieve data from your web application to your database.
  • Type: MySQL/Aurora
  • Source: The identifier of the tutorial-securitygroup security group that you created previously in this tutorial, for example: sg-9edd5cfb.

Now, we need a subnet group for our DB instance. Move over to Amazon RDS. Choose the Subnet groups option on the left.

  • Choose Create DB Subnet Group.
  • On the Create DB subnet group page, set these values in Subnet group details:
  • Name: tutorial-db-subnet-group
  • Description: Tutorial DB Subnet Group
  • VPC: tutorial-vpc (vpc-identifier)
  • In the Add subnets section, choose the Availability Zones and Subnets.
  • For this tutorial, choose us-west-2a and us-west-2b for the Availability Zones. Next, for Subnets, choose the subnets for IPv4 CIDR block 10.0.0.0/24, 10.0.1.0/24, and 10.0.2.0/24.

Now, we are finally ready to create our Database Instance

Back in RDS, choose Create database.

On the Create database page, shown following, make sure that the Standard create option is chosen, and then choose MySQL.

  • In the Templates section, choose Free tier.
  • In the Settings section, set these values:
  • DB instance identifiertutorial-db-instance
  • Master usernametutorial_user
  • Auto generate a password — Disable the option.
  • Master password — Choose a password.
  • Confirm password — Retype the password.

In the DB instance class section, enable Include previous generation classes, and set these values:

  • Burstable classes (includes t classes)
  • db.t2.micro

In the Storage and Availability & durability sections, use the default values.

In the Connectivity section, set these values:

  • Virtual private cloud (VPC) — Choose an existing VPC with both public and private subnets, such as the tutorial-vpc (vpc-identifier)
  • Subnet group — The DB subnet group for the VPC, such as the tutorial-db-subnet-group
  • Public accessNo
  • VPC security groupChoose existing
  • Existing VPC security groups — Choose an existing VPC security group that is configured for private access, such as the tutorial-db-securitygroup
  • Remove other security groups, such as the default security group, by choosing the X associated with each.
  • Availability ZoneNo preference
  • Open Additional configuration, and make sure Database port uses the default value 3306.

In the Database authentication section, make sure Password authentication is selected.

Open the Additional configuration section, and enter sample for Initial database name. Keep the default settings for the other options.

To create your MySQL DB instance, choose Create database.

Your new DB instance appears in the Databases list with the status Creating.

Wait for the Status of your new DB instance to show as Available. Then choose the DB instance name to show its details.

In the Connectivity & security section, view the Endpoint and Port of the DB instance.

You will need this to connect your webserver to your database isntance.

In this next section, we’re going to create an EC2 isntance and install a webserver.

then choose the Free tier Amazon Linux 2 AMI.

And then, staying in free tier, choose t2 micro as your instance type.

On the Configure Instance Details page, shown following, set these values and keep the other values as their defaults:

Choose Next: Add Storage. Keep everything default, then Next: Add Tags.

Choose Next: Configure Security Group.

On the Configure Security Group page, shown following, choose Select an existing security group. Then choose an existing security group, such as the tutorial-securitygroup

Then Review and Launch.

Success
Our instance is now running

Let’s Install an Apache web server. We’re going to connect to our new instance via SSH.

The correct way to connect is

ssh -i /path/my-key-pair.pem my-instance-user-name@my-instance-public-dns-name

you can see I chanched permissions on my pem file with chmod 400

Get the latest bug fixes and security updates by updating the software on your EC2 instance. To do this, use the following command:

$ sudo yum update -y

After the updates complete, install the PHP software using the amazon-linux-extras install command. This command installs multiple software packages and related dependencies at the same time.

$ sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2

Install the Apache web server.

$ sudo yum install -y httpd

Start the web server with the command shown following.

$ sudo systemctl start httpdand then set it to start on boot.$ sudo systemctl enable httpd

We need to set file permissions for the Apache web server

Add the ec2-user user to the apache group.

$ sudo usermod -a -G apache ec2-user

Log out to refresh your permissions and include the new apache group.

$ exit

Log back in again and verify that the apache group exists with the groups command.

$ groups

Change the group ownership of the /var/www directory and its contents to the apache group.

$ sudo chown -R ec2-user:apache /var/www

Change the directory permissions of /var/www and its subdirectories to add group write permissions and set the group ID on subdirectories created in the future.

$ sudo chmod 2775 /var/www find /var/www -type d -exec sudo chmod 2775 {} \;

Recursively change the permissions for files in the /var/www directory and its subdirectories to add group write permissions.

$ find /var/www -type f -exec sudo chmod 0664 {} \;

Now, ec2-user (and any future members of the apache group) can add, delete, and edit files in the Apache document root, enabling you to add content, such as a static website or a PHP application.

Now, we connect our Apache web server to the DB instance.

To add content to the Apache web server that connects to your DB instance

While still connected to your EC2 instance, change the directory to /var/www and create a new subdirectory named inc.

$ cd /var/www mkdir inc cd inc

Create a new file in the inc directory named dbinfo.inc, and then edit the file by calling nano (or the editor of your choice).

$ >dbinfo.inc

$ nano dbinfo.inc

Add the following contents to the dbinfo.inc file. Here, db_instance_endpoint is your DB instance endpoint, without the port, and master password is the master password for your DB instance.

<?php

define('DB_SERVER', 'db_instance_endpoint');
define('DB_USERNAME', 'tutorial_user');
define('DB_PASSWORD', 'master password');
define('DB_DATABASE', 'sample');

?>

Save and close the dbinfo.inc file.

Change the directory to /var/www/html.

cd /var/www/html

Create a new file in the html directory named SamplePage.php, and then edit the file by calling nano (or the editor of your choice).

$ >SamplePage.php

$ nano SamplePage.php

Add the following contents to the SamplePage.php file:

<?php include "../inc/dbinfo.inc"; ?>
<html>
<body>
<h1>Sample page</h1>
<?php

/* Connect to MySQL and select the database. */
$connection = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD);

if (mysqli_connect_errno()) echo "Failed to connect to MySQL: " . mysqli_connect_error();

$database = mysqli_select_db($connection, DB_DATABASE);

/* Ensure that the EMPLOYEES table exists. */
VerifyEmployeesTable($connection, DB_DATABASE);

/* If input fields are populated, add a row to the EMPLOYEES table. */
$employee_name = htmlentities($_POST['NAME']);
$employee_address = htmlentities($_POST['ADDRESS']);

if (strlen($employee_name) || strlen($employee_address)) {
AddEmployee($connection, $employee_name, $employee_address);
}
?>

<!-- Input form -->
<form action="<?PHP echo $_SERVER['SCRIPT_NAME'] ?>" method="POST">
<table border="0">
<tr>
<td>NAME</td>
<td>ADDRESS</td>
</tr>
<tr>
<td>
<input type="text" name="NAME" maxlength="45" size="30" />
</td>
<td>
<input type="text" name="ADDRESS" maxlength="90" size="60" />
</td>
<td>
<input type="submit" value="Add Data" />
</td>
</tr>
</table>
</form>

<!-- Display table data. -->
<table border="1" cellpadding="2" cellspacing="2">
<tr>
<td>ID</td>
<td>NAME</td>
<td>ADDRESS</td>
</tr>

<?php

$result = mysqli_query($connection, "SELECT * FROM EMPLOYEES");

while($query_data = mysqli_fetch_row($result)) {
echo "<tr>";
echo "<td>",$query_data[0], "</td>",
"<td>",$query_data[1], "</td>",
"<td>",$query_data[2], "</td>";
echo "</tr>";
}
?>

</table>

<!-- Clean up. -->
<?php

mysqli_free_result($result);
mysqli_close($connection);

?>

</body>
</html>


<?php

/* Add an employee to the table. */
function AddEmployee($connection, $name, $address) {
$n = mysqli_real_escape_string($connection, $name);
$a = mysqli_real_escape_string($connection, $address);

$query = "INSERT INTO EMPLOYEES (NAME, ADDRESS) VALUES ('$n', '$a');";

if(!mysqli_query($connection, $query)) echo("<p>Error adding employee data.</p>");
}

/* Check whether the table exists and, if not, create it. */
function VerifyEmployeesTable($connection, $dbName) {
if(!TableExists("EMPLOYEES", $connection, $dbName))
{
$query = "CREATE TABLE EMPLOYEES (
ID int(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(45),
ADDRESS VARCHAR(90)
)";

if(!mysqli_query($connection, $query)) echo("<p>Error creating table.</p>");
}
}

/* Check for the existence of a table. */
function TableExists($tableName, $connection, $dbName) {
$t = mysqli_real_escape_string($connection, $tableName);
$d = mysqli_real_escape_string($connection, $dbName);

$checktable = mysqli_query($connection,
"SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = '$t' AND TABLE_SCHEMA = '$d'");

if(mysqli_num_rows($checktable) > 0) return true;

return false;
}
?>

Save and close the SamplePage.php file.

Verify that your web server successfully connects to your DB instance by opening a web browser and browsing to http://EC2 instance endpoint/SamplePage.php

Success!

Thanks for reading!

--

--