IT

django와 aws elb사용 시 주의해야할 사항

紫紅 2019. 1. 23. 14:09
반응형

 이번 Django 웹 애플리케이션 개발 및 AWS에 배포를 하며 어마 무시하게 많은 지식을 습득하였다. 만 2개월이 넘는 시간동안 삽질을 정말 많이 하였는데, 나와 같은 어려움을 겪는 사람이 없길 바라며 글을 올린다.


 Django의 경우, sns소셜 로그인 기능 구현이 매우 쉽다. social-auth-app-django라는 패키지를 받은 후, settings.py에 등록해주고, 인터넷보고 따라 만들면 된다. 따라서 social-django의 사용법이나 django, python 등의 내용은 이번 포스트에서 다루지 않을 것이다.


 내가 겪은 문제는 크게 두 가지였는데 첫째는 django애플리케이션을 aws에 배포하는 것, 둘째는 배포 이후 facebook api와 같이 https프로토콜 사용을 강제하는 것에 있었다.


 첫번째 문제부터 소개하겠다. 처음 주변 지인들의 추천으로 「Django 애플리케이션을 Elastic Beanstalk에 배포」 https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/create-deploy-python-django.html를 보고 elastic beanstalk(이하 eb)라는 서비스를 이용하여 따라 배포를 시도했다. 당연한 얘기겠지만, 동작하지 않았다. 처음 실습목적으로 했던 배포까지 포함해서 40몇 차례 이상은 시도했지만, 그중 정상작동했던 것은 단 1회에 불과했다(아마 RDS인바운드 규칙 안 열어줘서 안된 경우도 있을 듯하다).

 나만 그런가 싶어 인터넷에 수차례 검색해보았지만, 나 외에도 많은 사람이 eb에서 발생하는 문제에 대해 뚜렷한 결론을 내리지 못한 것으로 보아, django를 eb으로 배포하는 것은 별로 바람직한 선택이 아니라고 말하고 싶다.


 특히 django를 나처럼 windows환경에서 개발한 사람이라면 더더욱 eb을 쓰지 않을 것을 권한다. 그 이유는 eb내부에서 pip install -r requirements.txt를 실행시키는데에 있다. windows환경에선 전혀 문제없이 돌아가던 pip install -r requirements.txt명령이 linux(EC2 ubuntu)환경에선 생각보다 많은 오류를 토해냈다. eb도 linux환경으로 구성되어있으므로 아마 똑같으리라 생각된다.

 파이썬환경과 가상환경을 따로 사용하는데도, 운영체제가 다르단 이유로 똑같은 모듈이 깔리지 않는다는 건 솔직히 납득하기 힘들다. 아마 내가 설정을 잘못해줬을 가능성도 있지만, 최소 python버전을 틀리진 않았다. 뭐가 문젠지 정확한 진단 내리기가 어려웠고, 그 밖의 여러 이유(EC2 windows server 2016판으로도 배포를 시도해보았으나, windows x64버전과 호환되는 wsgi도 별로 없었다)로 다음 번에 Django를 쓰게 된다면 그냥 linux운영체제에서 개발하거나 맥북을 쓰기로 마음먹었다.


 두번째 문제는 Facebook과 같은 https사용 강제형 api와 social-django, elb의 문제였다. AWS에서 제공하는 elastic load balancer이용하면 아주 손쉽게 공인인증서(SSL)를 받아 https프로토콜을 사용할 수 있다. 참고로 elb는 포트와 요청에 따라 해당 요청을 전달, 변경, 응답 등의 역할을 해준다.

 https를 사용하기 위해서 elb를 생성하고, elb에 규칙 두 개 정도를 설정해주면 된다. 


1. elb 80포트에 들어온 모든 요청을 자기 자신(elb)의 443 포트로 돌려주기 

2. elb 443포트에 들어온 모든 요청을 대상 그룹(원하는 대상, 나의 경우 EC2 ubuntu)으로 보내주기


이렇게 설정하고 나면, EC2는 80포트밖에 쓰지 않으나, 정작 외부에선 443포트로 밖에 접근하지 못한다. 외부에서 보기엔 분명 https이므로 문제될 것이 하나도 없다. 하지만 EC2의 social-django에서 외부로 보내는 요청과 그 콜백 받는 주소(redirection) 설정이 문제를 일으킨다. social-django의 facebook로그인 연동의 경우, 주소와 프로토콜 설정(http://~~~~~~.com/ 까지의 설정)은 was에게 맞기고 .com뒤에 오는 서버 파일 위치만 social-django가 담당하게 된다(/complete/facebook으로 결과를 받게 됨). was입장에선 사용자가 443이 아닌 80으로 들어온 것으로 간주하기 때문에(elb에서 무조건 80포트로 던져주니까), 따라서 콜백 요청 주소 역시 http://내서버EC2.com/comlpete/facebook이라고 적어서 facebook에 전달하게 된다.

 https를 강제하는 facebook에서는 http로 된 url을 등록할 수 없으므로, https를 사용하라는 경고와 해당 url은 등록되지 않았다는 두 가지 오류를 보내게 된다. 만일 elb에서 외부에서 보내는 요청 뿐 아니라, 역으로 내부에서 외부로 보내는 요청도 처리해줬더라면 해당 오류는 뜨지 않았을 것이다. 안타깝게도 그건 elb의 역할이 아니므로 Was에 인증서를 달아서 443포트를 사용하자.




 물론 해당 내용은 aws elb의 특성에 따른 문제점이므로 Django뿐 아니라, 다른 프로젝트에서도 충분히 발생할 수 있는 문제이다(node.js처럼 was를 쓰지 않는 경우엔 유연하게 대처가 가능할지도 모르겠다). 만약 facebook api와 같은 https강제형 서버와 통신할 일이 있다면, 반드시 elb를 이용하지 말고, was에 인증서를 달아서 해결하도록 하자. 어차피 elb 트래픽 이용료나 인증서 값이나 별 차이 없을 것이다.

반응형