Create a web server and an Amazon RDS Database instance
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:
- Create a VPC with private and public subnets
- Create an RDS Database Instance
- Create an EC2 instance and install a webserver.
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
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
andus-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 identifier —
tutorial-db-instance
- Master username —
tutorial_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 access — No
- VPC security group — Choose 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 Zone — No 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:
- Network: Choose the VPC with both public and private subnets that you chose for the DB instance, such as the
vpc-identifier | tutorial-vpc
created in Create a VPC with private and public subnets. - Subnet: Choose an existing public subnet, such as
subnet-identifier | Tutorial public | us-west-2a
created in Create a VPC security group for a public web server. - Auto-assign Public IP: Choose Enable.
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.
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
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
Thanks for reading!