서버리스란?
서버가 정말 없다는 뜻이 아닌 사용자가 서버 관리에 드는 노력이 필요없다는 뜻입니다. 사용한 만큼만 지불하는 시스템이고, 요청에 맞게 스케일링이 가능하며, 높은 보안 수준 또한 제공합니다.
서버리스 서비스의 종류는 여러가지가 있는데 COMPUTE에는 Lambda, Fargate가 있고 DATA STORES에는 S3, Aurora serverless, DynamoDB가 있으며, INTEGRATION에는 EVENTBridge, API Gateway, SQS, SNS, Step Functions, AppSync 등이 있습니다.
이번엔 S3, API Gateway, Lambda, DynamoDB 서버리스 서비스를 이용해 아키텍처를 구성하겠습니다.
정적 웹사이트를 호스팅 하는 S3와 람다의 함수를 가져오게 해주는 API Gateway, 백엔드 역할을 수행하는 서버리스 람다 그리고 테이블 역할을 하는 DynamoDB로 구성되어 있습니다.
3-tier 아키텍처로 S3가 프레젠테이션 티어, API Gateway와 Lambda가 애플리케이션 티어, DynamoDB가 데이터 티어을 담당합니다.
*서울 리전을 기준으로 진행했습니다.
1. DynamoDB 생성
DynamoDB에 들어가 테이블 생성을 클릭합니다.
테이블 이름은 hello-member, 파티션 키는 name으로 하고 문자열로 설정합니다.
파티션 키는 NoSQL인 DynamoDB에서 RDBMS에서의 기본 키의 역할을 합니다. 그래서 파티션 키는 필수 입력 사항입니다.
테이블 생성을 눌러준 후 기다려줍니다.
2. Lambda로 앱서버 생성하기
람다를 클릭하고 함수 생성을 눌러줍니다.
새로 작성을 선택하고, 함수 이름은 api-service-create, 런타임은 python 3.9, 아키텍처는 x86을 선택합니다.
기본 실행 역할 변경을 클릭 한 뒤 실행 역할은 "AWS 정책 템플릿에서 새 역할 생성" 클릭, 역할 이름은 my-lambda-role, 정책 템플릿은 dynamoDB를 검색해서 "단순 마이크로서비스 권한"을 선택합니다.
(처음 람다를 생성하면, DynamoDB에 접근할 수 없어 함수를 실행해도 저장이 되지 않습니다. 그래서 역할을 생성해야 하는데 역할 안에 DynamoDB에 접근할 수 있는 정책을 포함합니다. 그것이 정책 템플릿에서 선택한 "단순 마이크로서비스 권한"입니다.)
함수 생성을 클릭합니다.
IAM에 들어가서 액세스 관리 > 역할에 들어가면 my-lambda-role이 생성된 것을 확인할 수 있습니다.
76으로 시작하는 ID한테 서울리전 기준 다이나모DB의 모든 테이블 리소스에 대해 Action에서 명명한 내용을 허용한다는 뜻입니다.
코드 소스 부분에 아래의 기존 코드를 지우고 코드를 입력합니다.
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)
}
입력했다면 Deploy 버튼을 눌러 저장해줍니다.
Test 버튼 토글을 눌러 Configure test event를 누릅니다.
이벤트 이름은 my-api-test, 템플릿은 hello-world로 지정한 뒤 저장합니다.
dynamoDB에 잘 랜덤으로 생성되는 name: status 쌍을 저장하는 이벤트입니다.
이제 Test를 누르면 statuesCode 200이 나오면 성공입니다. body 부분에 name은 Penny, status는 Happy로 이름과 감정이 결과로 출력됩니다.
(랜덤이기 때문에 화면이랑 달라도 문제 없습니다)
만일 실패가 출력된다면 서울(ap-northeast-2) 리전으로 진행 중인지 다시 확인해보시면 좋을 것 같습니다. 코드는 ap-northeast-2를 기준으로 합니다
이제 생성된 Penny: Happy가 DynamoDB에 잘 생성되었는지 확인하러 가겠습니다.
DynamoDB > 테이블 > hello-member를 눌러주세요.
오른쪽 위에 있는 "표 항목 탐색"을 클릭합니다.
반환된 항목에 1개가 있고 Penny와 status에 Happy가 있으니 잘 들어간 것을 확인할 수 있습니다.
3. API Gateway 구성하기
이제 백엔드 역할을 하는 람다를 웹 페이지에서 호출 할 수 있도록 API Gateway를 생성하겠습니다.
1) 생성
RESTful API를 만들겁니다. REST API 구축을 눌러줍니다.
새 API를 선택한 뒤, api이름은 my-api로 하고 API 생성을 눌러줍니다.
2) 메서드 생성
메서드 생성을 클릭합니다.
메서드 유형은 GET으로 lambda 프록시 통합, 람다 함수는 방금 생성한 ap-northeast-2의 api-service-create로 선택합니다.
(API Gateway에서 api-service-create 람다 함수를 GET 방식으로 호출할 수 있도록 하는 설정입니다)
Lambda 프록시 통합은 웹 페이지에서 요청을 보내는 클라이언트와 람다 사이에서 API Gateway가 클라이언트의 요청 정보(헤더, 쿼리 파라미터, 바디 등)을 람다 함수에 json 형태로 그대로 전달하게 되어 간소화된 매핑이 가능합니다.
3) 메서드 테스트
메서드를 생성한 뒤 GET 메서드를 클릭하고 테스트 항목에서 테스트를 클릭해줍니다.
상태 200이 뜨며 Ama: Happy가 출력되었으니 성공입니다.
4) CORS 활성화
리소스 세부 정보에서 CORS 활성화를 해주셔야 하는데 Cross-Origin Resource Sharing입니다. 서로 다른 도메인에서의 정보 요청을 허용하는 것인데 활성화 해주지 않으면 제한되어 작동하지 않을 수 있습니다.
생성한 메서드가 GET 방식이니 GET을 체크하고 저장해줍니다.
5) API 배포
API 배포를 눌러줍니다. 구성한 API를 실제로 사용 가능한 상태로 만드는 과정입니다.
dev라는 이름의 스테이지가 생성되었습니다.
각 배포는 스테이지와 연결되며, 고유한 URL을 가집니다.
보이는 URL 호출을 클릭해서 복사해줍니다.
그리고 브라우저 창에 입력했을 때 위와 같이 출력되면 성공입니다.
API Gateway의 스테이지 url을 통해 람다, 다이나모DB까지 접속한 것 입니다.
API Gateway > Lambda > DynamoDB
지금까지의 과정입니다.
4. S3로 웹서버 기능 사용하기
1) S3 버킷 생성
콘솔의 s3로 들어가서 버킷 만들기를 누릅니다.
버킷 이름은 오늘 날짜를 넣어서 만들었습니다. 여러분은 다르게 하셔야합니다.
모든 퍼블릭 액세스 차단을 해제해줍니다. 그리고 생성을 누릅니다.
2) html 파일 업로드
본인의 IDE를 사용해 다음 코드를 입력하는 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 + " " + data.name
},
error: function (error) {
alert('ERROR::');
console.log(error)
}
});
}
</script>
</html>
<script> 태그의 url 부분에 자신의 API Gateway에서 생성한 dev 스테이지의 url을 입력합니다.
이렇게 넣으시면 됩니다.
파일 추가로 index.html을 넣고 업로드를 누릅니다.
3) 정적 웹사이트 호스팅 기능 활성화
속성 > 가장 아래로 내려 "정적 웹 사이트 호스팅" > 편집
활성화로 변경
인덱스 문서에 index.html 입력 > 저장
s3 웹 사이트에 접속할 수 있는 url 엔드포인트가 생성되었습니다.
4) 웹 사이트 접근 차단 해제를 위한 S3 버킷 정책 수정
EC2의 보안 그룹에서 특정 IP를 허용(Allow)하듯이 S3 정적 웹 호스팅도 허용하는 과정이 필요합니다.
버킷 정책으로 접근을 허용해 줄 겁니다. 편집을 누른 뒤에 다음 코드를 붙여넣기 합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1709405011428",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"<본인의 버킷 ARN>",
"<본인의 버킷 ARN>/*"
],
"Principal": "*"
}
]
}
위에 있는 버킷 ARN을 리소스 부분에 "" 사이에 사진과 같이 넣습니다.
resource 내용의 의미는 첫 줄은 버킷 자체를 가리키고 버킷 수준의 작업을 허용한다는 뜻이며, 두 번째 줄은 버킷 내에 있는 모든 객체에 대한 권한을 부여한다는 의미입니다.
변경 사항 저장을 누르면 s3 버킷 정책으로 접근 제한을 해제했습니다.
이제 다시 속성으로 돌아가서 S3 정적 웹 호스팅 엔드포인트 url을 브라우저에 입력합니다.
클릭하면 랜덤으로 이름과 감정이 출력됩니다.
이렇게 S3 > API Gateway > Lambda > DynamoDB 이렇게 이어지는 3-Tier 아키텍처를 완성했습니다.
5. 리소스 삭제하기
생성한 순서의 반대로 S3 > API Gateway > Lambda > DynamoDB 순서로 삭제하시면 됩니다.
그리고 IAM 역할에 들어가서 lambda-for-role도 삭제해 주시면 생성했던 리소스는 모두 삭제가 됩니다.
'[Cloud] > [AWS]' 카테고리의 다른 글
[AWS] iam instance profile 확인 명령어 (0) | 2024.09.08 |
---|---|
[AWS] SNS와 Cloudwatch를 이용한 모니터링과 오토스케일링 (0) | 2024.09.07 |
[AWS] ALB를 이용한 EC2 부하 분산 (0) | 2024.09.04 |
[AWS] EKS에서 트래픽 유발해서 HPA 스케일링 확인하기(with ECR) (1) | 2024.08.30 |
[AWS] AWS CLI로 EKS 클러스터 만들기 (0) | 2024.08.29 |