aws 에서는 API Gateway 를 제공 한다.
이는 serverless 기반의 API 생성 및 운영을 손쉽게 할 수 있는 서비스 이다. (근데 손쉽지 않더라..)
물론 굉장히 난해 하고 어렵지만 처음 한걸음은 항상 어려 웠다 ‘ㅅ’a (이 산을 넘으면 devops 가 되는 첫걸음이 된다.)
위 이미지 생성은 클라우드크래프트 (https://cloudcraft.co/) 에서 진행 하였다. (AWS 아키텍쳐를 짜는데 매우 유용함.)
즉 restful API 를 AWS 상에서 API gateway 와 Lambda 서비스를 이용하여 구축 하여 운영하는 것이다.
이미 이와 같은 많은 글을 참고 하였으나 대부분 아마존에서 제공 하는 nodojs 를 활용하는 방법만 존재 하더라…
1. Lambda 에서 함수를 생성 한다.
2. 함수가 생성 되면 기본 설정에서 함수의 제한 등을 확인할 수 있다.
핸들러의 의미는 함수가 실행되었을때 lambda_function.py 한의 def lambda_handler() 를 실행한다는 의미가 된다.
(물론 편집도 된다. DB 접근 시간이 있기 때문에 제한시간을 10~15초로 늘린다.)
3. 스크롤을 올려 보면 AWS Cloud 9 IDE 의 간소화 버전을 이용하여 수정을 할 수 있다.
4. Test 버튼을 눌러 테스트 셋을 생성 한다. (이미지는 없음)
테스트를 위한 좀더 많은 json 은 https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/sample-apps/nodejs-apig/event.json 에서 확인할 수 있다.
1 2 3 4 |
{ "httpMethod": "GET", "queryStringParameters": { "nick-name": "Enteroa", "Locate": "인천" } } |
1 2 3 4 |
{ "httpMethod": "POST", "body": "{\"nick-name\":\"Enteroa\",\"Locate\":\"인천\"}" } |
다시 TEST 버튼를 눌러보면 실행 API Gateway 에 연결 되었을때 실행 후 결과 값이 확인 된다.
함수 생성이 완료 되었지만 Hello World 를 보려고 이것을 하는게 아니기 때문에 API의 근본 목적인 데이터베이스 접속을 할 차례이다 ‘ㅅ’a
배포용 코드 작성은 AWS cloud 9 IDE 를 통해 작성을 할 예정이다. (일반적인 linux 나 windows 환경에서도 가능하다.)
물론 Cloud 9 을 통해 lambda 배포가 가능하지만 단순 소스 작성을 위해서만 이용할 예정 이다 ‘ㅅ’a (이걸 하려면 또 Cloud Fomation 을 해야 하기 때문에…)
Lambda 에서는 일부 json, logging 등을 별다른 설정 없이 import 할 수 있지만 pymysql 과 같은 서버에 별도 설치가 필요한 부분은 같이 업로드가 되어야 한다.
때문에 아래와 같이 pymysql 설치를 한다.
1 2 3 4 |
~]$ mkdir -p pydbcon ~]$ cd pydbcon ~]$ pip install -t ./ pymysql ~]$ touch dbinfo.py lambda_function.py |
db 정보를 저장할 dbinfo.py 파일과 AWS lambda 핸들러에서 지정된 lambda_function.py 파일을 같이 생성 한다.
1 2 3 4 5 |
db_host = "mydb.ap-northeast-2.rds.amazonaws.com" db_username = "enteroa" db_password = "pa55w@RD" db_name = "enteroa" db_port = 3306 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import json import logging import pymysql import dbinfo log = logging.getLogger() log.setLevel(logging.INFO) db = pymysql.connect( host = rds_config.db_host, port = rds_config.db_port, db = rds_config.db_name, user = rds_config.db_username, password = rds_config.db_password, ssl = {'ca':rds_config.db_ssl_ca}, charset = "utf8" ) def lambda_handler(event, context): with db.cursor(pymysql.cursors.DictCursor) as cursor: if event['httpMethod'] == 'GET': bodydata = json.loads(json.dumps(event['queryStringParameters'])) response = { 'statusCode': 200, 'headers': { 'content-type': 'application/json; charset=utf-8' }, 'body': json.dumps(bodydata), 'isBase64Encoded': False } return response if event['httpMethod'] == 'POST': req_body_dict = json.loads(event['body']) cursor.execute('SELECT VERSION()') list1 = cursor.fetchall() for a in list1: req_body_dict['MariaDB-Version'] = a['VERSION()'] bodydata = req_body_dict response ={ 'statusCode': 200, 'headers': { 'content-type': 'application/json; charset=utf-8' }, 'body': json.dumps(bodydata), 'isBase64Encoded': False } return response db.close() |
위와 같이 작성을 하고 zip 파일로 압축을 한다.
1 2 3 4 5 6 7 8 |
~]$ ls PyMySQL-0.10.0.dist-info lambda_function.py pymysql dbinfo.py ~]$ zip -r lambda001.zip ./* adding: lambda_function.py (deflated 62%) adding: dbinfo.py (deflated 25%) adding: pymysql/ (stored 0%) adding: PyMySQL-0.10.0.dist-info/ (stored 0%) |
압출한 파일을 AWS 웹콘솔 에서 업로드 한다.
zip 파일이 압축 해제가 되며 lambda001 아래에 파일 및 폴더가 위치 할 수 있는데 아래와 같이 드래그 앤 드롭으로 맞추어 준다.
아니면 기본설정-핸들러를 lambda_function.lambda001.lambda_handler 으로 바꾸어도 될꺼 같기도 하다 ‘ㅅ’a
데이터베이스의 경우 보안 때문에 IP를 막고 일부만 열어서 서비스 하는것이 일반적이기 때문에 실행하는 람다를 VPC 내에서 실행 되게 해야 한다.
그래서 생성한 lambda 함수가 자신의 VPC 에서 네트워크 인터페이스를 사용할 수 있는 권한을 주어야 한다.
화면 최상단의 권한 으로 이동하고 실행 역할(IAM role) 을 눌러 해당 정책에 정책 추가를 진행해야 한다.
아래의 권한으로 정책을 새롭게 생성해서 연결 해도 되고 인라인 정책 추가를 해도 된다.
추후 생성되는 Lambda 함수는 권한 부분에서 기존 역할로 이미 VPC 권한이 부여된 역할을 선택 해주면 좀더 편하게 사용할 수 있겠다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "ec2:CreateNetworkInterface", "ec2:DescribeInstances", "ec2:DescribeNetworkInterfaces", "ec2:DeleteNetworkInterface", "ec2:AttachNetworkInterface" ], "Resource": "*" } ] } |
lambda 실행될 VPC 에 대한 정보를 설정해 주어야 한다.
사용자 지정 VPC 지정과 VPC 지정 subnet 지정(2개 이상) 과 EC2보안그룹을 지정 하면 된다.
그리고 RDS 서버의 보안그룹에서 위에서 lambda 가 사용할 것으로 지정된 두개의 서브넷(172.31.0.0/20, 172.31.16.0/20)을 허용한다.
테스트를 달려 본다.
앗싸 가오리!
너무 길어져서 API 게이트웨이는 나중에 추가 할 예정이다 =_=a
팔로우 할때 주의 할점은 API 게이트 웨이의 리소스 > 메소드 에서 “통합 요청”의 유형이 LAMBDA 가 아닌 LAMBDA_PROXY 으로 해야 하는 python 코드 이다.