-
Lamda로 서로 다른 vpc에 있는 redshift에서 rds로 reverse ETL하기 (VPC peering)Data Engineering/AWS, Spark 2023. 5. 9. 00:32728x90반응형
AWS에서 작업을 하다보면 항상 가장 힘든게 네트워크 설정인 것 같다. 오늘은 Lamda로 서로 다른 private subnet에 있는 redshift에서 rds로 reverse ETL 파이프라인을 구성했던 방법을 기록해보려한다.
기본적으로 Lambda는 public network에 위치하고, private network로는 접근할 수 없다. 따라서 lamda에서 RDS나 redshift에 접근하기 위해서는 Lamda 함수를 생성한 후, 해당 함수의 configuration에서 접근하고자하는 VPC와 subnet, 그리고 보안그룹을 선택해서 람다가 해당 private network에 위치하도록 해주어야한다. 하지만 이렇게 했을 때 문제점은, Lamda가 특정 private subnet에 들어가기 때문에 다른 VPC의 private network와 소통할 수 없다는 점이다. 이를 해결하기 위해 VPC peering을 해주어야한다. (만약 Lamda가 Redshift나 RDS 둘 중 하나에만 access한다면 그냥 설정값에서 VPC를 넣어주기만 해도 된다.)
VPC peering
VPC peering은 private한 IP를 사용하여 두 VPC간의 트래픽을 라우팅하는 네트워크 연결이다. Public network를 타지 않기 때문에 데이터 보안에도 안전하다. 리전이나 다른 계정 간 VPC peering도 가능하고, peering자체에는 요금이 부과되지 않으며 데이터 전송시에 요금이 부과된다.
방법
위의 공식문서에 나와있는 순서를 하나씩 따라하면 된다.
- AWS의 VPC 콘솔에 peering connection 탭에 들어가서 create peering connection을 클릭한다.
- Requester VPC에는 연결을 요청할 VPC를, another VPC에는 연결을 받을 VPC를 선택한다. 나의 경우 redshift에 lambda를 위치시키고 RDS로 데이터를 보낼 예정이었으므로 requester VPC는 redshift VPC를, 연결을 받을 vpc는 RDS VPC를 선택했다.
- Peering connection을 생성하면 pending acceptance상태로 connection이 생성된다. 해당 connection을 클릭하고 action을 눌러서 accept request를 해주면 상태가 active로 변한다.
- 해당 connection을 선택한 후 DNS 탭으로 들어가서 DNS 확인 기능을 활성화 시켜준다 (Edit DNS settings > Enable 클릭). Private subnet끼리의 networking을 해야하므로 해당 과정이 꼭 필요하다.
- 이제 트래픽을 라우팅 해주기 위해 라우트 테이블을 업데이트 해 주어야 한다. 각 VPC를 클릭하면 VPC에 연결되어있는 route table을 볼 수 있다. 해당 라우트 테이블에 들어가준다.
- 라우트 테이블 콘솔에서 routes 탭으로 가서 Edit routes 버튼을 클릭한다.
- 라우트 편집 창이 뜨면 Add route를 클릭해서 서로의 VPC를 등록해준다.
- RDS 라우트 테이블에는 Destination에 redshift의 CIDR주소를 등록해주고, Target에 아까 생성했던 peering connection을 선택해준다.
- Redshift 라우트 테이블에는 Destination에 RDS database의 CIDR주소를 등록해주고 Target에 아까 생성했던 peering connection을 선택해준다.
- 각 VPC의 CIDR 주소는 VPC 콘솔에서 볼 수 있다 (IPv4 CIDR 부분)
- 이제 inbound와 outbound를 열어주어야한다. 각 클러스터가 연결되어 있는 보안그룹에 들어가서 서로의 보안그룹에 대한 traffic을 허용해준다.
- Redshift의 보안그룹에는 type redshift, protocol TCP, source RDS의 보안그룹 번호를 넣어준다.
- RDS의 보안그룹에는 type mysql, protocol TCP, source Redshift의 보안그룹 번호를 넣어준다.
- source에 보안그룹 검색할 때 드롭다운에 안 뜨는데, 그냥 수동으로 적고 저장하면 연결된다 (안 떠서 안되는 줄 알았다..).
이렇게 하면 VPC peering은 끝이다.
Glue connection 설정
Lambda에서 redshift와 RDS를 glue connection을 통해 접근할 예정이었기 때문에 glue connection을 생성해주었다.
- Glue > Data Catalog > Connections 콘솔에 들어간다.
- Create connection을 클릭해 redshift와 RDS connection을 생성한다.
- Connection type에는 각각 Amazon RDS, JDBC를 선택한다.
- Connection access에 DB 접속 정보를 입력한다. Redshift의 경우 jdbc url을 넣으면 된다.
- Network option에 VPC, subnet, security group을 입력한다. Security group은 해당 클러스터가 연결되어있는 보안 그룹을 사용해도 되고, 새로 생성한 후 해당 보안그룹을 클러스터에 연결해도 되나 중요한건 inbound에 자기참조로 all traffic이 열려있어야한다.
- 생성 후 해당 connection을 선택해서 actions > Test connection을 통해 연결이 잘 되는지 확인한다.
Lamda 설정
- 람다 함수를 생성한다. Redshift와 RDS는 awswrangler를 통해 connect할 수 있다. 코드는 대략적으로 아래와 같다.
- awswrangler 라이브러리를 사용하기 위해 lambda layer를 추가해준다. arn은 다음과 같다 (Python 3.9 기준)
- arn:aws:lambda:ap-northeast-1:336392948345:layer:AWSSDKPandas-Python39:6
- Configuration > VPC 탭에 들어가서 Lambda를 redshift VPC에 위치하도록 설정해준다.
- 데이터를 가져오기 충분한 값으로 General configuration > Memory와 Timeout을 설정해준다.
import awswrangler as wr def lambda_handler(event, context): conn = wr.redshift.connect("glue에서 생성한 redshift jdbc connection 이름") with conn.cursor() as cur: cur.execute(extract_query) rec = cur.fetchall() conn.close() conn = wr.mysql.connect("glue에서 생성한 RDS connection 이름") with conn.cursor() as cur: cur.execute(inerst_query) conn.commit() conn.close() return None
전체적으로 그렇게 어렵지 않은 과정인데 몇 일 동안 삽질한 이유는
- 람다에서 VPC configuration이 람다 함수를 해당 VPC에 위치시켜주는게 아니라 VPC에 대한 접근을 허용해주는 건줄 알고 peering이랑 보안 그룹을 lambda함수로 허용하는 오류를 범했고,
- private network에서 작동시키기 위해서는 peering connection에서 DNS 확인 기능을 허용해줘야하는 걸 몰랐다.
그래서 몇 일 동안 왜 로컬에서는 되는데 람다에선 안되냐며 컴퓨터와 싸웠던 시간이었다.
네트워크는 참 어렵고, 클라우드도 어려운데 클라우드의 네트워크는 더 어렵다. EKS할 때 지옥이었다...
참고로 작업하면서 AWS의 네트워크에 대해 조금 더 이해할 수 있었던 포스팅을 첨부한다.
728x90반응형'Data Engineering > AWS, Spark' 카테고리의 다른 글