개요
이번에 SMS 및 카카오톡 알림톡을 보내는 로직을 커스텀해서 프론트에 API를 제공하는 작업을 하게 되었다. 이 때 '알리고' 라는 서비스를 사용하게 되었는데, 여기서 아이피주소 화이트리스트 (특정한 IP 주소에서 보낸 요청에만 응답하는 것) 를 기본적으로 적용하고 있고, 현재 API 서버와 결합해야 하지만 outbound를 고정하기 힘들고 범용성을 가져야 하는 특정 때문에 Lambda로 제작하기로 했다.
목표
lambda를 사용해서 '알리고'의 API를 사용해 메시지를 보내자. 단, outbound IP 주소는 항상 고정이여야 한다.
구상
글 맨 밑의 참고자료에서 사진을 가져왔다.
간단히 아키텍쳐에 대한 정리를 해 볼려고 한다. 정리 전에 간단한 용어 정리부터 하려고 한다.
VPC: 가상 사설 네트워크이다.
NAT Gateway: 프라이빗 서브넷에 있는 서버를 외부에 접속하게 할 수 있으면서 외부에서는 프라이빗 서브넷으로의 접근을 차단하게 하는 인스턴스이다
서브넷 : VPC 안에서 IP 주소를 나누는 그물 같은 것이다. 이를 이용해서 각 인스턴스마다 그룹별로 설정을 다르게 적용할 수 있다.
우리의 목표는 람다가 고정 아이피를 통해 외부로 통신하는 것을 목표로 한다. 이 때 고정되어 있는 아이피를 연결해 주는 것이 필요한데, 이 때 적용할 것이 프라이빗 인스턴스를 외부 인터넷에 접속할 수 있게 하는 설계를 이용하려고 한다. 위의 그림에서 Database Server 대신 람다 API gateway가 들어있다고 생각하면 편하다.
먼저 람다에서 인터넷에 접속하는 순서는 다음과 같다.
- 람다 함수 호출
- api gateway
- 프라이빗 서브넷
- nat gateway
- 라우터 (라우팅 테이블에 의한 규칙)
- 인터넷 게이트웨이
해당 작업을 위에서 그림으로 나타내었는데, 여기서 Database Server는 외부에서 접근이 불가능하게 프라이빗 서브넷에 할당했다. 하지만 DB의 펌웨어 업데이트 등의 작업이 있을 경우에는 외부 인터넷에 연결해야 한다. 이 때 사용되는 것이 퍼블릭 서브넷에 있는 NAT Gateway이다. 그래서 그림처럼 Database Server에서 바로 라우터로 가는게 아닌, NAT Gateway를 경유하는 것으로 그림이 살짝 바뀌어야 할것 같다.
Main route table의 설명을 해석해보자. 해당 VPC 내의 아이피 주소를 요청하는 경우에는 local(VPC)로 트래픽을 보내고, 그 이외의 트래픽에 대해서는 모드 nat gateway로 트래픽을 보낸다. Custom route table은 내부 아이피 주소를 요청하는 경우에도 local로 트래픽을 보내고, 그 이외의 트래픽에 대해서는 인터넷 게이트웨이로 요청을 보내게 된다.
해당 플로우를 모두 설명했으니, 빠르게 설정을 해보자.
먼저 VPC를 제작하고, 인터넷 게이트웨이를 새로 생성하여 연결한다. 그 다음 서브넷을 생성한다. 서브넷을 생성할 때 퍼블릭 서브넷, 프라이빗 서브넷을 따로 만들어 준다.
이후에 nat gateway를 생성한 후, 퍼블릭 서브넷으로 연결해 준다. 퍼블릭 서브넷으로 연결하는 이유는 외부 네트워크와 연결하기 위해서이다! 여기에다 탄력적 IP를 할당한다. 왜냐하면 이 작업의 목적은 외부에서 고정된 IP 요청을 필요로 하기 때문이다.
이제 각각의 서브넷에 대해서 라우팅 테이블을 설정해 주어야 한다. 라우팅 테이블 설정은 위의 그림과 똑같이 따라하면 된다. (Destination 아이피 주소는 VPC의 대역폭과 맞추면 된다. 라우팅 테이블은 각각의 서브넷과 연결해야 하기 때문에, 각각의 서브넷에 올바를 라우팅 테이블이 연결되어 있는지 꼭 확인해야 한다.)
연결이 잘 되었는지 확인하기 위해서는, VPC - 네트워크 분석 - Reachability Analyzer를 사용하면 된다.
네트워크 구성이 성공적이라면, 연결이 잘 되었다고 뜬다!
마지막으로 람다 함수와 프라이빗 서브넷을 연결한다! 나의 경우에는 serverless.yml 설정에 포함시켜서 다른 설정 없이 바로 연결이 되었다. 수동으로 하려면 API 게이트웨이 - vpc 메뉴에서 해당 vpc, 서브넷, 보안 그룹과 같이 연결한다. 만약 권한이 없다고 하면 람다 역할에 AWSLambdaVPCAccessExecutionRole을 추가한다. serverless.yml에는 다음과 같이 표기를 했다.
service: sms-api
frameworkVersion: "3"
plugins:
- serverless-plugin-typescript
- serverless-offline
- serverless-vpc-plugin
provider:
name: aws
runtime: nodejs16.x
region: ap-northeast-2
vpc:
securityGroupIds:
- 보안그룹
subnetIds:
- 서브넷
custom:
vpcConfig:
enabled: false
vpc가 이미 만들어져 있다면 연결만 해 주고, 생성을 해야 한다면 아래에 있는 설명서를 읽고 실행해 봐도 좋을 거 같다. 개인적인 추천은 네트워크 설정은 직접 하고, 람다와 VPC만 연결해주면 될 것 같다.
비용에 관하여
NAT 게이트웨이는 인스턴스 기반의 서비스이기 때문에 한국 리전 기준 시간당 0.059 달러가 들어간다. 또한 고정 IP를 사용했기 때문에 이에 대한 비용도 따로 들어간다. (현재 나는 1개 이상의 고정IP를 사용하기 때문, 1개만 쓰고 있다면 과금 안됨) 나의 경우에는 NAT 인스턴스를 사용할 수도 있으나, 나의 경우에는 실제 프로덕션 서비스이기 때문에 아마존에서 자체 관리하는 NAT 게이트웨이를 사용하기로 했다.
참고자료
https://gompro.postype.com/post/1642377
https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/VPC_Scenario2.html
https://www.serverless.com/plugins/serverless-vpc-plugin
'서버 인프라 > Aws' 카테고리의 다른 글
AWS Chatbot으로 서버 상태 모니터링하기 (0) | 2022.09.05 |
---|---|
Kinesis 관련 내용 정리하기 (0) | 2022.08.18 |
서버 상태 Lambda와 Slack으로 실시간 확인하기 (6) | 2022.07.27 |
AWS Amplify를 이용하여 기존의 react app 배포하기 (0) | 2022.07.13 |
Typescript를 이용한 어플리케이션 Lambda에 배포하기 (0) | 2022.06.15 |