[TIL] 22.05.27

진이진이·2022년 5월 27일
1

TIL

목록 보기
25/74
post-thumbnail
post-custom-banner

오늘 한 일

  • 서버리스 백엔드
  • Weekly 타임어택

🎈Lambda란?

서버를 프로비저닝하거나 관리하지 않고도 코드를 실행할 수 있게 해주는 컴퓨팅 서비스로써 S3처럼 백엔드를 서버리스(Serverless)로 운영할 수 있는 서비스이다.
Lambda는 Lambda Function이라고 불리는데 기본적으로 하나의 함수를 실행한다.

  • Lambda 의 장점

  1. 비용절감 - 필요할때만 함수가 호출되고 비용이 부과되는 방식 ( 최대 34% 더 나은 가격 대비 성능 )
  2. 인프라 관리 부담의 효율 - 관리 할 필요 X
  3. 빠르게 백엔드를 구성 가능
  • Lambda 의 단점

  1. 리소스 제한 - 메모리(최대 10GB), 처리시간(최대 900초, 15분)
  2. Cold Start - 오랫만에 실행하게 되면 딜레이가 발생한다.
  3. 동시성 제약 - 동시에 처리할 수 있는 요청의 수가 리전별로 1000개로 제한되어 있다.

Lambda로 데이터베이스에 데이터 저장하기

1. Lambda 생성

  • AWS에서 Lambda함수를 생성
    함수이름 과 런타임 ( Python 3.9 ) 최신버전으로 설정

  • 생성된 코드 테스트해보기

  • 코드 테스트 설정

2. API Gateway 적용

API Gateway란?

API Gateway는 HTTP 통신을 할 수 있게 HTTP URL, METHOD(GET, POST..)
를 만들어주어 API 엔드 포인트 역할

  • 트리거 추가하기 ( API Gateway )
    트리거 구성 : API 생성 ▶ REST API ▶ 보안(열기) ▶ 이전 미디어 형식 : multipart/form-data ▶ 생성

  • API Gateway 확인

  • API 배포

3. RDS 생성

  • 보안그룹 생성
    EC2 보안그룹 ▶ 보안그룹 이름 설정 ▶ 인바운드 규칙 추가 ( TCP , 3306 , 0.0.0.0/0 )

  • RDS 생성
    RDS 데이터베이스 ▶ MYSQL ▶ 사용자이름, 마스터암호 ▶ 퍼블릭엑세스 허용 ▶
    기본VPC 보안그룹 ( EC2 보안그룹 ) ▶ 가용 영역 설정

  • 스키마, 테이블 생성
    RDS 데이터베이스의 엔드포인트를 호스트에 입력,
    유저정보는 RDS 데이터베이스 설정 값

  • DB 생성

  • 테이블 생성
    Columns : idx ( int ), title ( varchar 100 ), content ( text)
    Constraints : idx값 체크 ▶ 아래쪽 save ▶ persist

  • 파이참 프로젝트 만들기

    pip install --target ./python pymysql
  • python 폴더에 lambda_function.py 추가

    import json
    import pymysql
    
    def db_ops():
        try:
            connection = pymysql.connect(
                host=' 엔드 포인트 ',                        # 엔드 포인트 값
                user='admin',
                password='RDS password',                    # RDS password
                db='mydb',
                charset='utf8mb4',
                cursorclass=pymysql.cursors.DictCursor
            )
    
        except pymysql.MySQLError as e:
            print("connection error!!")
            return e
    
        print("connection ok!!")
        return connection
    
    def lambda_handler(event, context):
        body = json.loads(event['body'])
        conn = db_ops()
        cursor = conn.cursor()
        cursor.execute("insert into 테이블 이름(title, content) value('" + body['title'] + "', '" + body['content'] + "')")
        conn.commit()
    
        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": "success",
            }),
        }
  • 파일 압축

  • 파일 업로드

4. Postman 사용하기

Postman 이란?

프론트엔드와 상관없이 순수하게 API만을 테스트 할 때 사용하는 도구

  • Creat workspace

    {
       "title":"람다 테스트",
       "content":"람다 테스트"
    }
  • 데이터베이스 확인

Secrets Manager 사용하기

Secrets Manager란?

보안상 중요한 정보를 저장할 수 있는 서비스

  • Secrets Manager 생성하기
    AWS Secrets Manager 보안 암호 ▶ RDS 데이터베이스

  • 정책 추가하기
    Lambda 구성 ( 권한 ) ▶ IAM 역할 권한추가 ▶ SecretsManagerReadWrite 정책 연결

  • 코드 추가

    import json
    import boto3
    import pymysql
    
    def get_secret():
        session = boto3.session.Session()
        client = session.client(
            service_name='secretsmanager',
            region_name="ap-northeast-2"
        )
        get_secret_value_response = client.get_secret_value(
            SecretId='rds-secret-01'
        )
        token = get_secret_value_response['SecretString']
        return eval(token)
    
    def db_ops():
        secrets = get_secret()
        try:
            connection = pymysql.connect(
                host=secrets['host'],
                user=secrets['username'],
                password=secrets['password'],
                db='mydb',
                charset='utf8mb4',
                cursorclass=pymysql.cursors.DictCursor
            )
    
        except pymysql.MySQLError as e:
            print("connection error!!")
            return e
    
        print("connection ok!!")
        return connection
    
    def lambda_handler(event, context):
        body = json.loads(event['body'])
        conn = db_ops()
        cursor = conn.cursor()
        cursor.execute("insert into 테이블 값(title, content) value('" + body['title'] + "', '" + body['content'] + "')")
        conn.commit()
    
        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": "success",
            }),
        }
  • Secrets Manager 교체 구성
    교체 구성 수정 ( 자동 교체 구성, 교체 함수 ) ▶ Lambda 함수 확인 ▶ 암호 확인 ▶ API 테스트 ▶ 로컬에서 접속 & 암호변경 ( 보안 암호 값 )

VPC 구성하기

VPC ( Amazon Virtual Private Cloud ) 란?

가상 네트워크로 AWS의 확장 가능한 인프라를 사용한다는 이점과 함께 고객의 자체 데이터 센터에서 운영하는 기존 네트워크와 매우 유사

  • Lambda VPC 추가
    보안그룹 만들기 ( 보안그룹 이름 ,아웃바운드 ) ▶ 실행권한 추가 ( AmazonVPCFullAccess 정책 연결 ) ▶ 구성 > VPC 추가, 편집 ( 서브넷, 보안그룹 )

외부 통신이 안되는 이유

외부통신을 하기 위해서는 지정한 서브넷에 NAT 게이트웨이를 설정해 주어야 한다.

NAT 게이트웨이 구성하기

  • Inbound vs OutBound

  • 퍼블릭 서브넷 vs 프라이빗 서브넷

    퍼블릭 서브넷 : 인터넷 게이트웨이에 연결되어 있는 서브넷
    프라이빗 서브넷 : 연결이 되지 않은 서브넷

  • NAT 게이트웨이 만들기

  1. VPC 라우팅테이블 서브넷 연결 편집 ( 사용할 퍼블릭 서브넷 제외하고 3개 서브넷 연결 저장 )
  2. NAT 게이트웨이 ( PUBLIC ) 으로 생성 ▶ 탄력적 IP 할당
  3. 라우팅테이블 생성
  4. 라우팅테이블 NAT 게이트웨이 연결 ( 라우팅 편집 ▶ 0.0.0.0/0 추가 )
  5. 서브넷 연결
    서브넷 연결 ▶ 프라이빗 서브넷 선택 후 연결 저장 ▶
  • 코드 추가

    import json
    import boto3
    import pymysql
    
    def get_secret():
        session = boto3.session.Session()
        client = session.client(
            service_name='secretsmanager',
            region_name="ap-northeast-2"
        )
        get_secret_value_response = client.get_secret_value(
            SecretId='rds-secret-01'
        )
        token = get_secret_value_response['SecretString']
        return eval(token)
    
    def db_ops():
        secrets = get_secret()
        try:
            connection = pymysql.connect(
                host=secrets['host'],
                user=secrets['username'],
                password=secrets['password'],
                db='mydb',
                charset='utf8mb4',
                cursorclass=pymysql.cursors.DictCursor
            )
    
        except pymysql.MySQLError as e:
            print("connection error!!")
            return e
    
        print("connection ok!!")
        return connection
    
    def lambda_handler(event, context):
        body = json.loads(event['body'])
        conn = db_ops()
        cursor = conn.cursor()
        cursor.execute("insert into board(title, content) value('" + body['title'] + "', '" + body['content'] + "')")
        conn.commit()
    
        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": "success",
            }),
        }
  • 데이터 확인

profile
개발 어린이
post-custom-banner

0개의 댓글