serverless를 활용하여 간단한 크롤링 서비스 AWS Lambda에 배포
2020년 06월 16일

서론

just1s 토이 프로젝트를 진행하면서 한가지 불편한 기능이 있었는데, youtube 링크를 넣고 미리보기 까지는 가능하나, 아티스트와 제목은 수동으로 입력해야 한다는 점이었습니다. 물론 수동으로 입력하는 게 기본적으로는 맞지만 youtube 페이지 하단을 보면 일부는 영상에 사용된 음악 정보가 나옵니다. 이 정보를 파싱하여 자동으로 입력할 수 있다면 deck 추가 시 생산성 및 편의성을 높일 수 있지 않을까 생각했습니다.

puppeteer를 활용한 크롤링

puppeteer는 node.js 진영에서 크롤링에 가장 많이 사용하는 라이브러리로써, chrome 혹은 chromium 엔진을 headless로 동작시켜 크롤링에 사용합니다.

사실 puppeteer 같은 경우 레이블그룹 재직 시절에도 일부 사용했었습니다. 카톡 등 메신저에서 처럼 링크 공유 시 썸네일, 타이틀 표시 기능, 각종 패션 쇼핑몰 크롤링 등 자잘하게 사용했었습니다.

youtube 페이지 같은 경우 script 쪽을 찾아보면 window["ytInitialData"]에 json object 가 선언되어 있는데 이 정보 찾아 내려가면 음악 정보가 있습니다.

key로 youtube의 videoId를 받아 해당 json을 파싱하여 결과를 반환하는 매우 간단한 서버를 만들었습니다. 아래 링크를 참고하여 작업했습니다.

AWS Lambda에서 Puppeteer로 크롤링 하기

lambda, serverless

이를 이제 배포하여 사용할수 있도록 해야 하는데 ec2에 생으로 올리기에는 이미 클러스터로 사용하고 있고, 또 컨테이너화 시켜 ECS 클러스터에 배포하기도 애매해서, lambda에 배포해 보기로 결정했습니다. 또한 직접 배포할 수도 있지만 serverless를 통해 배포를 어느정도 자동화 시켜보도록 하기로 했습니다.

여기서 serverless에 대해 조금 더 언급하자면, serverless 자체가 개념적인 단어이기도 하면서 동명인 serverless 프레임워크가 그 중 유명합니다. serverless의 개념적인 뜻으로는 서버가 없다는 뜻이 아니라 서버 구축 관리에 대한 고민이 없다 라고 생각하면 편할 것 같습니다.

The Serverless Application Framework | Serverless.com

serverless 프레임워크는 AWS 뿐만 아니라 GCP, Azure 등 다양한 플랫폼을 지원합니다.

간단한 사용법으로는

  1. npm i -g serverless 로 serverless를 설치
  2. serverless config credentials --provider aws --key <AWS IAM 키> --secret <AWS IAM 시크릿> 으로 aws credential 정보를 cli 상에서 사용할 수 있도록 처리
  3. sls create -t aws-nodejs -p <프로젝트명> 로 프로젝트를 생성. ( sls = serverless )
  4. 기능을 function으로 정의 후 serverless.yml을 정의. start를 call 하면 src/index.handler function이 실행
  5. sls deploy로 배포

여기까지 따라하면 일반적 상황에서는 문제 없이 배포가 가능합니다. 여담으로 저는 IAM permission 이슈로 바로 배포를 할 수 없었는데 당시에 실수로 aws key를 넣은 테스트 코드를 커밋한 적이 있어서 aws에서 이를 차단하는 permission을 추가했는데 이를 인지 못해서 삽질을 조금 하긴 했습니다. permission은 당연히 "allow"만 있는 줄 알고 "deny"가 있는 줄 몰라 일어난 해프닝이었습니다.

DO_NOT_REMOVE로 끝나는 permission이 AWS에서 자동으로 추가한 permission입니다. 여기 iam:createRole등을 막는 정책이 포함되어 있었습니다.

이 이슈를 발견하게 된 계기는 policy simulator라는 페이지를 우연히 발견하고, 여기에 정책을 선택에 이것이 허용되었는지, 제한되어 있다면 어떤 정책이 막고 있는 지 등을 확인해 볼수 있는 기능이 있어 발견하게 되었습니다.

어쨌든 원래 주제로 돌아와, 관련 이슈를 해결하고 정상적으로 배포한 모습입니다. serverless가 serverless.yml 파일 기반으로 AWS CloudFormation yml을 생성하고, 그 cloudformation을 통해 S3 bucket에 배포, Lambda에 연결, API Gateway 연결 등을 하여 실행시키는 모습입니다. 좀 더 light-weight하게 구성하려면 serverless가 cloudformation을 생성하지 않고 lambda function에 바로 배포하게 할 수도 있지만 우선은 권장되는 기본 옵션으로 진행했습니다. production에 실제 적용하기 위해서는 serverless보다도 cloudformation, API Gateway, Lambda에 대한 추가적인 공부가 필요할 것으로 보입니다.

결론 및 또 다른 고민

just1s 프로젝트의 기존 back-end, front-end는 docker container 기반으로 ECS cluster를 통해 배포했고, 지금 수행한 serverless 기반의 lambda로 배포했습니다.

사실 기존의 방식으로 구축한 이유는 docker, container, orchestration을 어느 정도 공부해보고 싶기도 했고, 근본적으론 작성한 코드가 어디서든 같은 인프라 위에서 동작을 하게끔 하고 싶은 의도에서 비롯된 것이었습니다. ( It Works on My Machine 방지 )

직접 해보니 이렇게 serverless 기반으로 배포해도 내가 의도했던 것과 비슷한 그림이 나옵니다. 결국 Infrastructure as Code 니까.

  • 명세
    • dockerfile, docker-compose.yaml, AWS ECS task definition, AWS ECS service
    • serverless.yaml, AWS Cloudformation
  • 배포
    • AWS ECS cluter + Docker container
    • AWS lambda

이렇게 되어 또 고민이 생겼는데 언제 serverless로 배포하고, container로 배포할지에 대한 고민이었습니다. 이에 대한 이슈는 검색해보면 여러 글이 많습니다.

공통적으로 언급되는 점은 규모가 작고 접속이 일정하지 않고 scale 걱정을 하지 않아도 되는 간단한 서비스는 serverless로, 그 반대의 경우 및 서비스가 돌아가는 enviroment를 더 제어하고 싶을 떼에는 container에 배포하는 것을 권장하는 듯 합니다.

그러한 점을 기반으로 just1s 프로젝트의 배포 구조를 보면 웹 서버 같은 경우는 container 기반, 파서와 같은 서비스는 serverless로 배포했으니 나름 worst practice는 피한 구조라고 할 수 있지 않을까 생각합니다.