AWS Lambda와 RDS 연동하기

2019. 4. 9. 19:10개발을 파헤치다/서버 인프라

반응형

이번에는 RDS에 접근하여 데이터를 수정하는 AWS Lamda 함수를 구현해봅니다.

 

구현에 앞서 구현 환경은 아래와 같습니다.

 

  • RDS : PostgreSQL 10.6

  • Lambda 함수 : Python으로 구현

  • IDE : IntelliJ PyCharm

 

AWS Lambda를 활용하여 PostgreSQL 인스턴스가 운영되고 있는 RDS DB 서버에서 데이터를 조작하기 위해서는 psycopg2라는 라이브러리가 필요합니다.

 

Psycopg2는 PostgreSQL에 접근하여 데이터 조작을 하기 위해 사용되는 라이브러리인 libpq를 Python에서 사용할 수 있도록 만든 라이브러리입니다.

libpq는 C로 만들어진 라이브러이이고 psycopg2는 이 C로 만들어진 라이브러리를 Python에서 사용할 수 있도록 만든 C Wrapper 라이브러이인 것입니다.

 

이를 정상적으로 사용하려면 운영체제 환경에 libpq의 헤더 파일들이 필요한데 이는 libpq-dev라는 패키지에 포함되어 있습니다.

 

우리가 Lambda 함수에 들어갈 코드를 Zip 파일로 압축하여 업로드하게 되면 이벤트 트리거에 의해 코드가 실행됩니다.

 

이 Lambda 함수는 Amazon 클라우드의 OS Container 위에서 구동됩니다. 이때 이 OS Container는 AMI(Amazon Machine Image)를 기반으로 하죠. 이 이미지가 곧 OS 환경이 되기 때문에 해당 이미지에 앞서 얘기한 libpq-dev 패키지가 있어야만 psycopg2 라이브러리가 정상적으로 동작하게 됩니다.

 

따라서,  psycopg2를 이용하여 구현한 코드를 AWS Lambda에서 구동하면 아래와 같은 에러를 맞이하게 됩니다.

 

No Module Name : psycopg2

 

위의 문제를 해결하기 위해 누군가가 필요한 헤더들을 포함하여 컴파일된 psycopg2 라이브러리를 만들어 놓았습니다.

 

python2와 3을 모두 지원하며 제공된 라이브러리를 다운받아 럼더 풇잭투애 복붙한 다음, Zip 파일로 만들면 정상 작동 합니다.

 

python 3.6을 사용하는 경우를 예로 들면

 

 

위와 같이 Lambda 프로젝트 디렉토리에 psycopg2-3.6 디렉토리를 붙여넣은 다음 이름만 psycopg2로 바꿔주면 됩니다.

 

 

 

이제 아래와 같이 Lambda에서 동작할 함수를 구현합니다.

 

"""
    RDS에 접근하여 데이터를 조작하는 코드
"""
import os
import psycopg2

def handler(event, context):

    try:
        db_name = 'example_db'
        db_user = 'root'
        db_pass = 'password'
        db_host = 'your_rds_domain'
        db_port = 5432      # PostgreSQL Default Port Number
        
        sql = 'UPDATE user SET name=%s, nickname=%s WHERE id=%s'
        name = 'example_name'
        nickname = 'example_nickname'
        id = 12
        
        # RDS에 연결을 시도합니다
        conn = psycopg2.connect("dbname='%s' user='%s' host='%s' password='%s'" % (db_name, db_user, db_host, db_pass))
        cursor = conn.cursor()
        
        # Mogrify를 활용하면 실제로 수행되는 쿼리를 확인할 수 있습니다
        print(cursor.mogrify(sql, (name, nickname, id,)))
        
        # 쿼리를 실행합니다
        cursor.execute(sql, (name, nickname, id,))
        
        # 커밋을 하지 않으면 데이터베이스에 실제로 적용이 되지 않습니다
        conn.commit()
    except Exception as e:
        print(e)

반응형