AWS Tech Camp - Web Application with Serverless

gwonsang247·2024년 9월 3일

AWS

목록 보기
2/2
post-thumbnail

섹션 목표

AWS Tech Camp 첫 번째 섹션(Web Application with Serverless) 입니다.

해당 섹션의 주요 키워드는 서버리스 입니다. AWS에서 제공하는 서비스 중에서 서버리스 서비스를 경험하는 것이 주요 목적입니다. 이번 섹션에서는 아래와 같이 Lambda, S3, DynamoDB, API Gateway 네가지 서버리스 서비스를 사용해 간단한 어플리케이션을 구축해보았습니다.


어플리케이션은 선언된 이름 데이터와 상태 데이터를 랜덤으로 매칭해서 웹 페이지에 나타내는 기능을 합니다. 아키텍처는 아래 그림과 같이 Lambda를 활용한 간단한 3-Tier 어플리케이션입니다.




DynamoDB Table 생성

DynamoDB?

DynamoDB 는 AWS의 NoSQL 데이터서비스입니다. 기존에 흔히 사용하시는 Oracle이나 Mysql의 경우, 데이터를 보관하는 형태인 스키마를 정의하고, 이 스키마를 이용해서 데이터를 저장하게 됩니다. 하지만 이 DynamoDB 와 같은 NoSQL 데이터베이스를 이용하시면 이런 스키마 없이 데이터를 원하는 형태로 자유롭게 저장할 수 있습니다. 또한, AWS의 완전관리형 서비스인만큼 서버 관리도 신경쓰지 않으셔도 됩니다.

대규모 성능에 최적화된 완전 관리형 NoSQL 데이터베이스 서비스


DynoDB Core Concepts : Tables, Items, Attributes, Indexes

테이블 (Table)
DynamoDB에서 데이터는 테이블에 저장됩니다. 테이블은 관계형 데이터베이스의 테이블과 유사하지만, 스키마가 없는 NoSQL 구조를 따릅니다. 각 테이블은 고유한 이름을 가지며, 그 안에 여러 아이템을 저장할 수 있습니다.

아이템 (Item)
테이블 내의 개별 데이터 레코드로, 관계형 데이터베이스의 행(row)에 해당합니다. 각 아이템은 여러 속성(attributes)으로 구성되며, 서로 다른 아이템들은 서로 다른 속성을 가질 수 있습니다.

속성 (Attribute)
아이템 내의 데이터 필드를 의미하며, 이는 관계형 데이터베이스의 열(column)에 해당합니다. 속성은 이름과 값을 가지며, 값은 문자열, 숫자, 이진 데이터, 리스트, 맵 등 다양한 데이터 타입을 가질 수 있습니다.

주 키 (Primary Key)
테이블의 각 아이템을 고유하게 식별하는 데 사용되는 속성입니다. DynamoDB에서는 두 가지 유형의 주 키를 제공합니다:

파티션 키 (Partition Key): 단일 속성으로 이루어진 주 키. 이 키의 해시 값을 기반으로 데이터를 분산 저장합니다.

복합 키 (Composite Key): 파티션 키와 정렬 키(Sort Key)로 구성된 주 키. 파티션 키가 같은 아이템들을 정렬 키를 기준으로 정렬하여 저장합니다.

인덱스 (Indexes)
DynamoDB는 테이블 내에서 추가적인 쿼리 성능을 향상시키기 위해 인덱스를 사용할 수 있습니다.
글로벌 보조 인덱스 (Global Secondary Index, GSI): 다른 파티션 키와 정렬 키를 사용하여 테이블에 대한 추가 조회 방법을 제공합니다. 로컬 보조 인덱스 (Local Secondary Index, LSI): 동일한 파티션 키를 사용하지만 다른 정렬 키를 기반으로 추가 조회를 제공합니다.


🛠 DynamoDB 생성

  • DynamoDB 를 콘솔창에서 검색해서 들어갑니다.

  • DynamoDB 콘솔로 들어가서 왼쪽의 create table 버튼을 누릅니다.

  • Table name을 설정하고 (hello-member), Partition key(name)를 설정합니다. 작성하신 다음에는 오른쪽 아래의 create table 버튼을 눌러서 생성합니다.

  • 아래처럼 Status 가 Active 가 될 때까지 기다립니다. 시간이 다소 걸립니다.



Lambda 서버 생성하기

lambda?

Lambda 는 AWS 의 대표적인 서버리스 서비스로, 서버에 대해서 고민을 하지 않고 서비스를 간단하게 만들 수 있도록 도와드립니다.
많은 요청이 발생할 때에도 Lambda는 자동으로 확장되고, 관리되므로 걱정하지 않고 서비스에만 집중할 수 있습니다. 추가하고 싶은 기능이나, 간단한 서비스를 만드실 때 어렵게 생각하지 말고 Lambda 를 이용할 수 있습니다.
Lambda를 통해서 사진 이미지의 썸네일 버젼을 만드는 기능을 만들수도 있고, 간단하게 데이터 분석을 하고 싶을 때에도 이용할 수 있습니다. 좀 더 익숙해 지시면 AWS 의 이벤트 서비스들과 연동해서 이벤트가 발생했을 때 Lambda 의 기능을 이용해서 이벤트를 처리하는 식으로 사용하실 수도 있습니다. 가능성이 무궁무진한 서비스입니다.

  • 불필요한 서버 관리
  • 자동 확장
  • 고가용성 및 보안
  • 사용한 만큼만 지불

🛠 Lambda 생성

  • Lambda 를 콘솔창에서 검색해서 들어갑니다.

  • Create a function 을 눌러서 Lambda 생성 메뉴로 들어갑니다.

  • 왼쪽 탐색창의 Functions를 선택하고, Create a function 을 선택합니다. Lambda 생성 메뉴로 들어갑니다.
  • Author from scratch 를 선택합니다. 이 메뉴는 Lambda의 모든 설정을 처음부터 해서 만드는 겁니다.
  • Function name을 설정하고, Runtime으로는 익숛한 언어를 선택합니다. (해당 세션에서는 Python 3.9로 설정)
  • Permissions을 직접 생성해 보도록 하겠습니다. Permissions 섹션에서 Execution role 의 Create a new role from AWS policy templates 를 선택합니다. Role name을 작성합니다. (해당 세션에서는 my-lambda-role로 설정)
  • 생성한 Lambda Function을 NoSQL 데이터베이스 서비스인 AWS DynamoDB와 연결합니다. AWS 서비스끼리 서로 연결하거나 이용하거나 호출하거나 할 때에는 권한이 필요합니다. Simple microservice permissions DynamoDB 를 선택합니다. 그리고 오른쪽 아래의 Create function 버튼을 눌러 다음으로 이동합니다.

    Create function 버튼을 눌러 Lambda -> functions -> 생성한 함수로 접근하면 아래와 같이 Lambda 함수가 생성된 것을 확인할 수 있습니다.
  • Lambda 화면에서 Code source 부분에 함수의 기능을 정의하고 있는 아래 코드를 복사 붙여넣기 한 다음 Deploy 버튼을 누릅니다.
import json
import boto3
import random
import json
def lambda_handler(event, context):
    member_name = ['HONG GILDONG','KIM SANGCHUL','KARINA','WINTER','PARK DOLLDOLL']
    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)
    }
  • Test 버튼을 누릅니다.

  • Test버튼을 누르면 아래와 같은 Configure test event 팝업이 뜨고, 다음과 같이 입력합니다. Event name 으로는 my-api-test 를 입력하고, Template은 hello-world를 선택합니다. 그리고 Save 버튼을 누릅니다.

  • Test 버튼을 누르면 테스트가 진행됩니다. 앞에서 DynamoDB Table을 만들었기 때문에, 오류 없이 아래와 비슷한 결과가 나와야 합니다. 아래 출력된 값들은 랜덤하게 선택된것이기 때문에 다 다오르게 나올겁니다. 하지만 아래 형식으로 나오면 성공한겁니다.
  • 값이 DynamoDB에 잘 기록이 되었는지 확인 하기위해, DynamoDB 를 콘솔창에서 검색해서 들어갑니다.

  • 왼쪽 탐색창에서 Tables를 선택하고, 기존에 만들었던 hello-member 테이블을 이름을 누릅니다. 아래와 같은 테이블 관리 메뉴를 확인 하실수 있습니다. 테이블에 입력된 Item들을 확인하기 위해, Explore table items 버튼을 누릅니다.

  • 화면의 아래쪽에, Lambda를 실행해서 DynamoDB에 값이 입력되있는걸 확인 하실수 있습니다.



API Gateway 구성하기

API Gateway 는 AWS의 API 관리 서비스입니다. API 란 외부에서 기업의 서비스를 이용하려고 할때 규격을 정해주는 것을 의미합니다. 일종의 형식을 정해놓고, 이 형식대로 기업의 서비스를 호출하면 기업은 서비스를 제공해 주는 약속이라고 생각하시면 됩니다. API Gateway는 이런 API 를 관리해주고 API 를 통해 외부에서의 호출이 왔을때 대문 역할을 하는 AWS 서비스입니다.

🛠 API Gateway 생성

  • API Gateway 를 콘솔창에서 검색해서 들어갑니다. 왼쪽의 APIs 메뉴로 들어갑니다. HTTP API 보다 API 관리 기능이 더 추가되어 있는 REST API 로 생성해 보겠습니다. REST API 에서 Build 버튼을 누릅니다.

  • API Details에서 New API, Setting 에서는 API name을 지정합니다. 그 다음 create API 버튼을 누릅니다.

  • 들어간 화면 오른쪽 아래에 있는 Method Panel에서 Create Method 를 누릅니다. Create Method 화면이 나오고 여기서 API를 구성할 수 있습니다. Method Type으로 GET을 선택합니다. Integration type은 Lambda Function 을 선택하고, Lambda Proxy integration Toggle 버튼을 클릭하여 활성화해 줍니다. Lambda Function 에는 이전에 생성한 lambda 함수인 api-service-create로 이름을 작성합니다. 다 작성했으면 맨 밑의 Create method 버튼을 누릅니다. 아까 lambda의 이름을 다른 걸로 저장하셨다면 그 lambda 를 찾아서 넣어주시면 됩니다.

  • 생성한 API의 Resources 메뉴에서 방금 생성한 GET Method를 누르면 이제는 오른쪽에 해당 Method에 관련된 정보가 보이게 됩니다. TEST Tab을 선택하여 테스트를 준비합니다. 들어간 Tab에서 Test 버튼을 다시 눌러줍니다.

  • Test 가 성공하였다면, Status가 200으로 나오며, Response Body에 랜덤한 값이 나오게 됩니다. 그림과 다른 값이 나오실 수 있습니다.

🛠 API Gateway 추가 설정

  • API gateway 를 만들었지만, 바로 호출하면 CORS 관련 에러가 나게 될 것입니다. 따라서 호출이 정상적으로 이루어지기 위한 추가 설정을 하겠습니다. 생성한 API의 Resources 메뉴에서 Enable CORS 를 클릭합니다.

  • Enable CORS화면의 Access-Control-Allow-Methods 중 방금 생성한 GET Method를 선택한 후 Save 버튼을 클릭합니다. api 가 정상적으로 작동된다는 것을 확인하고, 추가 설정을 마쳤으니 이제 이 api 를 실제 사용할 수 있게 준비하겠습니다. Resources 화면에서 Deploy API 를 누릅니다.

  • Deploy API를 누르면 팝업 창이 뜨게 되는데, 여기에서 Stage 에서는 New Stage 를 선택하고 Stage name 에서는 dev 를 입력합니다. 여기서 stage는 API를 관리하기 위한 정책이라고 합니다.

  • 완료되면 Invoke URL 이 나오게 됩니다. 이 URL 은 사람마다 모두 다릅니다. 이 URL 은 반드시 복사해서 메모장에 붙어넣으시기 바랍니다. 바로 다음 단계에서 활용합니다. 이 URL을 브라우저에 붙여놓고 접속하면 외부에서 API 호출을 통해 Lambda 함수를 호출합니다.


S3로 웹서버 기능 사용하기


S3는 어디서나 원하는 양의 데이터를 검색할 수 있도록 구축된 객체 스토리지 입니다. Amazon Simple Storage Service(Amazon S3)는 업계 최고 수준의 확장성, 데이터 가용성, 보안 및 성능을 제공하는 객체 스토리지 서비스입니다. 고객은 규모와 업종에 관계없이 원히는 양의 데이터를 저장하고 보호하여 데이터 레이크, 클라우드 네이티브 애플리케이션 및 모바일 앱과 같은 거의 모든 사용 사례를 지원할 수 있습니다. 비용 효율적인 스토리지 클래스와 사용이 쉬운 관리 기능을 통해 비용을 최적화하고, 데이터를 정리하고, 세분화된 액세스 제어를 구성하여 특정 비즈니스, 조직 및 규정 준수 요구 사항을 충족할 수 있습니다.


🛠 S3 Bucket 생성하기

  • S3 를 콘솔창에서 검색해서 들어갑니다. Create bucekt 버튼을 누릅니다.

  • Bucket name에 my-bucket-[random number] 를 입력합니다. 여기서 [random number]는 무작위 숫자 입니다. 대괄호를 빼야합니다. (Bucket name은 전세계에서 유일해야 합니다.)

  • 아래쪽으로 내리다보면 Block all public access 선택을 해제 합니다. S3를 정적 웹페이지 호스팅 용도로 사용하는 경우에는 외부 접근을 허용해야 합니다. 만약, 이미지 같은 유형의 데이터를 저장하는 용도로 사용하는 경우에는 해당 항목을 체크해서 접근을 막아햐 합니다. 접근 허용 사실을 인지하고 있음을 표시하기 위해 하단의 I acknowledge ... 체크합니다. 이후 Create bucket 버튼을 눌러서 Bucket을 생성합니다.

  • 아래처럼 Bucket이 만들어 졌다면, Bucket 이름을 눌러서 들어 갑니다. 그 후 정적 웹페이지에 호스팅 할 html 파일을 업로드 합니다. Add files 버튼을 누릅니다. 위에서 저장한 index.html 파일을 선택하고, 제일아래 Upload 버튼을 눌러서 업로드합니다.업로드가 성공적으로 된것을 확인하고, Close 버튼을 누릅니다.


  • 업로드가 잘됐다면, 아래처럼 index.html 파일이 보일겁니다.

  • 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>
        body {
            background-color: #f4f4f4;
            font-family: Arial, sans-serif;
        }

        #title {
            font-family: 'Comic Sans MS', cursive, sans-serif;
            font-size: 2.5em;
            color: #ff5733;
            margin-top: 50px;
            text-align: center;
            text-shadow: 2px 2px #333333;
        }

        button {
            background-color: #28a745;
            border: none;
            color: white;
            border-radius: 10px;
            width: 50%;
            height: 45px;
            font-size: 15pt;
            margin-top: 30px;
            text-align: center;
            cursor: pointer;
            box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
            transition: all 0.3s ease;
        }

        button:hover {
            background-color: #218838;
            transform: scale(1.05);
        }

        #sentence {
            font-size: 18pt;
            margin-top: 30px;
            font-weight: bold;
            color: #007bff;
            text-align: center;
        }

        #lambda-line {
            border: 2px solid #007bff;
            margin: 20px auto;
        }
    </style>
</head>

<body>
    <p id="title">3-Tier Application Demo with <b>Lambda</b></p>
    <hr id="lambda-line" width="800px" align="center">
    <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: "https://9aeq9odyp5.execute-api.ap-northeast-2.amazonaws.com/dev",
            dataType: 'json',
            success: function (data) {
                document.getElementById('sentence').innerHTML = data.name + " is " + data.status;
            },
            error: function (error) {
                alert('ERROR::');
                console.log(error);
            }
        });
    }
</script>

</html>

🛠 S3 정적 웹사이트 호스팅 기능 활성화하기

  • S3의 정적 웹사이트 호스팅 기능을 활성화하여 웹서버 기능을 사용해 보기 위해, 아래와 같이 Properties탭을 선택합니다.
    화면 제일 아래쪽으로 스크롤해보면 Static website hosting 섹션을 확인 할수 있습니다. Edit 버튼을 누릅니다.

  • 설정하는 부분입니다. index document 입력란에 index.html을 입력합니다. 처음 주소로 접속할때 읽어 들일 html파일을 지정해 주는 부분입니다. Save changes 버튼을 눌러서 저장합니다.

  • 위 설정이 잘되었다면, 정적 웹사이트 기능을 활성화되고, 아래와 같이 주소가 생성됩니다. 이 주소로 접속할겁니다. 해당 url로 접근하면 접근이 차단되는 것을 확인할 수 있습니다. 그 이유는 S3 설정에서 S3에 대한 외부 접근은 허용했지만, index.html에 대한 접근이 허용되지 않았기 때문에 이를 허용해 줘야 합니다.

  • 아직 외부에서 접근할수 있는 권한이 없어서 정적 웹사이트가 차단되어 있습니다. 외부에서 파일을 읽어 들일수 있도록 권한을 부여할 겁니다. 아래와 같이 Permissions 탭으로 이동합니다. Bucket policy 섹션에 Edit 버튼을 눌러서 수정합니다.

  • 다음 내용을 복사하여, Bucket policy 편집창에 붙여 넣습니다. 그리고 11,12번째 줄의 [본인버킷번호] 부분을 본인의 Bucket 랜덤 넘버로 변경합니다. 그리고 Save changes 버튼을 눌러서 저장합니다.

    권한의 내용은 본인 버킷의 내용에 대해 접근한 사람이 다운로드 할 수 있도록 허용하겠다는 내용입니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1709405011428",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::my-bucket-[본인버킷번호]",
        "arn:aws:s3:::my-bucket-[본인버킷번호]/*"
      ],
      "Principal": "*"
    }
  ]
}
  • 정적 웹사이트 호스팅 주소를 브라우저에 붙여 넣어 봅니다. 아래 화면 처럼 나오면 Who are you? 버튼을 눌러줍니다. 람다가 실행되고 Dynamodb에 기록이 잘되었는지 확인합니다.

실습 자료
https://catalog.us-east-1.prod.workshops.aws/workshops/600420b7-5c4c-498f-9b80-bc7798963ba3/ko-KR/serverless

0개의 댓글