AWS

AWS Serverless(서버리스)로 서버 고민 없이 웹 애플리케이션 구축하기 #2

묠니르묘묘 2024. 9. 9. 23:50

 

1편에서 봤듯이 "친구들의 기분 상태를 랜덤으로 매칭하는 서비스"를 서버리스로 구축해보자.

 

 

1. 서버리스 아키텍처 개요

3-tier serverless architecture

비즈니스 로직을 AWS Lambda(람다) 함수에 작성하고 람다가 실행되면 DynamoDB에 친구들의 기분 상태 데이터를 저장한다. API Gateway를 통해 람다 함수를 접근할 수 있는 URL을 생성하고 S3에 HTML을 업로드하여 S3 정적 웹 사이트 호스팅 기능으로 웹 사이트를 호스팅한다.

(자세한 내용은 1편에)

 

 

2. DynamoDB

완전관리형 AWS의 NoSQL 데이터서비스를 이용하여 데이터를 저장하기 위해 생성한다.

서비스에 연결할 DynamoDB 테이블을 만들면 멤버의 이름과 성격을 저장할 수 있다.

hello-member 이름으로 테이블을 생성해보자.

 

 

1. 테이블 생성 누르기

 

 

2. 테이블 이름은 hello-member 로, 파티션 키는 name 으로 작성한다. 작성 후 페이지 아래 테이블 생성을 누른다.

 

 

3. 아래처럼 활성 상태인 DynamoDB 테이블을 생성했다.

 

 

3. Lambda

AWS 대표적인 서버리스 서비스로 많은 요청이 발생할 때에도 람다는 자동 확장되고 관리된다.

추가 기능이나 간단한 서비스 만들 때 람다를 이용하게 된다.

e.g. 사진 이미지 썸네일 만드는 기능 추가, 간단한 데이터 분석, AWS 이벤트 서비스들과 연동해서 이벤트 처리 등

 

1. 함수 생성 누르기

 

 

2. 새로 작성(Author from scratch) 를 선택한다. 이는 람다의 모든 설정을 처음부터 만든다는 의미다.

 

 

3. 함수 이름(Function name)은 api-service-create 를 입력하고, 런타임(Runtime)으로는 python 3.12 선택

 

 

4. 권한(Permission)을 직접 생성한다. 기본 실행 역할 변경(Change default execution role)을 누르고 실행 역할(Execution role)의 AWS 정책 템플릿에서 새 역할 생성(Create a new role from AWS policy templates)를 선택한다. 역할 이름(Role name)으로는 my-lambda-role 으로 작성한다.

 

 

5. NoSQL 데이터베이스 서비스인 DynamoDB와 연결하거나 이용하거나 호출하기 위해 권한이 필요하다. 단순 마이크로서비스 권한(Simple microservice permissions DynamoDB)를 선택한다. 그리고 아래 함수 생성을 누른다.

 

6. 람다 화면에서 코드 소스(Code source) 부분에 아래 코드를 넣고 Deploy 버튼을 누른다.

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)
    }

 

 

7. Test 버튼을 누르면 테스트 이벤트 구성(Configure test event)가 나온다. 이벤트 이름(Event name)으로는 my-api-test 를 입력하고, 템플릿(Template)은 hello-world 를 선택한다. 그리고 저장을 누른다.

 

 

8. Test 버튼을 누르면 테스트가 진행된다. 이제 아래와 같이 결과가 나오면 된다. 출력된 값들은 랜덤하게 선택된 것이다.

 

 

9. 테스트 결과가 DynamoDB에 잘 저장됐는지 확인을 해본다. DynamoDB 콘솔창에 들어가서 왼쪽 탐색창에서 테이블을 선택한다. 그리고 기존에 만들었던 hello-member 테이블을 누른다.

 

 

10. 표 항목 탐색(Explore table items) 버튼을 누르면 화면 아래쪽에 람다를 실행해서 얻은 값이 저장된 걸 알 수 있다.

 

 

4. API Gateway

AWS의 API 관리 서비스를 이용하여 람다를 실행해보자.

API Gateway는 API 를 관리해주고 API 를 통해 외부에서의 호출이 왔을 때 대문 역할을 한다.

API 란 외부에서 기업의 서비스를 이용하려고 할 때 규격을 정해주는 것을 의미한다. 일종의 형식을 정해놓고, 이 형식대로 기업의 서비스를 호출하면 기업은 서비스를 제공해 주는 약속이라고 생각하면 된다.

 

 

1. API Gateway 콘솔창에 들어간다. 왼쪽 탐색창에서 API 를 선택하고 HTTP API 보다 API 관리 기능이 더 추가되어 있는 REST API 로 생성하기 위해 구축 버튼을 누른다.

 

 

2. API 세부 정보에서 새 API 선택하고, API 이름은 my-api 지정한다. 그 후 API 생성 버튼을 누른다.

 

 

3. API를 생성하면 바로 리소스 화면이 나온다. 여기서 메서드 생성 버튼을 누른다.

 

 

4. 메서드 유형은 GET 선택한다. 통합 유형은 Lambda 함수를 선택하고, Lambda 프록시 통합 토글 버튼을 클릭하여 활성화한다. Lambda 함수에는 api-service-create 이름을 작성한다. 이후 메서드 생성 버튼을 누른다.

 

 

5. 생성한 API의 리소스 메뉴에서 방금 생성한 GET Method를 누르면 오른쪽에 해당 Method 관련된 정보가 보인다. TEST 탭을 선택하여 테스트를 준비한다.

 

 

6. 테스트 버튼을 눌러 테스트를 진행한다. 성공했다면 상태(Status)가 200이 나오며, 응답 본문에 랜덤한 값이 나온다.

 

 

7. API Gateway를 만들었지만 바로 호출하면 CORS 에러가 발생한다. 호출이 정상적으로 이루어지기 위한 추가 설정을 한다. 생성한 API의 리소스 메뉴에서 CORS 활성화 버튼을 누른다.

 

 

8. Access-Control-Allow-Methods 중 방금 생성한 GET Method 선택한 후 저장 버튼을 누른다.

 

 

9. 이제 api를 실제로 사용할 수 있게 API 배포 버튼을 누른다.

 

 

10. 팝업 창이 뜨는데 스테이지에서는 *새 스테이지* 를 선택하고 스테이지 이름은 dev 입력한다.

 

 

11. 완료되면 URL 호출이 나오게 된다. URL은 사람마다 다르며 바로 브라우저를 통해 접속해본다.

 

 

12. URL을 브라우저에 붙여넣어 접속하면 아래와 같이 나온다. 이 작업은 URL을 통해 람다를 호출한 것이다.

 

 

5. AWS S3

어디서나 원하는 양의 데이터를 검색할 수 있도록 구축된 객체 스토리지이다. 거의 모든 사용 사례를 지원할 수 있고, 비용 효율적인 스토리지 클래스와 사용이 쉬운 관리 기능을 통해 비용을 최적화하고, 데이터를 정리하고, 세분화된 액세스 제어를 구성하여 특정 비즈니스, 조직 및 규정 준수 요구 사항을 충족할 수 있다.

 

 

1. S3 콘솔창에 들어와서 버킷 만들기 버튼을 누른다.

 

 

2. 버킷 이름에 my-bucket-[랜덤 숫자]를 입력한다. [랜덤 숫자]는 무작위 숫자로 넣으면 되며 대괄호를 빼야한다.

버킷 이름은 전세계에서 유일해야 한다.

 

 

3. 아래에 이 버킷의 퍼블릭 액세스 차단 설정이 나오는데 여기서 모든 퍼블릭 액세스 차단 선택을 해제한다. 그리고 나오는 위험 문구에서 현재 설정으로 인해 이 버킷과 그 안에 포함된 객체가 퍼블릭 상태가 될 수 있음을 알고 있습니다. 를 선택한다. 그리고 아래 버킷 만들기 버튼을 누른다.

전세계 사람들이 접근하기 때문에 "정적 웹 사이트 호스팅"과 같은 구체적으로 확인된 사용 사례에서 퍼블릭 액세스가 필요한 경우가 아니라면 차단을 활성화하는 것이 좋다

 

 

4. 아래 HTML 파일을 텍스트 에디터에 붙여 넣고 index.html 파일로 저장한다. 그리고 ajax 요청의 url 부분에 URL을 입력하세요 를 API Gateway의 URL로 변경한다.

이 index.html 의 버튼을 누르면 앞에서 만든 람다가 실행된다
<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 onclick="checkEvent();">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 + "&nbsp;&nbsp;" + data.name
            },
            error: function (error) {
                alert('ERROR::');
                console.log(error)
            }
        });
    }
</script>

</html>

 

 

5. 앞서 만든 버킷에서 index.html 파일을 업로드한다.

 

 

6. 업로드를 하면 버킷에 아래처럼 html 파일이 보인다.

 

 

7. 버킷의 속성(Properties) 탭에 들어가서 아래쪽으로 내려가면 정적 웹 사이트 호스팅이 나오며 편집 버튼을 누른다.

 

 

8. 인덱스 문서에 index.html 입력한다. 처음 주소로 읽어 들일 html 파일을 지정해주는 부분이다. 변경 사항 저장 버튼을 누른다.

 

 

9. 설정이 잘 됐다면 정적 웹 사이트 호스팅 기능이 활성화 되며 아래와 같이 주소가 생성된다.

 

 

10. 아직 외부에서 접근할 수 있는 권한이 없어서 사이트가 차단되어 있다. 외부에서 파일을 읽을 수 있도록 권한을 부여한다. 아래와 같이 권한 탭으로 이동하여 버킷 정책에서 편집 버튼을 누른다.

 

 

11. 아래 내용을 복사하여 붙여넣는다. 이 때 11,12번째 줄에 [본인버킷번호] 부분을 본인의 버킷 랜덤 숫자를 넣고 저장 버튼을 누른다. 권한의 내용은 본인 버킷의 내용을 모든 사람이 다운로드할 수 있게 하겠다는 내용이다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1709405011428",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::my-bucket-[본인버킷번호]",
        "arn:aws:s3:::my-bucket-[본인버킷번호]/*"
      ],
      "Principal": "*"
    }
  ]
}

 

 

12. 정적 웹사이트 호스팅 주소를 브라우저에 넣으면 아래 화면처럼 나온다. 버튼을 누르면 웹사이트에 사람이름과 기분이 표시된다. 버튼을 누르면 람다가 실행되는데 DynamoDB에 기록이 잘 됐는지 확인하면 끝이다.