RDS 같은 데이터베이스는 사실 외부에서 직접 접속하는 것을 막는 것이 좋다.

그러기 위해서는 private subnet을 이용하여 vpc내의 ec2가 접근하는 것은 허용하고, 나머지 접근은 허용하지 않으면 된다.

그림을 그리면 이런 느낌이다.

우리는 EC2에 외부에서 접속하여 RDS에 데이터를 올리고 조회할 수 있게 만들 것이다.

 

1. Public/Private Subnet 만들기

VPC마법사를 이용하여 만든다.

퍼블릭 및 프라이빗 서브넷이 있는 VPC 선택

2단계에서 vpc이름과 프라이빗, 퍼블릭 서브넷의 이름과 가용 영역을 설정한다.

탄력적 ip도 적용한다.

vpc는 10.0.0.0/16의 cidr를 사용하고, 그 안에서 public subnet은 10.0.0.0/24, private subnet는 10.0.1.0/24를 할당받았고, 이후에 추가하는 private subnet은 10.0.2.0/24를 할당한다.

 

2. private subnet추가

서브넷에서 서브넷 생성을 누른다.

VPC는 기존에 있던 VPC를, cidr블록은 아까 언급한 것처럼 10.0.2.0/24를 넣어준다.

가용영역은 아까 만든 private과 다른 곳에 만든다. 

 

3. VPC 보안 그룹 만들기

VPC는 아까 만든 VPC로 설정하고, 인바운드 규칙은 0.0.0.0/0이나 본인의 ip로 둔다.

private도 비슷하게 진행하는데, 인바운드 규칙에서 유형에 mysql/aurora로 설정하고, 소스에 아까 만든 ec2-security를 넣는다. 

4. RDS Subnet group 생성

RDS를 어떤 가용 영역에 위치시킬지 설정한다.

아까 가용영역 b, c에 private 서브넷을 만들었으므로 b, c 선택

5. RDS DB instance 만들기

연결에서 우리가 지금까지 만든 것들을 모두 입력한다.

(VPC, subnet group, vpc보안 그룹)

퍼블릭 액세스는 허용하지 않는다.

이후에 진행할 과정에서 초기 데이터베이스 이름이 필요하다.

 

6. EC2 instance 생성 및 Webserver 설치

네트워크를 기존에 만든 vpc, 서브넷은 public으로 설정.

보안그룹도 ec2를 위해 열어둔 것으로 설정.

eip도 자동할당을 한다.

 

이제 연결을 하여 PHP가 포함된 Apache Webserver를 설치한다.

sudo yum update -y
sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2
sudo yum install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd

업데이트를 진행하고

php software를 설치하고

webserver를 설치하고 시작, 그리고 system boot마다 시작하는 코드를 입력한다.

 

그러면 /var/www에 html 폴더가 생긴다.

이 폴더에 있는 파일을 우리는 웹에서 볼 수 있다.

하지만 지금 이 폴더의 소유권은 ec2-user가 가지고 있지 않다.

소유권을 옮겨오자.

그리고 inc라는 /var/www의 하위 디렉터리를 만든다.

이 디렉토리도 소유권을 옮겨오자.

그리고 dbinfo.inc파일을 inc 디렉터리에서 작성한다.

<?php
define('DB_SERVER', 'endpoint');
define('DB_USERNAME', 'tutorial_user');
define('DB_PASSWORD', 'master password');
define('DB_DATABASE', 'sample');
?>

위의 엔드포인트, tutorial_user 등에 자신의 환경에 맞게 입력한다.

/var/www/html에 SamplePage.php를 만든다.

아래의 코드를 이용하자.

출처-

https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/CHAP_Tutorials.WebServerDB.CreateWebServer.html

<?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;
}
?>

7. 탄력적 ip를 이용하여 SamplePage.php에 연결

이름과 주소를 입력해보자.

+ Recent posts