EC2 프리티어에서 구동중이던 트위터 움짤 업로드 봇을 이번에 Lambda + scheduling + S3의 조합으로 바꾸기로 했다
올해 5월에 프리티어가 끝나면 EC2 의 t2.micro 인스턴스는 한달에 약 8달러가 소비되지만 lambda + S3로하면 하루에 12번의 람다함수 한달 약 360번 5초정도로 가정하고 S3를 약 1기가를 사용한다고하면 0.005달러
아이러니하게도 한달에 약 1기가*2 ( 움짤 360장에 약 1기가) 의 외부 데이터 송출 요금이 0.114달러로 다른 비용 다 합친 것 보다도 비싸다..
AWS의 데이터 트래픽 요금은 확실히 비싸긴 한 것 같다. 지금이야 0.1달러로 보이지만 서비스가 커질 수록 트래픽 요금이 막대해진다.
1. S3 관련 설정하기
먼저 S3버켓을 만든다
이 버켓은 계정 내부의 어플리케이션의 통신에서만 사용하기 때문에 모든 public access나 권한을 최소한으로 설정한다
파일 업로드에서는 그동안 하나하나 모아 온 움짤 폴더들을 업로드 한다.
업로드가 진행되는 동안 aws-cli로 이후 동기화를 해주는 코드 를 작성한다.
하나의 WSL에 복수의 aws credential을 셋팅하여 관리 할 수도 있지만 혹시라도 회사 계정과 섞여버리면 대참사가 일어나기에 Ubuntu 18.04로 추가로 설치하여 분리된 환경을 구축했다.
2. lambda 함수 작성
aws의 아주 멋진 서비스 중 하나라고 생각하는 lambda이다. lambda덕분에 정말 여러가지 서비스를 유연하게 제공하는 것이 가능하며 실무에서도 지긋지긋하게 사용중이다. 외부 요청에 대한 처리들은 물론이고 내부에서의 관리 심지어 내부 인스턴스들의 비용 최적화의 자동화까지 lambda를 이용하여 관리한다.
기존 코드를 python으로 작성했기에 python환경을 이용한다 ARM 아키텍쳐를 이용하면 약 25%더 저렴하지만 지금까지 x86환경에서 작동시켜왔기에 아마 ARM에서도 돌아가겠지만 안정성을 위해서 아키텍쳐는 유지하도록 하겠다
Permission은 우선 기본으로 새로운 role을 작성시킨다. 아마 이후에 S3 full access를 부여할 예정이다. ( 움짤의 중복 업로드 방지용 로그파일의 입출력을 위해 full access 아닐 경우 read_only )
python같은 스크립트 언어들은 lambda 인터페이스 안에서 바로 작성 후 적용이 가능하며 컴파일 기반의 경우에는 컴파일 한 파일을 압축파일로 올려야 한다.
간단한 테스트로 위와 같은 코드를 Deploy해서 Test를 해본다
위와 같은 test case를 작성하고 Test 버튼을 다시 누르면
위와 같은 결과를 볼 수 있다. Response는 최종 return이며 Function Logs는 말 그대로 로그이다.
테스트 케이스의 JSON 이 출력되어있는 것을 볼 수 있다. 이렇게 lambda는 여러가지 외부 요인을 JSON형식을 표방하는 데이터 타입 ( 언어마다 다를 수 있음 ) 으로 받아서 해당 데이터를 처리가 가능하다.
이번 움짤 봇은 시각이 땡 치면 혼자 사진만 올리면 끝이라 외부에서의 정보는 필요 없으니 event항목을 실질적으로 사용하지는 않는다
움짤 봇들의 코드 뭉텅이를 집어 넣어준다
이 때 main의 부분이 lambda_handler함수 내부가 되어야 한다.
트위터 API의 authentification 과정 등등과 하단의 자세한 코드들은 생략한다.
원래 로컬에서 받아오던 파일들을 S3에서 가져오도록 코드를 바꿔야한다.
외부에서 실행할 경우 AWS Credential을 environment variable에 등록 시키거나 인자로 넘겨 줄 필요가 있지만 계정 내부의 서비스에서는 그런 것들이 없어서 간편하다
3. lambda에 python 외부 라이브러리 추가하기
tweepy와같은 기본 라이브러리가 아닌 경우에는 인식을 못하기 때문에 lambda layer를 통해서 추가시켜 줘야 한다.
다음과 같이 tweepy와 같은 외부 라이브러리들이 설치되어있는 python이라는 zip파일을 작성한다
mkdir -p ipra_bot_layer/python
pip3 install tweepy -t ipra_bot_layer/python
pip3 install [외부모듈] -t ipra_bot_layer/python
cd tweepy
zip -r tweepy.zip python
왼쪽의 Additional resources / Layers 에서 해당 layer를 추가해주고
이렇게 custom layer를 추가해준다.
4. lambda에 tweepy credential 추가하기
secure하면서도 universal하게 관리하는 방법으로는 parameter store나 secret manager등등을 활용하는 방법이 있겠지만!
회사 일이면 그런 식으로 추진하겠지만!
귀찮으면 하드코딩을 하셔도 괜찮고 환경변수에 넣어도 괜찮습니다.
저는 환경변수에 넣겠습니다.
5. 코드수정
이제 본격적으로 새로운 구성에 맞춰서 코드 수정을 진행한다. 먼저 S3에서 파일을 가져오게 설정한다.
우선 우리의 lambda가 s3에 접근 가능하게 해야한다.
아니면 다음과 같은 에러를 본다
"An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied",
미리미리 설정하고 테스트하면 좋겠는데 맨날 테스트하고 아 맞다 권한! 하는 일상이다
configuratio - permission - rolename 을클릭하고 Permission policies에 S3에 필요한 권한을 적절하게 추가한다.
이번에는 해당 버켓에 대한 S3 full access를 부여했다.
이미지를 S3에서 트위터로 바로 전송이 가능하면 좋겠지만 못찾아서 lambda의 tmp폴더에 내려받아서 전송하는 방식을 채택해야 했다.
6. 정기적으로 갱신하게 지정
Add trigger에서 2시간마다 또는 cron형식으로 스케쥴링을 진행한다
이 경우에는 Eventbridge를 사용한다.
rate expression과 cron표기의 상세는 링크를 참고
7. 끝!
무사히 작동을 테스트했다.
lambda의 또하나의 장점은 timeout덕분에 예상치 못한 에러에 의한 네트워크 폭주를 자동적으로 막아준다는 점이다
이제 ec2의 cron은 종료하러 가야겠다.