[SK shieldus Rookies 16기][AWS] Amazon RDS / Amazon S3

Jina·2023년 12월 6일
0

SK shieldus Rookies 16기

목록 보기
33/59
post-thumbnail
post-custom-banner

Amazon RDS

정의

Amazon Relational Database Service
클라우드에서 간편하게 데이터베이스 설치·운영·확장 할 수 있는 관리형 서비스 모음

배포방식

  1. Amazon Aurora(MySQL 호환) Amazon Aurora(PostgreSQL 호환) MySQL MariaDB PostgreSQL Oracle SQL Server 의 7가지 주요 엔진 중에서 선택
  2. Amazon RDS on AWS Outposts 를 통해 온프레미스에 배포

특징

  1. 인프라 프로비저닝, 소프트웨어 유지관리 안 함
  2. 선택한 RDB 엔진을 클라우드 또는 온프레미스에 배포 및 크기 조정 가능
  3. Amazon RDS 다중 AZ 배포로 고가용성 달성 가능
  4. 운영 전문성, 보안 모범 사례 및 혁신 활용 가능

Amazon S3

정의

Simple Storage Service
확장성, 데이터 가용성, 보안 및 성능 제공하는 객체(=파일) 스토리지 서비스

장점

  1. 확장성 : 업계 최고 수준의 확장성 제공
  2. 데이터 가용성 : 고객이 원하는 양의 데이터를 저장 및 보호
  3. 보안 및 성능 : 비교 불가능한 보안과 성능 제공
  4. 데이터 내구성 : 99.999999999%의 데이터 내구성 보장

특징

  1. 비용 효율성: 비용 최적화를 위한 스토리지 클래스 및 관리 기능 제공
  2. 비즈니스 요구 사항 충족: 데이터 정리, 액세스 제어 설정 등을 통해 조직의 요구사항 충족
  3. Amazon S3 스토리지 클래스를 활용한 비용 절감
  4. 규정 준수 : 강력한 보안, 규정 준수, 감사 기능 제공
  5. 데이터 관리 : 강력한 액세스 제어, 복제 도구, 조직 전체 가시성 제공

SPA 형태로 바꿈 - ec2 rds 형태로 바꿈 - s3 rds 형태로 바꿈 - lambda 형태로 변경

마이크로 서비스 아키텍쳐란?

마이크로 서비스? 독립적으로 실행할 수 있는 단일 서버로 구현하고 실행할 수 있는 서비스 단위

마이크로 서비스 아키텍쳐란?

실습 전

1. MySQL 설치

MySQL Installer 8.0.35
https://dev.mysql.com/downloads/installer/

  1. mysql-installer-web-community-8.0.35.0.msi 다운로드 진행

  2. MySQL 커뮤니티에 로그인하지 않고, 다운로드만

  3. Excute해야하는 것이 있으면 Excute해주기

  4. MySQL 서버 설정

  5. MySQL 계정 설정
    6-2. MySQL Root Password : root

    6-3. MySQL 유저 계정
    User Name : rookies
    Password : rookies

  6. 변경하는 부분 없이 Next

  7. Apply Configuration에서 Excute해주기

  8. 설치완료

2. MySQL 접속

  1. MySQl Connections > + 클릭

  2. root 계정 정보 입력

  3. Setup New Connection > Test Connection
    정상적으로 접속이 되면 아래와 같은 팝업 발생

  4. Setup New Connection로 돌아와서 > OK 클릭

  5. MySQL Connections > 생성한 워크밴치 클릭하면 접속

3. MySQL에 테스트 DB 생성

  1. 스키마 생성 쿼리문
CREATE SCHEMA `sampledb` DEFAULT CHARACTER SET utf8 ;

use sampledb;

CREATE TABLE `emp` (
  `empno` varchar(50) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `department` varchar(50) DEFAULT NULL,
  `phone` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  1. 스키마에 데이터 삽입
use sampledb;

insert into emp (empno, name, department, phone) values (1, '첫번째', '본사', '010-0000-0001');
insert into emp (empno, name, department, phone) values (2, '두번째', '지사', '010-0000-0002');
insert into emp (empno, name, department, phone) values (3, '세번째', '협력사', '010-0000-0003');

실습

1. Python, MySql, Flask 연동한 CRUD

  1. cmd창
# /aws 디렉토리로 이동
$ cd /aws

# hello-flask 디렉토리 생성
$ mkdir hello-flask

# hello-flask로 이동
$ cd hello-flask

# vscode 실행
$ code .

# 파이썬 가상환경 생성(venv)
$ python -m venv venv

# 파이썬 가상환경 실행
$ .\venv\Scripts\activate

# 가상환경이 실행되면 경로 앞에 (venv) 가 붙는다.

# flask 설치
$ pip install flask

# pymysql 설치
$ pip install pymysql

# 설치된 패키지 확인
$ pip list
Package      Version
------------ -------
blinker      1.7.0
click        8.1.7
colorama     0.4.6
Flask        3.0.0
itsdangerous 2.1.2
Jinja2       3.1.2
MarkupSafe   2.1.3
pip          23.2.1
PyMySQL      1.1.0
setuptools   65.5.0
Werkzeug     3.0.1

[notice] A new release of pip is available: 23.2.1 -> 23.3.1
[notice] To update, run: python.exe -m pip install --upgrade pip

# 현재 프로젝트를 실행하기 위한 필수 패키지 목록 파일 생성
$ pip freeze > requirements.txt
# 패키지 목록 파일 확인
$ type requirements.txt
blinker==1.7.0
click==8.1.7
colorama==0.4.6
Flask==3.0.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
Werkzeug==3.0.1
  1. /aws/hello-flask/mydao.py 생성
import pymysql

class MyEmpDao:
    def __init__(self):
        pass
    
    def getEmps(self):
        ret = []
        db = pymysql.connect(host='localhost', user='root', db='sampledb', password='password', charset='utf8')
        curs = db.cursor()
        
        sql = "select * from emp";
        curs.execute(sql)
        
        rows = curs.fetchall()
        for e in rows:
            temp = {'empno':e[0],'name':e[1],'department':e[2],'phone':e[3] }
            ret.append(temp)
        
        db.commit()
        db.close()
        return ret
    
    def insEmp(self, empno, name, department,phone):
        db = pymysql.connect(host='localhost', user='root', db='sampledb', password='password', charset='utf8')
        curs = db.cursor()
        
        sql = '''insert into emp (empno, name, department, phone) values(%s,%s,%s,%s)'''
        curs.execute(sql,(empno, name, department,phone))
        db.commit()
        db.close()
    
    def updEmp(self, empno, name, department,phone): 
        db = pymysql.connect(host='localhost', user='root', db='sampledb', password='password', charset='utf8')
        curs = db.cursor()
        
        sql = "update emp set name=%s, department=%s, phone=%s where empno=%s"
        curs.execute(sql,(name, department, phone, empno))
        db.commit()
        db.close()
    def delEmp(self, empno):
        db = pymysql.connect(host='localhost', user='root', db='sampledb', password='password', charset='utf8')
        curs = db.cursor()
        
        sql = "delete from emp where empno=%s"
        curs.execute(sql,empno)
        db.commit()
        db.close()

if __name__ == '__main__':
    #MyEmpDao().insEmp('aaa', 'bb', 'cc', 'dd')
    #MyEmpDao().updEmp('aa', 'dd', 'dd', 'aa')
    #MyEmpDao().delEmp('aaa')
    emplist = MyEmpDao().getEmps();
    print(emplist)

2-2 mydao.py 실행

$ python app.py

2-3. /aws/hello-flask/myflask01.py 파일 생성

from flask import Flask
from flask.templating import render_template

from mydao import MyEmpDao

app = Flask(__name__)

@app.route('/emp01')
def emp():
    empList = MyEmpDao().getEmps();
    return render_template("emp01.html", empList=empList)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

2-4. /aws/hello-flask/templates/emp01.html

<!DOCTYPE html>
<html>
<head>
<style>
table, th, td{
	border : 1px solid black;
}
</style>
<meta charset="UTF-8">
<title>회원관리</title>
</head>
<body>
<table>
	<tr>
		<th>사번</th>
		<th>이름</th>
		<th>부서</th>
		<th>전화번호</th>
	</tr>
		{% for emp in empList%}
		<tr>
			<td>{{emp.empno}}</td>
			<td>{{emp.name}}</td>
			<td>{{emp.department}}</td>
			<td>{{emp.phone}}</td>
		</tr>
		{% endfor %}
</table>
</body>
</html>

2-5. 프로젝트 실행

$ python myflask01.py

 * Serving Flask app 'myflask01'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:80
 * Running on http://172.30.1.94:80
Press CTRL+C to quit

  1. AWS VPC 생성
    3-2. VPC > VPC 생성 > VPC 생성 설정

    3-3. VPC 생성 버튼 클릭

    3-4. VPC 생성 확인

  2. AMS RDS 생성
    4-1. RDS > 데이터베이스 생성

    4-2. 데이터베이스 생성

    마스터 사용자 이름 : root / 암호 : password

    4-3. 데이터베이스 생성 버튼 클릭
    4-4. 데이터베이스 생성 확인

  1. EC2인스턴스 생성
    생성된 EC2 인스턴스는 웹 애플리케이션을 실행하는 서버 역할 및 베스천 호스트 역할을 수행한다.
    5-2. EC2 > 인스턴스 > 인스턴스 시작 버튼 클릭
    5-3. 인스턴스 설정

    나머지 설정은 그대로 두고, 인스턴스 생성 버튼 클릭
    5-4. 생성 확인
  1. DB에 EC2 연결

    6-2. 연결된 컴퓨팅 리소스에서 EC2 연결 설정 클릭

    다음 > 설정 버튼 클릭
  1. Bitvise SSH Client를 이용한 SSH 로그인
    7-2. 인스턴스 퍼블릭 IP주소와 퍼블릭 IP DNS 주소 확인

    7-3. Bitvise SSH Client 실행 > 로그인

    7-4. Bitvise SSH Client > New terminal console 클릭
    7-5. 파이썬 설치 확인
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
[ec2-user@ip-10-0-11-237 ~]$ python3
Python 3.9.16 (main, Sep  8 2023, 00:00:00)
[GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

7-6. SFTP를 이용해 웹 어플리케이션 소스 코드 업로드
Bitivise SSH Client > New SFTP window

7-7. PIP 및 프로그램 실행에 필요한 패키지를 설치
Bitivise SSH Client > New Terminal Console

[ec2-user@ip-10-0-11-237 ~]$ cd hello-flask/

[ec2-user@ip-10-0-11-237 hello-flask]$ ls
mydao.py  myflask01.py  requirements.txt

[ec2-user@ip-10-0-11-237 hello-flask]$ sudo yum install python-pip

[ec2-user@ip-10-0-11-237 hello-flask]$ pip install -r requirements.txt

7-8. 애플리케이션을 실행
mydao.py 실행하니 MySQL 서버가 로컬 호스트로 되어 있기 때문에 변경이 필요하다.

[ec2-user@ip-10-0-11-237 hello-flask]$ python3 mydao.py

Traceback (most recent call last):
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/connections.py", line 644, in connect
    sock = socket.create_connection(
  File "/usr/lib64/python3.9/socket.py", line 844, in create_connection
    raise err
  File "/usr/lib64/python3.9/socket.py", line 832, in create_connection
    sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ec2-user/hello-flask/mydao.py", line 54, in <module>
    emplist = MyEmpDao().getEmps();
  File "/home/ec2-user/hello-flask/mydao.py", line 9, in getEmps
    db = pymysql.connect(host='localhost', user='root', db='sampledb', password='password', charset='utf8')
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/connections.py", line 358, in __init__
    self.connect()
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/connections.py", line 711, in connect
    raise exc
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")

vi 편집기로 mydao.py 파일 열기

[ec2-user@ip-10-0-11-237 hello-flask]$ vi mydao.py

host="localhost"라고 되어 있는 부분에 "localhost"를 RDB 엔드포인트로 변경 "database-020.cgswf9z3mjij.us-west-2.rds.amazonaws.com"

host를 수정하고 다시 앱을 실행하면 DB가 없다고 나온다.

[ec2-user@ip-10-0-11-237 hello-flask]$ python3 mydao.py

Traceback (most recent call last):
  File "/home/ec2-user/hello-flask/mydao.py", line 54, in <module>
    emplist = MyEmpDao().getEmps();
  File "/home/ec2-user/hello-flask/mydao.py", line 9, in getEmps
    db = pymysql.connect(host='database-020.cgswf9z3mjij.us-west-2.rds.amazonaws.com', user='root', db='sampledb', password='password', charset='utf8')
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/connections.py", line 358, in __init__
    self.connect()
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/connections.py", line 664, in connect
    self._request_authentication()
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/connections.py", line 954, in _request_authentication
    auth_packet = self._read_packet()
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/connections.py", line 772, in _read_packet
    packet.raise_for_error()
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File "/home/ec2-user/.local/lib/python3.9/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.OperationalError: (1049, "Unknown database 'sampledb'")
  1. AWS RDB와 MySQL 연결
    MySQL Workbench > Setup New Connection

    8-2. 경고 팝업 뜨면 Continue Anyway 클릭
    8-3. 접속 확인

    8-4. RDSMariaDB를 클릭하면 경고 팝업이 뜨는데 무시한다.

  2. 스키마 및 테이블 생성
    9-1. sampledb 스키마 생성

CREATE SCHEMA `sampledb` DEFAULT CHARACTER SET utf8 ;

use sampledb;

CREATE TABLE `emp` (
  `empno` varchar(50) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `department` varchar(50) DEFAULT NULL,
  `phone` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

9-2. sampledb 스키마에 데이터 삽입

use sampledb;

insert into emp (empno, name, department, phone) values (1, '첫번째', '본사', '010-0000-0001');
insert into emp (empno, name, department, phone) values (2, '두번째', '지사', '010-0000-0002');
insert into emp (empno, name, department, phone) values (3, '세번째', '협력사', '010-0000-0003');
  1. EC2 인스턴스에서 애플리케이션을 실행
    10-1. Bitivise SSH Client > New Terminal Console
    10-2. RDS에 연결됐는지 확인
[ec2-user@ip-10-0-11-237 hello-flask]$ python3 mydao.py
[{'empno': '1', 'name': '첫번째', 'department': '본사', 'phone': '010-0000-0001'}, {'empno': '2', 'name': '두번째', 'department': '지사', 'phone': '010-0000-0002'}, {'empno': '3', 'name': '세번째', 'department': '협력사', 'phone': '010-0000-0003'}]

10-3. 웹 어플리케이션 실행

# 필수 패키지 설치
[ec2-user@ip-10-0-11-237 hello-flask]$ sudo yum install python3.11
[ec2-user@ip-10-0-11-237 hello-flask]$ sudo pip install pymysql
[ec2-user@ip-10-0-11-237 hello-flask]$ sudo pip install flask

# 앱 실행
[ec2-user@ip-10-0-11-237 hello-flask]$ sudo python3 myflask01.py

10-4. 브라우저에서 웹 어플리케이션 확인
주소창에 EC2 인스턴스 퍼블릭 IPv4 주소/emp01 입력

  1. node.js 설치

    11-2. cmd창에서 확인
$ node --version
v20.10.0

$ npm --version
10.2.3
  1. React 프로젝트 생성
    12-1. React 설치
$ npm install create-react-app -g
npm WARN deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.

added 67 packages in 2s

5 packages are looking for funding
  run `npm fund` for details
npm notice
npm notice New patch version of npm available! 10.2.3 -> 10.2.4
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.4
npm notice Run npm install -g npm@10.2.4 to update!
npm notice

12-2. 리액트 프로젝트 생성

# aws 디렉터리로 이동
$ cd /aws/

# 리엑트 프로젝트 생성
$ npx create-react-app hello-react

# 아래와 같이 나오면 생성 성공
Success! Created hello-react at C:\aws\hello-react
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd hello-react
  npm start

Happy hacking!

12-3. 통신모듈 axios 설치

# 리액트 프로젝트 디렉터리로 이동
$ cd hello-react

# axious 설치
$ npm install -y axious

12-4. 현재 디렉터리를 프로젝트 루트로 설정한 VSCode 실행

$ code .

12-5. 리액트 서버 실행

$ npm start

  1. 리액트 프로젝트 내용 수정
    13-1. aws/hello-react/src/App.css
table, th, td{
  border : 1px solid black;
}

13-2. aws/hello-react/src/App.js

import './App.css';

function App() {
  return (
    <table>
      <tr>
        <th>사번</th>
        <th>이름</th>
        <th>부서</th>
        <th>전화번호</th>
      </tr>
       
        <tr>
          <td>{"empno"}</td>
          <td>{"name"}</td>
          <td>{"department"}</td>
          <td>{"phone"}</td>
        </tr>
       
    </table>
  );
}
export default App;

14. /emp01 주소로 요청이 들어왔을 때 화면(template) + 데이터를 반환하지 않고 데이터만 반환하도록 수정

14-2. aws/hello-flask/myflask01.py 수정

from flask import Flask
from flask.templating import render_template
from flask.json import jsonify # 추가

from mydao import MyEmpDao

app = Flask(__name__)

@app.route('/emp01')
def emp():
    empList = MyEmpDao().getEmps();
    # return render_template("emp01.html", empList=empList)
    return jsonify(empList) # 추가

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

14-3. flask 앱 실행

# flask 프로젝트 디렉토리로 이동
$ cd \aws\hello-flask

# 파이썬 가상환경 실행
$ .\venv\Scripts\activate

# flask 앱 실행
(venv)$ python myflask01.py

15. App.js (컴포넌트)가 화면에 최초 나타났을 때(마운트될 때) flask 서버로 데이터를 요청하고, 응답으로 데이터가 전달되면 화면에 출력하도록 수정

15-2. aws/hello-react/App.js

import { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios';

function App() {
  const [emps, setEmp] = useState([]);
  
  useEffect(() => {
    axios.get('http://localhost:80/emp01')
    .then(res => console.log(res))
    .catch(err => console.log(err));
  }, []);

  return (
    <table>
      <tr>
        <th>사번</th>
        <th>이름</th>
        <th>부서</th>
        <th>전화번호</th>
      </tr>
        
        <tr>
          <td>{"empno"}</td>
          <td>{"name"}</td>
          <td>{"department"}</td>
          <td>{"phone"}</td>
        </tr>
        
    </table>
  );
}

export default App;

15-3. 리액트 앱 실행

$ cd /aws/hello-react
$ npm start

15-4. 앱을 실행 후 개발자도구를 통해 CORS 에러가 발생 확인

16. CORS 오류가 발생하지 않도록 Flask 소스 코드를 수정

16-2. aws/hello-flask/myflask01.py

from flask import Flask
from flask.templating import render_template
from flask.json import jsonify
from flask_cors import CORS # 추가

from mydao import MyEmpDao

app = Flask(__name__)
CORS(app, origins=['*']) # 추가

@app.route('/emp01')
def emp():
    empList = MyEmpDao().getEmps();
    return jsonify(empList)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

16-3. flask 앱 실행

(venv)$ python myflask01.py 

16-4. 브라우저를 이용해서 리액트 개발 서버로 접속 ⇒ 콘솔에 데이터가 출력되는 것을 확인

17. 응답으로 전달 받은 데이터를 화면에 출력하도록 리액트 코드를 수정

aws/hello-react/src/app.js

import { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios';

function App() {
  // 상태변수를 정의
  const [emps, setEmp] = useState([]);  
  
  // 화면이 최초로 출력되었을 때(=마운트될 때) 동작을 정의 
  useEffect(() => {
    axios.get('http://localhost:80/emp01')
    .then(res => {
      console.log(res);   // 응답 내용을 콘솔에 출력
      setEmp(res.data);   // 응답 내용 중 data 항목을 상태변수 emps에 설정
    })
    .catch(err => console.log(err));
  }, []);

  return (
    <table>
      <thead>
        <tr>
          <th>사번</th>
          <th>이름</th>
          <th>부서</th>
          <th>전화번호</th>
        </tr>
      </thead>
      <tbody>
        { // 상태변수의 내용을 화면에 출력
          emps.map((emp, index) => (
            <tr key={index}>
              <td>{emp.empno}</td>
              <td>{emp.name}</td>
              <td>{emp.department}</td>
              <td>{emp.phone}</td>
            </tr>
          ))
        }
      </tbody>
    </table>
  );
}

export default App;

브라우저에서 확인 시 데이터가 반영되는 것을 확인할 수 있다.

브라우저 > 개발자 도구 > Network

18. React 서버용 인스턴스 추가

  1. EC2 > 인스턴스 > 인스턴스 시작
  2. 로컬에서는 3000포트로 서비스 했지만, EC2 인스턴스에서는 80 포트가 가용하므로 80포트로 서비스 하도록 설정
  3. 나머지 설정은 그대로 두고 인스턴스 시작
  4. 인스턴스 생성 확인

19. 리액트 서버로 SSH 접속해서 웹 서버를 설치하고, 리액트 코드가 웹 서버를 통해서 서비스되도록 설정

  1. Bitvise SSH Client > 로그인
  2. Bitvise SSH Client > New terminal console
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
[ec2-user@ip-10-0-31-245 ~]$ sudo yum install -y httpd
[ec2-user@ip-10-0-31-245 ~]$ sudo systemctl start httpd
[ec2-user@ip-10-0-31-245 ~]$ sudo systemctl enable httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[ec2-user@ip-10-0-31-245 ~]$ sudo systemctl is-enabled httpd
enabled
  1. 브라우저에서 EC2 인스턴스 퍼블릭 IP로 접근

20. 리액트 코드에서 플라스크 서버 주소를 EC2 인스턴스의 퍼블릭 주소 변경

aws/hello-react/App.js 수정

import { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios';

function App() {
  // 상태변수를 정의
  const [emps, setEmp] = useState([]);  
  
  // 화면이 최초로 출력되었을 때(=마운트될 때) 동작을 정의 
  useEffect(() => {
    // axios.get('http://localhost:80/emp01')
    // 플라스크 서버가 동작하고 있는 EC2 인스턴스의 퍼블릭 주소로 변경
    axios.get('http://54.185.239.251:80/emp01')
    .then(res => {
      console.log(res);   // 응답 내용을 콘솔에 출력
      setEmp(res.data);   // 응답 내용 중 data 항목을 상태변수 emps에 설정
    })
    .catch(err => console.log(err));
  }, []);

  return (
    <table>
      <thead>
        <tr>
          <th>사번</th>
          <th>이름</th>
          <th>부서</th>
          <th>전화번호</th>
        </tr>
      </thead>
      <tbody>
        { // 상태변수의 내용을 화면에 출력
          emps.map((emp, index) => (
            <tr key={index}>
              <td>{emp.empno}</td>
              <td>{emp.name}</td>
              <td>{emp.department}</td>
              <td>{emp.phone}</td>
            </tr>
          ))
        }
      </tbody>
    </table>
  );
}

export default App;

리액트 빌드 생성하기

# 빌드 생성
$ npm run build

# 빌드 파일 확인
$ dir .\build
 C 드라이브의 볼륨에는 이름이 없습니다.
 볼륨 일련 번호: 7CA3-675B

 C:\aws\hello-react\build 디렉터리

2023-12-06  오후 04:04    <DIR>          .
2023-12-06  오후 04:04    <DIR>          ..
2023-12-06  오후 04:04               517 asset-manifest.json
2023-12-06  오후 02:18             3,870 favicon.ico
2023-12-06  오후 04:04               644 index.html
2023-12-06  오후 02:18             5,347 logo192.png
2023-12-06  오후 02:18             9,664 logo512.png
2023-12-06  오후 02:18               492 manifest.json
2023-12-06  오후 02:18                67 robots.txt
2023-12-06  오후 04:04    <DIR>          static
               7개 파일              20,601 바이트
               3개 디렉터리  98,885,005,312 바이트 남음

Bitvise SSH Client > New SFTP window > build 폴더 업로드

Bitvise SSH Client > New Terminal console

[ec2-user@ip-10-0-31-245 ~]$ sudo mv ./build/* /var/www/html
# 권한 확인
[ec2-user@ip-10-0-31-245 ~]$ ls -l /var/www/html
total 40
-rw-rw-r--. 1 ec2-user ec2-user  517 Dec  6 07:04 asset-manifest.json
-rw-rw-r--. 1 ec2-user ec2-user 3870 Dec  6 05:18 favicon.ico
-rw-rw-r--. 1 ec2-user ec2-user  644 Dec  6 07:04 index.html
-rw-rw-r--. 1 ec2-user ec2-user 5347 Dec  6 05:18 logo192.png
-rw-rw-r--. 1 ec2-user ec2-user 9664 Dec  6 05:18 logo512.png
-rw-rw-r--. 1 ec2-user ec2-user  492 Dec  6 05:18 manifest.json
-rw-rw-r--. 1 ec2-user ec2-user   67 Dec  6 05:18 robots.txt
drwxrwxr-x. 4 ec2-user ec2-user   27 Dec  6 07:08 static

21. 플라스크 서버에 소스코드 업데이트

Bitvise SSH Client > MyEC2-020 인스턴스로 로그인 > New SFTP window

Bitvise SSH Client > New SFTP window > myflask01.py 파일 덮어쓰기

Flask 앱 실행
Bitvise SSH Client > New terminal console

$ cd hello-flask
$ sudo python3 myflask01.py

EC2 인스턴스인 MyReactServer-020의 퍼블릭 IP로 접근하여 데이터 반영 되는지 확인

2. 리액트 서버를 S3의 정적 웹 호스팅 기능을 이용해서 구현

1) 리액트 서버 역할을 수행했던 EC2 인스턴스를 종료

2) S3 버킷 생성

S3 > 버킷 > 버킷 만들기 선택

나머지 설정을 그대로 두고, 버킷 만들기 버튼 클릭

3) 버킷에 리액트 코드(빌드 결과)를 업로드

S3 > 버킷 > myreactserverbucket-020 버킷 클릭

만약 파일 업로드를 하는데 엑세스 거부 된다면 계정에 S3 권한이 없다는 것이다. 이때 해결방법은 다음과 같다.

  • 방법1. IAM에서 내 계정에 S3 권한을 부여
  • 방법2. S3 > 버킷 > 권한 탭 > 퍼블릭 엑세스 차단(버킷 설정)에 편집 버튼 클릭 > 모든 퍼블릭 엑세스 차단 항목 체크 해제

4) 정적 웹 사이트 호스팅 활성화

S3 > 버킷 > myreactserverbucket-020 클릭 > 속성 탭 > 정적 웹사이트 호스팅에서 편집 버튼 클릭


나머지 설정은 그대로 두고 변경사항 저장

정적 웹 사이트 접속 시 403 에러 발생 문제

웹사이트 접속 시 403 에러 발생한다.

403 에러의 원인이 다양한데

빌드 파일 확인

C:\aws\hello-react>npm install -g serve
C:\aws\hello-react>serve -s build  ┌──────────────────────────────────────────┐
   │                                       │
   │   Serving!                            │
   │                                       │
   │   - Local:    http://localhost:3000   │
   │   - Network:  http://192.168.56.1:3000│
   │                                       │
   │   Copied local address to clipboard!  │
   │                                       │
   └──────────────────────────────────────────┘

해결방법

  1. S3 > 버킷 > myreactserverbucket-020 클릭 > 권한 > 버킷 정책에서 편집 버튼 클릭
  2. 다음과 같이 권한 설정
  3. 웹 사이트 확인 시 정상적으로 나오는 걸 확인할 수 있다.

리소스 정리

  1. RDS > 데이터베이스 > 사용 중이었던 DB를 일시적으로 중지
  2. Flask 서버가 돌아가고 있던 MyEC2-020 인스턴스 중지
profile
공부 기록
post-custom-banner

0개의 댓글