VPC, 서브넷, 인스턴스의 구조를 자동으로 그려주는 웹페이지 제작
Git Hub 링크
프로그래밍 언어: Python, JavaScript
프레임워크: React
개발환경: Visual Studio Code
프론트엔드 서버: Node.js
백엔드 서버 서버: Flask
기타: Git Hub, Docker
AWS에서는 내가 만든 VPC, 서브넷, 인스턴스 등의 구조 사진을 정말 간략하게 보여주는데 이 사진이 좀 더 자세하게 있으면 좋을 것 같아서 만들게되었다.
개발기간: 2024.11.1 -
이 사진이 AWS 홈페이지에서 제공하는 사진이다.
클라이언트 (프론트엔드):
사용자가 웹 브라우저를 통해 애플리케이션에 접근한다.
React로 개발된 프론트엔드는 사용자 인터페이스(UI)를 제공한다.
사용자 입력에 따라AWS VPC정보를 요청하는 API 호출을 수행한다.프론트엔드 API 호출:
사용자가 VPC를 선택하면 프론트엔드는/vpcs 엔드포인트에 GET 요청을 보낸다.
이 요청은 백엔드 서버의Flask 애플리케이션으로 전달된다.백엔드 (Flask):
Flask 서버는AWS SDK(Boto3)를 사용하여 AWS 계정의 VPC 정보를 가져온다.
/vpcs 엔드포인트에 대한 요청을 처리하고, AWS에서 수집한 VPC 정보를JSON 형식으로 반환한다.AWS와의 통신:
Flask 애플리케이션은 AWS EC2 서비스를 통해 VPC, 서브넷, 인스턴스 등의 정보를 조회한다.
AWS API 호출은보안 자격 증명을 사용하여 인증을 수행한다.데이터 반환:
백엔드는 AWS에서 수집한 정보를 프론트엔드에 다시 전송한다.
프론트엔드는 수신한 데이터를 UI에 표시합니다. 사용자에게는 VPC의서브넷,인스턴스,라우팅 테이블등의 정보가 보여진다.상세 정보 요청:
사용자가 특정 VPC를 선택하면, 프론트엔드는 해당 VPC의 상세 정보를 요청하는 API 호출을 한다.
백엔드는 선택된 VPC의서브넷,인스턴스,라우팅 테이블정보를 반환한다.최종 사용자 경험:
사용자는 제공된 UI에서 AWS VPC와 관련된 모든 정보를 쉽게 탐색하고, 원하는 데이터를 시각적으로 확인할 수 있다.
- 내 VPC 목록 확인 및 구성요소 확인
- 내가 선택한 VPC의 다이어그램 제작
- 내가 선택한 VPC의 토폴로지 제작
AWS의 VPC 목록 및 요소 확인
VPC의 구조를 받아와 동적으로 그린 다이어그램
VPC 구조를 그리는 토폴로지
나의 경우
도커를 사용하였고, 프론트엔드 서버와 백엔드 서버를 각 분리해서 사용했다.
프론트의 경우 3000번 포트, 백엔드의 경우 5000번 포트에서 동작했다.
이로 인해 프론트와 백엔드 사이의 통신이 이루어지도록 하기 위해CORS설정을 해서 통신 문제를 해결했다.백엔드코드
app = Flask(__name__) CORS(app)
프론트엔드, package.json에 해당 코드를 추가했다.
"proxy": "http://backend:5000"
여담으로 테라폼 프로젝트로 만든 인프라가 프론트, 백엔드, DB가 서브넷을 모두 나누어뒀기에 그거에 맞추어 이 코드에 로그인, 게시판 기능을 추가할 까 했다. 결론은 시간 부족으로 인해 만들다가 다시 원래대로 복구했다.
그래서
JWT를 써서 로그인 정보를 쿠키에 저장하고, 서버에 안전하게 넘기기 위해credentials을 설정했었다. 하지만 시간 부족으로 인해 결국 모두 지웠다.
VPC의 구조를 그릴 때 퍼블릭 서브넷과 프라이빗 서브넷을 구분하는 방법은 가장 중요한 문제였다. Python으로 내 VPC 내부의 데이터를 받아오지만, 해당 데이터에는 서브넷이나 인스턴스가 퍼블릭인지 프라이빗인지 구분이 불가능하기 때문이다.
나의 경우 인터넷 게이트웨이의 연결 여부로 판단을 했다.
인터넷 게이트웨이가 연결이 되어있는 서브넷은 외부와 통신이 가능하다는 것이고 그것을 퍼블릭 서브넷으로 두었다.
cytoscape라는 모듈을 사용하여 해당 다이어그램 및 토폴로지를 그리는데에는 생각보다 어려움이 있었다.
큰 노드(VPC) 안에 작은 노드(서브넷, 인스턴스 등)을 넣어야하는데cytoscape는 내가 마우스를 통해 노드의 위치를 바꿀 수가 있었다. 그래서 마우스로 드래그를 하더라도 VPC안에 서브넷이나 AZ 등이 밖으로 나가지 않게 하기 위한 설정을 해야했다.
노드간의 부모 자식을 설정해서 서로의 위치 및 크기를 조절할 수 있었다.
부모 자식 코드 예시
elements.push({ data: { id: 'vpc', label: `VPC: ${topologyData.vpcName}`, parent: 'region' }, classes: 'vpc', position: { x: regionFixedX, y: regionFixedY + vpcToAzSpacing } });
적용 내용:
useEffect를 사용해 데이터가 로드된 후에만Cytoscape.js를 초기화하도록 설정했다.
useEffect내부에서 topologyData의 존재 여부를 확인하고, 데이터가 준비되지 않았을 때는return으로 초기화를 막았다.
의존성 배열에 topologyData와 regionName을 포함해 데이터 변경 시 그래프를 재렌더링하도록 구현했다.
적용 내용: 백엔드에서 필요 없는 데이터를 제외하고 필터링하거나, 데이터를 미리 정렬하여 프론트엔드에서 바로 사용할 수 있도록 처리했다.
예: 서브넷 데이터를 게이트웨이 연결 여부에 따라 정렬해 퍼블릭 서브넷과 프라이빗 서브넷을 구분하고, 이를 가용 영역(AZ)별로 배치했다. 또한, 루트 테이블과 인스턴스 데이터를 서브넷 하위에 포함시켜 계층 구조를 단순화했다.
적용 내용: AWS API 호출을 위해 필요한 IAM 권한을 추가로 설정했다.
VPC,Subnet,Instance등의 데이터를 호출하기 위해ec2:Describe등 VPC 읽기 권한을 IAM 계정에 부여했다.
boto3로 VPC의 정보들을 받아오는데 RDS의 정보도 받아오려고 했다. 하지만 아무리 코드를 수정해도 배열이 [] 이렇게 빈 배열만 반환되었다.
알고보니 RDS의 자체적 보안 기능(?) 그거 때문에 RDS의 정보를 읽어올 수 없던 것이다.
126 오류라고 "Permission denied"가 뜨면서 나의 프론트엔드 도커가 자꾸 종료가 되었다.
찾아보니 권한문제로 인해 생길 수 있는 문제라고 했다.
sudo docker compose up --build -d이 명령어를 실행했지만 여전히 똑같았다. 그래서 도커 그룹에 사용자를 추가했다
sudo usermod -aG docker $USER추가로 도커 bash에 접속하여 ENTRYPOINT의 권한을 변경했다.
chmod +x /app/start.sh그래도 안 되길래 도커를 삭제하고 다시 똑같은 설정을 하고 sudo로 실행하니 되었다. 왜 실행이 된 건지는 이유를 모르겠다.
npm start는 로컬 개발 환경에 최적화되어 있어 기본적으로HTTP만 지원하며,HTTPS요청을 처리하지 못한다.
HTTPS를 사용하려고 하면 다음 문제가 발생할 수 있다.SSL/TLS 인증서 미설정:
HTTPS는 인증서를 요구하지만,npm start는 인증서를 제공하지 않는다.도메인 미처리:
npm start는 기본적으로 localhost 또는 IP 주소에서만 동작하며, 도메인 요청을 처리하도록 설정되지 않는다.
이로 인해HTTPS연결이 실패하거나 브라우저에서 경고 메시지가 표시된다.
프론트에서 백엔드 API 호출을 하는게 경로를 잘못 설정해서 에러가 났다.
나의 경우 Terraform 프로젝트를 진행하며 해당 AWS 인스턴스에 코드를 배포하여 진행했는데, 그럴 경우 App.js의
fetch('/vpcs'와 같은 fetch 부분들을fetch('자신의백엔드api주소/vpcs'이렇게 바꾸면 된다.