[TIL] 22.05.31

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

TIL

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

오늘 한 일

  • 서버리스 배포자동화
  • 거북이반 자바 강의

🎈SAM 이란?

Serverless Application Model의 약자로 Lambda를 좀 더 잘 관리할 수 있고 빌드하는 데 사용할 수 있는 오픈 소스 프레임워크

  • 준비 ( Window 기준 )

  1. SAM 설치
    https://github.com/aws/aws-sam-cli/releases/latest/download/AWS_SAM_CLI_64_PY3.msi

  2. SAM 확인
    sam --version

  3. AWS-CLI 설치
    https://awscli.amazonaws.com/AWSCLIV2.msi

  4. AWS-CLI 설치 확인
    aws --version

  5. AWS 사용자 생성

    IAM 사용자 생성 ▶ 사용자 추가 ▶ 권한 설정 ( 기존 정책 연결 : AdministratorAccess )   ▶ 액세스 키, 비밀 액세스 키 기억하기
  6. 로컬 AWS-CLI 키 등록
    aws configure

  7. python 설치
    람다함수가 python 3.(6,7,8,9)라서 로컬을 맞춰야 한다.

  • SAM 사용하기

  1. SAM 프로젝트 만들기( 경로는 영어로 )
    sam init

  2. 빌드 및 배포
    빌드
    sam build
    배포
    sam deploy --guided

    ❗❗❗빌드에서 발생한 에러❗❗❗

    sam build --debug로 에러가 어디 발생했는지 확인

    이유 : 파일이 위치한 곳의 경로에 한글이 있다.
    해결 : Packager.py 의 코드를 바꿔주었다.
    stdout = out.decode() ▶ stdout = out.decode('iso8859_2')

    Packager.py 경로!!!

    1.메모장 관리자 권한으로 실행 ▶ 2.c드라이브 ▶ 3.Program Files ▶ 4.Amazon ▶ 5.AWSSAMCLI ▶ 6.runtime ▶ 7.lib ▶ 8.site-packages ▶ 9.aws_lambda_buliders ▶ 
    10.workflows ▶ 11.python_pip

    결과 : 잘 접속된다.

  • SAM 배포 과정 중 생성된 리소스

    1. 애플리케이션 2. CloudFormation 3. S3 Bucket 4. API Gateway 5. Lambda
    생성된 인프라 : IaC(Infrastructure as Code) 개념을 SAM 프레임워크를 통하여 적용

  • API 추가

  1. bbs_write 파일을 만들고 __init__.py 생성, requirements.txt파일에 pymysql 추가

  2. vpc 설정은 생략한다

  3. Secret Manager 실행 권한 추가

  • 사용한 .yaml 코드

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
    Description: >
      sam-bbs
    
      Sample SAM Template for sam-bbs
    
    # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
    Globals:
      Function:
        Timeout: 3
        Tracing: Active
    
    Resources:
      HelloWorldFunction:
        Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
        Properties:
          CodeUri: hello_world/
          Handler: app.lambda_handler
          Runtime: python3.9
          Architectures:
            - x86_64
          Events:
            HelloWorld:
              Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
              Properties:
                Path: /hello
                Method: get
      TestWorldFunction:
        Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
        Properties:
          CodeUri: test_world/
          Handler: app.lambda_handler
          Runtime: python3.9
          Events:
            TestWorld:
              Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
              Properties:
                Path: /test
                Method: get
      BbsWriteFunction:
        Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
        Properties:
          CodeUri: bbs_write/
          Handler: app.lambda_handler
          Runtime: python3.9
          Events:
            BbsWrite:
              Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
              Properties:
                Path: /write
                Method: post
          Policies:
            - Statement:
                - Sid: AWSSecretsManagerGetSecretValuePolicy
                  Effect: Allow
                  Action: secretsmanager:GetSecretValue
                  Resource: 리소스값 추가 ( 보안암호 ARN )
    
    Outputs:
      # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
      # Find out more about other implicit resources you can reference within SAM
      # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
      HelloWorldApi:
        Description: "API Gateway endpoint URL for Prod stage for Hello World function"
        Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
      HelloWorldFunction:
        Description: "Hello World Lambda Function ARN"
        Value: !GetAtt HelloWorldFunction.Arn
      HelloWorldFunctionIamRole:
        Description: "Implicit IAM Role created for Hello World function"
        Value: !GetAtt HelloWorldFunctionRole.Arn
  • 사용한 파이썬 코드

    import json
    import boto3
    import pymysql
    from datetime import date
    
    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-02'
        )
        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):
        conn = db_ops()
        cursor = conn.cursor()
    
        try:
            if event['httpMethod'] == 'OPTIONS':
                body = json.dumps({
                    "message": "success",
                })
            else:
                today = date.today()
                body = json.loads(event['body'])
                cursor = conn.cursor()
                cursor.execute("insert into bbs(title, content, regDate) value('" + body['title'] + "', '" + body['content'] + "', '" + today.strftime("%Y%m%d") + "')")
                conn.commit()
                body = json.dumps({
                    "message": "success",
                })
    
            return {
                "statusCode": 200,
                # Cross Origin처리
                'headers': {
                    'Access-Control-Allow-Headers': 'Content-Type',
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Methods': 'OPTIONS,POST'
                },
                "body": body,
            }
        except Exception as e:
            print(e)
            return {
                "statusCode": 500,
                # Cross Origin처리
                'headers': {
                    'Access-Control-Allow-Headers': 'Content-Type',
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Methods': 'OPTIONS,POST'
                },
                "body": json.dumps({
                    "message": "fail",
                }),
            }
  1. postman으로 테스트 해보기 postman 사용하기 설명

    ❗❗❗Post man에서 발생한 에러❗❗❗

    아직 에러를 해결하지 못함...
  • 생각해본 해결 방법

  1. 하나하나 에러 확인하면서 적용해보기

  2. 갈아엎기

    선택 : 갈아엎기!!!!!! 이보다 좋은 방법은 없는 것 같다. 어차피 앞으로 개발자 인생을 살기 위해선 내 계정명을 영어로 바꿀 필요가 있다.
    참고할 블로그
    리라님의 블로그 : 계정명 영어로 바꾸기

    갈 길이 멀다... 근데 에러?? 난 즐긴다.

profile
개발 어린이
post-custom-banner

4개의 댓글

comment-user-thumbnail
2022년 5월 31일

마지막 줄 핵멋잇네여 👍

답글 달기
comment-user-thumbnail
2022년 5월 31일

에러를 즐길줄 아시는군요 ..키야~

답글 달기
comment-user-thumbnail
2022년 5월 31일

에러?? 난 즐긴다

답글 달기
comment-user-thumbnail
2022년 6월 2일

에러? 오히려 좋아.

답글 달기