
서버리스 어플리케이션에 관심이 있어서 AWS Builders Korea Program AWS Serverless 로 간단한 Web Application 만들기 (AWS Builders Korea) 트랙에 신청하였다.
서버리스 라고 해서 어려운 개념들도 수반될거 같았지만, AWS 솔루션 아키텍트 분께서 친절하게 강의를 해주셔서 별 문제없이 트랙을 마칠 수 있었다.
향후 AWS 서버리스 서비스나 프로젝트를 만들때 많은 도움이 될것같다.



import json
print('Loading function')
def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))
    print("value1 = " + event['key1'])
    print("value2 = " + event['key2'])
    print("value3 = " + event['key3'])
    return event['key1']  # Echo back the first key value
    #raise Exception('Something went wrong')
이벤트 작업 테스트 로 .json 파일을 넣어서 함수를 테스트 해볼 수 있다.
{
  "key1": "Hello!",
  "key2": "value2",
  "key3": "value3"
}

함수이름 : simple-webpage
런타임 : python 3.9
아키텍처 : x86_64
실행역할 : 기본 Lambda 권한을 가진 새 역할 생성



import json
def lambda_handler(event, context):
    response = {
        "statusCode": 200,
        "statusDescription": "200 OK",
        "Access-Control-Allow-Origin" : "*",
        "isBase64Encoded": False,
        "headers": {
            "Content-Type": "text/html; charset=utf-8"
        }
    }
    response['body'] = """<html>
    <head>
    <meta charset="utf-8" name="viewport" content="width=device-width, height=device-height, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <title>Hello World!</title>
    <style>
        #title {
            font-family: arial; font-size: 2em;color: #eb971a; margin-top:50px;
            text-align: center;
        }
        button {
                background-color: #eb971a;
                border:none;
                color:white;
                border-radius: 5px;
                width:40%;
                height:35px;
                font-size: 13pt;
                margin-top:30px;
                text-align: center;
        }
        #sentence {
                font-size: 17pt;
                margin-top:30px;
                font-weight: bold;
                color: #eb971a;
        }
    </style>
        </head>
        <body>
            <p id="title">Hello World From <b>Lambda</b></p>
            <hr id="lambda-line" width="800px" align="center" color="#eb971a;">
            <center><button>Who are you?</button></center>
            <center><div id="sentence"></div></center>
        </body>
        <script type="text/javascript">
        
            function checkEvent(){
                $.ajax({ type: "GET", 
                        url: "URL을입력하세요", 
                        dataType:'json',
                        success: function(data){ 
                        document.getElementById('sentence').innerHTML = data.status + "  " + data.name
                        }, 
                        error: function (error){
                        alert('ERROR::');
                        console.log(error)
                        }
                });
            }
        </script>
        </html>
            
        """
        
    return response


이전에는 Tomcat 설치하고 웹서버 설치하고 했어야함 5분만에 작업이 끝났다. 결국, 개발자는 코드에만 집중할 수 있다!!
html 페이지는 보통 S3에 올려놓고 서비스한다
페이지의 "Who are you?" 버튼을 누르면 에러를 뿜는다

function checkEvent(){
                $.ajax({ type: "GET", 
                        url: "URL을입력하세요", 
                        dataType:'json',
                        success: function(data){ 
                        document.getElementById('sentence').innerHTML = data.status + "  " + data.name
                        }, 
                        error: function (error){
                        alert('ERROR::');
                        console.log(error)
Who are you? 버튼의 이벤트에 GET 메서드 즉, API에서 데이터를 가져오는 코드가 있기 때문이고, 우리는 아직 API 를 구현하지 않았기 때문이다. 다음 과정에서 Lambda 로 API 를 만들고 Amazon API GateWay 로 생성한 API 엔드포인트 를 코드소스에 기입할 예정이다. 함수이름 : api-service-create
런타임 : python 3.9
아키텍처 : x86_64
권한 : AWS 정책 템플릿에서 새역할 생성
URL 생성은 딱히 필요 없다.


import json
import boto3
import random
import json
def lambda_handler(event, context):
    
    member_name = ['Ama','Jone','Zon','Penny','Jessie']
    member_status = ['Happy','Sad','Serious','Satisfied','Free']
    
    dynamodb = boto3.resource('dynamodb',endpoint_url='http://dynamodb.ap-northeast-2.amazonaws.com')
    member_table = dynamodb.Table('hello-member')
    
    name = member_name[random.randint(0,4)]
    status = member_status[random.randint(0, 4)]
    
    member_table.put_item(
       Item={
            'name': name,
            'status': status,
        }
    )
    
    documents = {'name':name,'status':status}
    
    print(documents)
    
    return {
        'statusCode': 200,
        'headers': {'Access-Control-Allow-Origin': '*'},
        'body': json.dumps(documents)
    }


put_item 메서드가 실행되지 않아 오류를 뿜는다 Test Event Name
my-api-test
Response
{
  "errorMessage": "An error occurred (ResourceNotFoundException) when calling the PutItem operation: Requested resource not found",
  "errorType": "ResourceNotFoundException",
  "requestId": "4e3aa377-881a-443b-b6b6-897a983d413a",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 17, in lambda_handler\n    member_table.put_item(\n",
    "  File \"/var/runtime/boto3/resources/factory.py\", line 580, in do_action\n    response = action(self, *args, **kwargs)\n",
    "  File \"/var/runtime/boto3/resources/action.py\", line 88, in __call__\n    response = getattr(parent.meta.client, operation_name)(*args, **params)\n",
    "  File \"/var/runtime/botocore/client.py\", line 530, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n",
    "  File \"/var/runtime/botocore/client.py\", line 960, in _make_api_call\n    raise error_class(parsed_response, operation_name)\n"
  ]
}
Function Logs
START RequestId: 4e3aa377-881a-443b-b6b6-897a983d413a Version: $LATEST
[ERROR] ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the PutItem operation: Requested resource not found
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 17, in lambda_handler
    member_table.put_item(
  File "/var/runtime/boto3/resources/factory.py", line 580, in do_action
    response = action(self, *args, **kwargs)
  File "/var/runtime/boto3/resources/action.py", line 88, in __call__
    response = getattr(parent.meta.client, operation_name)(*args, **params)
  File "/var/runtime/botocore/client.py", line 530, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 960, in _make_api_call
    raise error_class(parsed_response, operation_name)END RequestId: 4e3aa377-881a-443b-b6b6-897a983d413a
REPORT RequestId: 4e3aa377-881a-443b-b6b6-897a983d413a	Duration: 1545.42 ms	Billed Duration: 1546 ms	Memory Size: 128 MB	Max Memory Used: 69 MB	Init Duration: 249.72 ms
Request ID
4e3aa377-881a-443b-b6b6-897a983d413a
AWS 솔루션 아키텍트분이 말하길 Amazon DynamoDB는 DBA 가 필요고, 파티션 키에 대한 설정을 잘하면 누구나 쉽게 다룰 수 있다고 하셨다. 또한, 액세스 패턴이 정해져 있으면 성능이 매우 좋다고 한다.
테이블 이름 : hell-member
파티션 키 : name



프로토콜 : REST
새 API생성 : 새 API
API 이름 : my-api


통합 유형 : Lambda 함수
Lambda 프록시 통합 사용 : check
리전 : ap-northeast-2
Lambda 함수 : 이전에 생성했던 api-service-create





정말 강력하다 예전 Django 프로젝트중에 CORS 에러로 애를 많이 먹은적이 있었는데 클릭 한번으로 해결이 가능하다!!!




Invoke URL 이 생성되는데 기록해두자


그 전에 만들었던 simple-webpage function으로 접속
소스 코드를 들여다 보면 GET 메서드에 대해 EVENT 를 발생할 URL을 API Gate Way URL 을 입력








