이전편에서 이어지는 포스팅입니다. 이전편에서 정적 웹사이트 호스팅-사용자 관리 파트까지 다루었습니다.
사용한 서비스: AWS Lambda, Amazon DynamoDB
AWS Lambda와 Amazon DynamoDB를 사용하여 웹 애플리케이션에 대한 요청을 처리하기 위한 백엔드 프로세스를 만듭니다. 이전에 배포한 브라우저 애플리케이션을 사용하여 사용자는 선택한 위치로 unicorn을 전송하도록 요청할 수 있습니다. 이러한 요청을 이행하려면 브라우저에서 실행 중인 JavaScript가 클라우드에서 실행하는 서비스를 호출해야 합니다.
사용자가 unicorn을 요청할 때마다 호출될 Lambda 함수를 구현하는 파트입니다. 이 함수는 플릿에서 unicorn을 선택하고, DynamoDB 테이블에 요청을 기록한 후 디스패치된 unicorn에 대한 세부 정보를 프론트엔드 애플리케이션에 반환합니다.
이 함수는 Amazon API Gateway를 사용하여 브라우저에서 호출됩니다. 이 연결을 설정하기전에 함수를 테스트합니다.
3.1) Amazon DynamoDB 테이블 만들기
Rides라는 이름의 테이블을 생성하고, 스트링 타입의 RideId를 파티션 키로 지정합니다. 다른 세팅은 디폴트 값을 사용합니다.
생성 이후 Overview 하단의 ARN(Amazon Resource Name)은 이후에 사용되므로 메모합니다.
3.2) Lambda 함수를 위한 IAM 역할 만들기
각 Lambda 함수에는 IAM 역할이 연결되어 있습니다. 이 역할은 기능이 상호작용하도록 허용된 다른 AWS 서비스를 정의합니다. 이 프로젝트에서는 Amazon CloudWatch Logs에 로그를 쓸 수 있는 권한과 DynamoDB 테이블에 항목을 쓸 수 있는 액세스 권한을 Lambda 함수에 부여하는 IAM 역할을 만들어야 합니다.
IAM에서 Roles > Create New Role를 선택합니다. AWS service에서 role type으로 Lambda를 선택하고, permission으로는 AWSLambdaBasicExecutionRole를 부여합니다.
Role name으로 WildRydesLambda를 지정한뒤 create하였습니다.
role중에서 방금 생성한 WildRydesLambda를 선택하고(선택했어야하고...😭), Permission > Add inline policy를 선택합니다.
여기서 WildRydesLambda가 아닌 Amplify role을 만들어놓은걸 잘못 클릭한것이 문제였는데 ..캡쳐하면서도 몰랐다.. 마지막에 나타나는 오류의 이유
inline policy를 위해 정책 서비스로 DynamoDB를, Select action에서 PutItem을 선택하였습니다.
Add ARN을 선택하여 이전 DynamoDB 생성단계에서 메모해둔 ARN을 입력해줍니다.
DynamoDBWriteAccess로 policy 이름을 지정해주고 create합니다!
3.3) 요청을 처리하기 위한 Lambda 함수 만들기
AWS Lambda는 HTTP 요청 등과 같은 이벤트에 대응하여 코드를 실행합니다, 이 단계에서는 웹 애플리케이션에서 unicorn을 디스패치하는 API 요청을 처리할 코어 함수를 만듭니다.
Lambda에서 create function을 선택합니다. RequestUnicorn로 function name을 지정하고, Runtime으로 Node.js 12를 선택하였습니다. Choose an existing role에서 바로 이전에 만든 IAM Role인 WildRydesLambda를 선택해주고 create function합니다.
RequestUnicorn함수가 생성되었습니다. 하단으로 내려 Function code의 index.js를 수정 -> 저장해주었습니다.
3.4) 구현 테스트
함수를 테스트하기 위해서 Select a test event > Configure test event를 선택해주고, Event name으로 TestRequestEvent를 적어주었습니다. editor에 코드를 적어주고, Create하여 Test 버튼을 눌러보았습니다.
실행에 성공하여, Details를 눌러보았습니다. 원하는 result가 나오지 않아서 설마했지만... function code를 확인해봐도 문제가 없고, 무엇보다 기분좋은 'succeeded + 초록색 창'에 아닐거야 하며 다음 단계로 넘어갔습니다.
사용한 서비스: Amazon API Gateway, AWS Lambda
Amazon API Gateway를 사용하여 이전 파트에서 구축한 Lambda 함수를 RESTful API로 공개합니다. 이 API는 퍼블릭 인터넷에서 액세스할 수 있습니다. 이 API는 이전 파트에서 생성한 Amazon Cognito 사용자 풀을 사용하여 보호됩니다.
이 구성을 사용하고 공개된 API에 AJAX 호출을 수행하는 클라이언트 측 JavaScript를 추가하여 정적으로 호스팅된 웹 사이트를 동적 웹 애플리케이션으로 전환합니다.
4.1) 새 REST API 생성
API Gateway에서 REST API 생성을 선택합니다. Create API를 누르고 API의 이름으로 WildRydes를 적어주었습니다. Endpoint Type은 Edge optimized를 선택하여 create합니다.
(Edge optimized는 인터넷에서 액세스하는 퍼블릭 서비스에 가장 적합합니다. 일반적으로 Regional endpoints는 동일한 AWS 영역 내에서 주로 액세스하는 API에 사용됩니다.)
4.2) Cognito user pool Authorizer (권한 부여자) 생성
Authorizers > Create New Authorizer 를 선택하여 Authorizer의 이름을 WildRydes로 부여해줍니다. Type으로는 Cognito를 선택하고, Cognito를 생성할때 선택한 리전을 골라서 user pool의 이름을 (= WildRydes) 적어줍니다. Token source에 Authorization를 입력하고 create합니다.
배포한 웹 사이트의 /ride.html로 이동하여 이전에 나왔던 표시로 부터 auth token를 복사합니다. 방금 생성한 Authorizer에서 Test 버튼을 누르고 복사한 토큰을 붙여 넣어줍니다.
Test 버튼을 눌러 Response Code: 200으로 cognito user pool authorizer가 잘 돌아가는 것을 확인할 수 있습니다.
4.3) 새 리소스 및 메소드 생성
WildRydes API 아래 resource를 클릭하여 Action에서 Create resource를 선택합니다. 리소스 이름으로 ride를 지정해주고, Enable API Gateway CORS에 체크하여 create합니다.
새롭게 만들어진 /ride 리소스를 선택하여 POST를 선택하고 체크마크에 체크합니다. integration type으로 Lambda Function를 선택하고, Lambda Proxy integration에 체크해줍니다. 람다의 리전으로 리전을 선택해주고, 람다함수의 이름을 (=RequestUnicorn) 적어주었습니다.
다음으로는 Method Request를 눌러서 Authorization을 WildRydes Cognito user pool authorizer로 수정하고 체크마크에 체크해주었습니다.
4.4) API 배포
이제 API배포를 위해 Actions에서 Deploy API를 눌러줍니다. Deployment stage에서 [New Stage] 를 선택하고, stage이름으로 prod를 적어 deploy하였습니다.
Invoke URL은 이후에 사용되므로 복사합니다.
4.5) 웹 사이트 구성 업데이트
config.js 파일을 열어 비워져있는 Invoke URL 부분에 붙여넣기 해줍니다.
역시나 깃에 푸시합니다.
4.6) 구현 검증
구현의 검증을 위해서 로그인된 웹 페이지의 /ride.html에서 Request Unicorn 버튼을 누릅니다..!
유니콘을 request하는 데에서 에러가 생겼습니다. 아까 원하는 result가 나오지 않아서 미심쩍었던 부분으로 돌아가보았습니다.
생각해보니 function code를 수정하기 전의 result가 나오고 있었습니다. save가 안된 것일까 다시 한번 save를 눌러보고 다른 저장방법이 있나 찾아보다가 deploy버튼의 save를 눌러보았습니다.
statuscode 500으로 에러메시지가 생겼습니다.
' RequestUnicorn is not authorized to perform : dynamodb : Put item on resource '
authorize랑 dynamodb 관련된 에러구나 ..
dynamodb랑 IAM 역할을 했었던 부분을 살펴보기 위해 먼저 dynamodb에 들어가 보았습니다.
엥 inline policy로 지정했던 DynamoDBWriteAccess가 Lambda가 아닌 Amplify에 만들어져있었습니다.
x버튼으로 policy를 삭제하고 다시 DynamoDB의 PutItem을 Lambda에 생성해주었습니다.
다행히 다른 서비스들이나 배포에 영향이 가는 건 없었습니다. 다시 Lambda function으로 돌아와서 test해보았습니다.
원했던 실행결과가 나왔습니다. 다시 Amplify로 배포하여 보았습니다.
와,, 드디어 핀을 찍으면 해당 장소에 유니콘이 나왔습니다 :) 웹앱이 제대로 동작하는 것을 볼 수 있었습니다.
프리티어 사용자에게 생명인 단계로, 프로젝트를 진행하는 동안 생성한 리소스를 모두 종료하는 과정입니다. AWS Amplify app, an Amazon Cognito User Pool, AWS Lambda function, IAM role, DynamoDB table, REST API, CloudWatch Log를 단계별로 종료하게 됩니다.
5.1) 앱 삭제하기
AWS Amplify를 선택하여 생성했던 앱을 삭제합니다.
5.2) Amazon Cognito 사용자풀 삭제하기
Cognito > Manage your User Pools에서 WildRydes를 선택하여 Delete pool을 눌러 삭제합니다.
5.3) 서버리스 백엔드 삭제하기
Lambda > RequestUnicorn > Actions > Delete function 하여 Lambda function을 삭제합니다.
IAM > Roles > WildRydesLambda > Role Action > Delte role 하여 IAM role을 삭제해줍니다.
DynamoDB > Table > Rides > Delete table 하여 db table을 삭제해줍니다.
5.4) REST API 삭제하기
API Gateway > API 선택(WildRydes) > Actions > Delete API 하여 REST API를 삭제합니다.
5.5) CloudWatch Log 삭제하기
CloudWatch > Logs 에서 /aws/lambda/RequestUnicorn 를 선택하고, Delete log group을 눌러 삭제합니다. 이제 모든 리소스가 삭제되었습니다!
GCP를 위주로 퀵랩을 하다보니 콘솔 사용이 GCP에만 익숙해져 있어서 aws 서비스들로 프로젝트를 하기에 걱정이 있었다. aws서비스들은 saa를 준비하며, 웨비나들을 들으며 공부했던 경험이 있지만, 직접 사용해본 경험은 핸즈온 세션들을 제외하고 그리 많지 않기 때문이다.
aws 웨비나에서 한 클라우드에 익숙해지면 다른 클라우드는 금방 사용할 수 있다는 말을 어떤 분이 해주신 적이 있어서 과연 그럴까 했었는데, 이번 기회로 직접 해보니 정말 그랬다. 처음엔 서비스를 찾는 데에도 버벅임이 있었지만 방학을 이유로 여유롭게 할 수 있다보니 여러 서비스들을 꼼꼼히 사용해볼 수 있어서 좋았고, 많은 서비스들을 한 프로젝트에서 다뤄볼 수 있어서 좋았다.
또한, 기존에 프로젝트 세션으로 제공된 자료들과 코드들이 있기 때문에 사용에 큰 가이드가 되어주었고 덕분에 공부하기 편리했다.
과금에 대한 두려움은 있지만, 학생들의 경우 대부분 상황을 봐주시는 경우가 많기 때문에 그리 걱정하지 않고 사용할 수 있을 것 같다.
이제 퀵랩에 aws도 많이 생겼다고 하니, 앞으로는 aws를 이용해서도 직접 만들어 보는 공부를 많이 해봐야겠다.
프로젝트는 aws에서 진행했던 서버리스 웹 앱 구축하기 프로젝트 세션을 참고하여 진행했습니다.