Generator, Co, Async 를 이용한 비동기 순차 실행시키기
AWS의 로드 밸런서(ELB)와 람다(Lambda)를 사용해서 간단한 Koa(Serverless HTTP) API 서버 배포하기
2020-06-14
Explanation
현재 시간 일요일 새벽 4시 16분.
빨리 자야 월요일에 안녕하게 출근할 수 있는데, 잠은 안 오고, 잠 안 오는데 누워있자니 시간 아깝고..
그렇다고 일을 하자니 또 그 정도로 머리가 잘 돌아가는 상황은 아니어서,
생각 없이 할 수 있는 간단한 포스팅을 하려 합니다!
이번 포스팅은 AWS의 로드밸런서(ELB)와 람다(Lambda)를 사용하고 NodeJS의 Koa 프레임워크와 Serverless HTTP를 사용한 간단한 API 서버 배포하기!
직접 서버를 개발하고 배포하는 일은 많지 않지만, 최근에 간단하게 할 일이 있었는데요.
생각난 김에 간단하게 적어보려 합니다! 긔긔~
소시민 개발자이기에 매년 AWS의 프리티어 유목민 생활을 하고 있는데, 얼마 전에 새로운 프리티어로 이민을 왔는데, AWS에서 300달러 크레딧 준다고 해서 신나서 열심히 신청했는데, 크레딧 안 준다고 연락 와서 괘씸해서 앞으로 AWS 포스팅 안 하려고 했지만… 은 TMI
시작은 보안 그룹! 우선 앞서 이야기한 대로 ELB와 Lambda를 사용할 거니까 두 개의 보안 그룹을 만들 거에요. 간단하게 만들 거라 SSL은 쓰지 않을 거니까 ELB의 보안 그룹은 모든 외부 HTTP 통신 접근을 허용하는 보안 그룹을 만들고, 해당 ELB 보안 그룹에서만 인바운드 할 수 있는 Lambda 보안 그룹을 만들 거랍니다.
보안 그룹은 EC2 서비스에 있고, 왼쪽 메뉴 중(1번) ‘보안 그룹’을 선택한 후 오른쪽 위쪽의(2번) ‘보안 그룹 생성’ 버튼을 눌러서 생성합니다.
위 이미지처럼 보안 그룹의 이름을 정해주고 인바운드 규칙을 모든 위치의 HTTP 연결을 허용해 주고 아래의 ‘보안 그룹 생성’ 버튼을 눌러줍니다! 그리고 이번엔 Lambda에서 사용할 보안 그룹도 만들어 줄게요.
아까 만들었던 것처럼 보안 그룹 이름을 정해주고 이번엔 인바운드로 조금 전에 만든 ‘test-elb’라는 보안 그룹을 허용해 주고 ‘보안 그룹 생성’ 버튼을 눌러 생성해 줍니다.
엄청청 간단하게 Koa 서버를 만들어 볼게요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
const Koa = require("koa"); const Router = require("koa-router"); const cors = require('@koa/cors'); const router = new Router(); const app = new Koa(); app.use(cors()); router.get('/test1', (ctx) => { ctx.body = 'hello'; }); router.get('/test2', (ctx) => { ctx.body = 'world'; }); app.use(router.routes()); app.listen(4000, () => { console.log(`Server is running on port 4000!`); }); |
하지만 우리는 Lambda에서 함수로 사용해야 하니까 그냥 이렇게 Lambda에 배포하면 안 돼요.
직접 해보진 않았지만.. 의식의 흐름대로 생각해보면 이대로 Lambda에 올리게 되면,
가령 ‘domain.com/test1’ 라는 요청을 왔을 때
Lambda는 서버를 열고 아무것도 응답해 주지 않으니 404를 응답하게 되지 않을까요??
그래서 우리는 이제 Node의 프레임워크인 Serverless의 플러그인인 Serverless HTTP를 사용해서 수정해 줄 거예요. Serverless HTTP 플러그인은 아주 간단해요. 공홈 적혀있는 간단한 예를 적어보자면,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
const serverless = require('serverless-http'); const Koa = require('koa'); // or any supported framework const app = new Koa(); app.use(/* register your middleware as normal */); // this is it! module.exports.handler = serverless(app); // or as a promise const handler = serverless(app); module.exports.handler = async (event, context) => { // you can do other things here const result = await handler(event, context); // and here return result; }; |
이제 위 예를 참고해서 코드를 수정해 줄 거예요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const serverless = require('serverless-http'); const Koa = require("koa"); const Router = require("koa-router"); const cors = require('@koa/cors'); const router = new Router(); const app = new Koa(); app.use(cors()); router.get('/test1', (ctx) => { ctx.body = 'hello'; }); router.get('/test2', (ctx) => { ctx.body = 'world'; }); app.use(router.routes()); module.exports.handler = serverless(app); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// package.json { "name": "test-api-server", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node ./index.js" }, "repository": { "type": "git", "url": "git+https://github.com/falsy/blog-post-example.git" }, "author": "falsy", "license": "WTFPL", "bugs": { "url": "https://github.com/falsy/blog-post-example/issues" }, "dependencies": { "@koa/cors": "^3.1.0", "koa": "^2.11.0", "koa-router": "^8.0.8", "serverless-http": "^2.5.0" } } |
간단하죠??
이제 Lambda를 만들어서 위 소스를 넣어줄 거예요.
AWS에서 Lambda 서비스로 이동해서 ‘함수 생성’ 버튼을 누르고 위와 같이 함수 이름을 정해주고 ‘함수 생성’ 버튼을 선택합니다.
이 글은 아주 단순한 퀵 스타트이기 때문에 아래의 ‘역할’ 부분은 생략할게요. 실제 서비스에 사용하신다면 그에 맞는 Role을 만들어서 설정해 주세요. (기본값은 lambda 역할로 새로 생성됩니다.)
그리고 아까 만들었던 Koa – serverless-http 프로젝트 폴더를 zip 파일로 압축해서 람다에 업로드해줍니다.
(node_modules 포함)
짜잔! 그럼 아래와 같이 코드가 추가된 걸 확인하실 수 있을 거예요.
이제 거의 다 왔답니다! 마지막 로드밸런서 만들기!
AWS의 EC2 서비스로 이동해서 왼쪽 메뉴의 로드밸런서를 선택한 후 ‘로드 밸런서 생성’ 버튼을 선택합니다.
유형으로는 Application Load Balancer (HTTP / HTTPS)를 선택할 거예요.
로드 밸런서의 이름을 정해주고, 가용 영역의 VPC와 서브넷은 기본 값으로 설정한 후 ‘다음: 보안 설정 구성’ 버튼을 선택해 줍니다.
이쯤 되면 VPC와 서브넷에 대해서 이야기를 해야 할 것만 같지만, 이 부분은 다음 기회에…
HTTPS를 사용하라는 안내 문구는 살포시 넘기고,
(만약 실제 서비스라면 요즘은 HTTPS는 기본적으로 사용하는 게 좋겠죠? AWS에서는 ACM(AWS Certificate Manager)에서 SSL인승서를 편하게 발급받아 사용할 수 있답니다. 이 부분도 다음에 기회가 된다면..)
다음 보안 그룹은, 역시 아까 처음에 만들었던 ‘test-elb’라는 보안 그룹을 선택해 줍니다.
그리고 로드벨런서의 대상 그룹을 만들어 줍니다, 대상 유형은 Lambda 함수로 설정할게요.
음… 그러니까, ELB – Lambda 또는 ELB – EC2 이런 식으로 바로 연결되는 게 아니고 중간에 대상 그룹을 설정해서 ELB – 대상 그룹 – Lambda 또는 ELB – 대상 그룹 – EC2 이렇게 되어 있어서, 언제든 대상 그룹을 통해서 ELB의 대상 값을 변경할 수 있답니다.
이런 부분들이 OOP 적이면서 또, MSA의 강점이겠죠?
대상으로 아까 만들었던 Lambda 함수를 설정해 주면 끝!
‘test-api-server-lb’ 라는 로드 밸런서가 만들어졌고 현재 ‘provisioning’ 상태네요. 그리고 DNS 이름은 A 레코드로 ‘test-api-server-lb-336024832.ap-northeast-2.elb.amazonaws.com’라고 만들어졌네요.
이제 조금 기다리면 상태 값이 ‘active’로 변경될 거예요.
방금 만든 로드 밸런서가 active 상태가 되면 로드 밸런서가 우리가 만든 koa – serverless http로 구성된 Lambda 함수를 잘 호출하는지 테스트해볼가요?
앞서 발급받은 DNS URL을 브라우저에서 붙여넣기 하거나 터미널에서 cURL로 확인합니다.
1 2 3 4 |
$ curl test-api-server-lb-336024832.ap-northeast-2.elb.amazonaws.com/test1 # hello $ curl test-api-server-lb-336024832.ap-northeast-2.elb.amazonaws.com/test2 # world |
짠! 날이 밝았습니다…