AWS를 이용해 만든 .dev 블로그 한달 비용

noname2048·2021년 4월 15일
8
post-thumbnail

클라우드는 벡엔드 개발자로써 언제나 관심있는 분야의 주제이긴 했습니다. 지금은 Google, AWS, Naver 등에서 클라우드 서비스를 제공하고, 또 기간이 제법 오래된 만큼 기업들은 안정적이고 편리한 기능들을 많이 이용하는 것 같습니다. 그런 와중에 개발자 포트폴리오를 만들면서 클라우드 경험을 해보고자 짧은 한달 남짓한 AWS를 이용하면서 겪었던 일을 작성하려고 합니다.

시작은 언제나 흥미에서

제가 관심있던 44bit 블로그에서 글을 읽다가, .dev 라는 최상위 도메인(Top Level Domain)의 등록이 가능하다는 글을 읽었습니다. 개발자로써 블로그를 직접 만들어 운영해보고 싶던 저에게는 dev 도메인은 도전해보고 싶은 과제 였습니다. 물론 블로그에 커스텀 마크다운 디자인과 코드 블록, 폰트와 더블어 여러가지를 시험해보고 싶긴하지만, 아는게 많이 없어 자신이 없었던 저는 우선 게시판을 먼저 만들기로 하였습니다.

개발자라면 탐나는 .dev 최상위 도메인 등록 시작 (44Bits) 읽으러 가기

.dev 도메인은 의외로 AWS에서는 등록 할 수 없었습니다. 44bit 블로그 지원하는 4개의 회사에 개인적으로 익숙하게 사용하는 회사가 나오지 않아서 개인적으로 많이 아쉬웠습니다. 그렇지만 덕분에 외국의 유명한 도메인 관리 사이트인 Namecheap, Porkburn과 같은 서비스를 알아보고 공부할 수 있는 기회가 되었습니다.

네임칩을 처음 알려준 블로그: 해외 도메인 구매 사이트 추천 및 도메인 구입 시 주의사항 읽으러 가기

여러가지 서비스가 있지만, 아직 돈을 본격적으로 벌 수 없는 처지라, 아무래도 싼 값이 좋은것 같아 여러가지 알아보던 도중, 인터페이스가 직관적이고 가장 많은 사람들이 사용하는 것 같은 Namecheap을 선택하게 되었습니다. 많은 사람이 쓴다면 커뮤니티나 한국에 관련 블로그에서 도움 받기도 쉽고, 문서화가 잘 되어 있을거라 생각하였습니다. 영어에 자신이 있거나, 더 싼 서비스를 찾고자 하시는 분은 Porkburn 과 같은 서비스를 조심스럽게 추천드려봅니다.

https(443) 통신을 위한 험난한 여정

여차저차 블로그 글과 문서를 통해 제 아이디가 들어간 .dev 도메인을 얻어냈습니다. 12$ 정도), 하지만 아직도 갈길이 멀었습니다. dev 도메인은 https 만 지원하도록 약속되어있습니다. (브라우저단에서 http를 https로 바꾸도록 되어있습니다.) 물론 처음부터 https를 지원하는 블로그를 만들고 싶었긴한데, 처음에 생각하던 것과는 달리 오래 걸렸던 것 같습니다. (생각보다 과정이 길었어요 ㅠ)


예시로 들고온 한국교통안정공단의 홈페이지와 같은 경우, http 통신을 하면 위와 같이 보안에 문제가 있다고 경고하고 있습니다. 최근에 브라우저 트렌드에 따라 바뀐 것이기 하지만, 오래전부터 개발자 그룹과 커뮤니티는 https 의 사용을 권장해왔습니다. 대부분의 유명한 사이트의 경우 http로 통신을 시도해도 자동으로 https로 자동 리다이렉트 되는 것을 확인 할 수 있습니다.

그러면, https 통신을 위해서 중요한건 무엇이 있을까요. 바로 SSL 인증서 입니다. tcp 통신에서 ssl 레이어를 추가로 부여해 클라이언트가 서버가 암호화를 통해 인증을 하는 과정을 SSL인증서를 통해 진행합니다. 인증서를 등록하려면, 신뢰하는 기관 (Certificate Authority)에게 인정받아 사이트의 제공자가 안전함을 증명해야합니다. 이 인증서를 발급하는 대표적인 기업으로는 IdenTrust, DigiCert Group, Sectigo, GoDaddy Group, GlobalSign등이 있고, 무료 서비스를 찾는 사람들에게 잘 알려저있는 Let’s Encrypt SSL 과 같은 기업들이 있습니다.

예전에 Let's Encrypt SSL을 사용했던 경험에 비추어 보자면, 무료이지만, 도메인을 사용중인 서버 운영체제에 사이트가 제공하는 프로그램을 설치하여 자동갱신하거나, 90일동안 관리하지 않으면 인증서가 무효가 된다던가 하는 귀찮은 관리 프로세스가 존재했습니다. 다만 무료인만큼 필수라고 생각하지만, 좀 더 편리한 서비스를 찾고 싶었습니다.

(만약 .dev 도메인을 사용하지 않아 등록과 호스팅을 모두 AWS에서 진행했다고 한다면, AWS는 오래전부터 load blance를 사용할 경우 자동으로 ssl 통신을 지원하도록 요청하는 기능이 있으니 살펴보시면 좋겠습니다.)

Namecheap에서는 어떻게 관리하는지 궁금하기도 했고, 와일드 카드를 사용하는 도메인이 지원되지 않지만 가장 싼 SSL 서비스가 6$에 1년을 지원하기 때문에 오랜기간 블로그를 유지하는데에는 적합하다고 생각했습니다.

네임칩 인증서 가격 정책

OpenSSL을 이용한 CSR 발급받기

CSR은 Certificate Signing Request로, SSL 발급기관에게 사이트와 정보를 통해 모종의 정보를 적어, 암호키로 암호화 한뒤 발급기관에 제출하는 양식을 말합니다. CSR에 들어가는 정보는 다음과 같습니다.

  • Country name: use a valid 2-letter country-code.
  • State of Province: Use your state or Province name, or use the Locality name if you have none.
  • Locality name: use your city, town or other locality name.
  • Organization Name: use your company/organization name or put NA (Not Applicable).
  • Organizational Unit: use your unit or department name or put NA (Not Applicable).
  • Common Name: Fully qualified domain name you need to secure: for example, www.example.com

제 경우에는 다음과 같이 작성했습니다.
Subject: C = KR, ST = Seoul, L = Dongjak, O = noname2048, OU = Dev Team, CN = noname2048, emailAddress = sungwook.csw@gmail.com

약간 다르긴 하지만, Common Name의 경우 www.noname2048.dev 를 사용했었습니다. (현재 비용문제로 AWS에서 내려가 있습니다 ㅠ)

여하튼 openssl을 이용한 CSR 정보를 만들어 Namecheap 에 넘겨주는 것은 공식문서를 따라 편하게 진행할 수 있었습니다.

(namecheap 공식문서): 네임칩에 csr 작성하여 요청하기

CSR을 정상적으로 넘겼다면, SSL 인증서, Private key,그리고 Certificate chain 3가지를 전달 받게 됩니다.

이렇게 인증서를 정상적으로 만들었다면, 이게 실제 서버에 적용되어 사용하고 있는지를 Namecheap에서 증명해줄 것을 요청합니다. 보통은 정보에 기재된 메일로 인증을 묻는 간단한 인증도 있겠지만, 가장 최상단에 있고, 추천하는 인증방식은 DNS를 통한 인증방식입니다.

DNS 설정으로 SSL 인증하기

보통 도메인 업체에서 도메인을 구입하고 나면, 도메인 업체가 가지고 있는 네임서버에 등록하거나, 다른 클라우드 서버에 이 도메인을 DNS에 등록하게 됩니다. 이 과정에서 www.noname2048.dev 와 같은 주소를 실제 ipv4주소로 변환하는 과정을 거치게 되는데, 이때 참조하는 서버가 DNS 입니다.

클라이언트가 도메인 네임을 가지고 서버를 방문하기 위해서는, DNS 서버에 도메인을 특정한 ipv4로 변환할 수 있게 기재해야합니다. AWS에 Route53 서비스를 통해 호스팅을 시작하면, 자동으로 AWS가 이 기록을 저장할 네임서버 4개를 디폴트로 만들어 주게 됩니다. (이 경우, 도메인 제공사 설정에서도 다른 NS-네임서버를 이용한다고 설정해주는 것이 좋습니다.)

이 네임서버에서 noname2048.dev를 ipv4로 변환할 수 있도록 A 레코드를 만들어서, 해당 ipv4로 를 기재하면 됩니다.

이때 Namecheap은 랜덤한문자열.noname2048.dev 로 접속을 시도 했을때, Namecheap 이 제시한 사이트로 리다이렉트 되는지를 검사 하여 인증을 진행합니다. 이 제시한 사이트는 namecheap의 인증서 및 관리의 파트너인 comodo 사의 특정 랜덤한문자열.comodoca.com 으로 연결되는 사이트 입니다.

이를 진행하려면, 특정 소도메인을 ipv4가 아닌 다른 문자열로 바꿔주는 CNAME 레코드를 기재하여 작성하면 됩니다.

그리고, Activate를 누르면 다음 창이 뜨게 됩니다.

만약 인증서에 문제가 생길경우 reissue 를 통해서 언제든 인증서를 재발급 받으 실 수 있으니 걱정하지 마세요. (이 정보를 어떻게 알았냐구요? 저도 알고 싶지 않았어요...)

주의: (CSR을 만드실때 이용하는 PrivateKey 는 SSL 암호화를 AWS ALB 통해 관리하실 경우 대중적인 RSA 방식을 사용하세요.) 다른 블로그와 함께 참고하다가 RSA대신 복잡한 타원곡선 암호를 이용하면 암호화가 더 좋다길래 타원 암호화를 했다가, 인증키의 크기가 2배가 되어 ALB에 등록이 안되는 사태가 일어나 영문을 모르고 해당 인증을 여러번 시도했습니다.

AWS EC2 우분투로 서버 인스턴스 올리기

EC2 관련 설정 내용은 이미 많이 알려져 있어 요즘에는 정보 구하기가 쉬운것 같습니다. 여러 기타 코딩학원이나 학생들사이 에서도 요즘은 EC2를 많이 이용하는 것 같습니다. 저는 학부생때 접해서 지금까지도 잘 사용하고 있는 ubuntu 를 운영체제로 선택하여, Django를 올려두었습니다.

서버 내부에는 Nginx <-port-> (docker)Gunicorn <-uwsgi-> (docker)Django를 통해 간단한 production 환경의 인덱스 페이지를 작성해 두었습니다.

AWS ALB만들기

ALB를 사용하는 데까지는 여러가지 고민이 필요했습니다. AWS에서는 기존에 잘 활용되어 오고있던 Classic load Balancer 를 두고, ALB와 NLB를 새로 도입하여 서비스를 제공하고 있습니다.

기존에 CLB를 썼었지만, AWS가 계속 홍보하고 있는 ALB와 NLB가 있는데, ALB를 사용해 보고 싶기도 하고, 나중에 따로 서브도메인이나 웹소켓을 활용하게 되면, 해당 라우팅만 따로 떼어 지정할 수 있는 점이 편해보여 ALB를 적용하게 되었습니다.

VPC와 외부게이트웨이

ALB를 만들어서 EC2에 적용한뒤, apt-get을 작성해 보았는데... 외부 인터넷에 접속이 되지 않습니다. 그 이유를 검색하다보니, ALB를 생성하기 위해 만들었던 임의의 VPC에 인터넷 게이트웨이가 달려있지 않아 발생한 문제였습니다. CIDR 표기법으로 VPC를 처음 만들어 보았었는데, VPC에 인터넷 게이트웨이를 달아야 인터넷을 접속할 수 있다는 것은 처음 알았습니다.

(처음 사용하시는 분들은 AWS가 default로 작성해준 VPC에 인터넷게이트웨이가 세팅되어 나올 수 있습니다. 저는 기존의 VPC를 커스텀하고 싶다는 생각에 잘 모르면서 패기롭게 삭제해 버려서 그렇습니다.)

여하튼 게이트웨이를 달아주고 나니 다시 apt-get이 정상적으로 EC2에서 작동됩니다.

AWS ALB에 SSL인증서 등록하기 (AWS Certificate Manager)

본래라면 ALB에 SSL을 직접등록 할 수도 있지만, AWS는 AWS Certificate Manager을 이용해 등록하기를 권장하는 것 같습니다. ALB 작성시에 올라갈 인증서를 등록하는 선택지에는 4가지 선택이 있는데요.

  • CM에 등록된 인증서 사용하기 (권장됨)
  • CM에 새로 인증서 등록하기 (권장됨)
  • 이미 등록된 인증서 사용하기
  • 직접 새로 등록하기

관련 등록은 대중적인 RSA 방식으로 암호화가 진행된 인증서를 사용한다면 (지금의 경우에는 namecheap 인증서) 공식문서를 통해 무리 없이 진행하여 인증서를 적용 할 수 있습니다.

namecheap 공식문서: aws loadbalancer에 ssl 등록하기

해당 인증서를 등록하고 나면, ALB에서 정상적으로 443 포트를 listen 하면서 ec2에 정보를 보내주는 지 확인하면 됩니다.

RDS와 S3 붙이기

프로덕션 레벨에서 쓰일 RDS는 mysql의 오라클 인수 이후 postgresql 쓰는 추세인것 같습니다. 최신버전 (12.5)의 AWS RDS(postgresql)를 만들어서, 장고 공식문서에 사용된 postgresql 지원 문서에 따라 psycopg2를 의존관리에 추가하여 사용하였습니다. 가장 비용이 많이 드는 부분입니다.

정적파일 서빙은 전통적으로 nginx가 해주지만, S3를 연결하면 nginx 없이 django-storage만 가지고 작동이 가능합니다. 다만, collectstatic 으로 올린 static 파일을 사이트 도메인단에서 접근하기 위해서는 public 설정은 필수입니다. 더불어 CORS 설정도 같이 해줘야 합니다.

다른 한편으로 redisaws elasticache 로 올려보고 싶었지만, 프리티어가 아닌 입장에서는 슬슬 비용이 고민이 되는 시점까지 와버려, redis를 접목시키지는 못했습니다. 다음 프로젝트를 할 때 로컬에서 고민하도록 해야할 것 같습니다.

CI/CD 적용하기

뿐만아니라 요즘은 벡엔드의 기본 소양(?) 으로 여겨지고 있는 CI/CD도 공부할겸, git push 를 하면 테스트와 배포까지 자동으로 이뤄지도록 스크립트를 작성해보았습니다. 과정이 길고 복잡해서 기회가 된다면 다른 포스트로 작성해보도록 하겠습니다.

CI/CD 과정을 CircleCIAWS CodeDeploy 이용해 구축하였습니다. AWSCLI2 업데이트 및 CodeDeploy를 적용시키는 과정이 쉽지 않았었습니다. 특히 appspec.yml을 공식문서를 따라 읽으면서 작성할때 시행착오가 있었습니다. 4가지 hooks (BeforeInstall, AfterInstall, ApplicationStart, ValidateService)를 모두 작성해야 했지만, ApplicationStart와 ValidateService만 일단 작성했습니다.

CD는 blue-green 처리를 nginx의 upstream을 활용했는데요. docker-compose 위에서 돌아가는 gunicorn 앱을 각각 8001번과 8002번 포트에 매칭하여, 번갈아가면서 bind 되면, nginx가 load balance를 적용하게 됩니다.

circleci의 가격 정책
circleci docs, 공식문서

circleci 에서 main branch 만 필터링 하여 테스트를 진행하는데, 도중에 fail이 뜨면 메일로 따로 알림이 오게됩니다. slack, jira와도 연동 할 수 있는것 같습니다.

circleci에서 미리 작성해둔 함수들을 라이브러리 처럼 yaml 파일에서 이용 할 수 있는 orbs 를 적당히 활용하면, 쉽게 codedeploy와 연동할 수 있는데요, ci가 마무리 되면, codedeploy에서 github repo를 바로 넘겨 받는 명령어는 다음과 같습니다.

orbs:
  aws-cli: circleci/aws-cli@1.4.1

jobs:
  django_prac_test:
    - deploy:
        name: aws deployment
        command: |
          cd ~/project
          export LATEST_MAIN_SHA1=$(git rev-parse HEAD)

          aws deploy create-deployment \
          --application-name django-prac-004 \
          --deployment-group-name askbanana \
          --github-location repository=noname2048/django-prac-004,commitId=${LATEST_MAIN_SHA1}

codedeploy 설정하려면 AWS Systems Manager를 이용해 codedeploy-agent를 ec2에 미리 설치해야합니다. 정기적으로 이 agent를 업데이트 하거나, 딱 한번만 설치해서 업데이트를 하지 않거나 할 수 있습니다.

설정이 완료되면, 명령어를 받은 codedeploy는 github에 있는 appspec.yml 파일에 따라서 해당 deploy를 진행하게 됩니다. codedeploy 중, 오류가 발생했다면 ec2에 있는 /var/log/aws/codedeploy-agent/codedeploy-agent.log 에서 찾아보거나, aws cloudwatch 로 연동하여 에러를 확인 할 수 있습니다. 아래는 빌드 마다의 기록입니다.

장고로 개발하기

이제 CI/CD가 끝났으니, 장고로 개발한뒤 git push만 한다면, 테스트 후 문제가 없다면 production 으로 바로 반영됩니다. 덕분에 개발 할때 재미있게 개발 했던것 같습니다.

(물론 그간의 삽질이 보상받을 정도로 제가 벡엔드 로직을 잘 짜는 건 아니지만요. 이하 생략. 아래는 위의 SSL 설치중 CSR이 잘 안풀려 노션에 적어놓고 하루종일 고민했던 흔적입니다.)

어디까지 개발했나

이후 codecov도 설치하긴 했지만 TDD는 거의 구현하지 못해서 coverage는 처음부터 계속 떨어지기만 할뿐, 올라가진 못했습니다.

제가 만든 게시판의 이모저모는 다음과 같습니다.

  • 1주 개발 환경 설정
  • 2주 CI/CD 구성하기
  • 2주 게시판, 사용자 만들기
  • 3주 AWS 연동하기
  • 4주 덧글과 좋아요 구현하기
  • 5주 디자인 다듬기 (tailwind, 트게더 클론해보기)
  • 6주 최적화하기 (반정규화)

게시글과 덧글 작성, 추천시스템, 조회수 확인, 소셜 로그인 정도까지 구현해봤던 것 같습니다.

그래서 비용은...?

아무래도 학생이다 보니, 비용문제가 중요하긴 했는데요, 프리티어에서 벗어난지 꽤 된 계정으로 진행하다 보니 조금 걱정이 되었었습니다.

지난달에는 47$, 이번달 15일까지 27$가 추가되었습니다. 도합 약 80$의 금액이 청구되었는데, 단순히 EC2, ALB, RDS 만 가지고 측정한 금액인데도 불구하고, 한달에 5만원 정도의 금액이 지출되는 것을 알게 되었습니다.

다만 만들었던 블로그는 아직 많이 미흡해서, 방문자가 거의 없는 관계로, 이 금액은 서비스만 연결하고, 테스팅 이외의 어떤 트래픽도 없었을때라는 점 참조해 주시면 좋겠습니다.

어쩌니 저쩌니 일단 비용이 부담이라 블로그는 내리고, 다른 방안을 찾아보기로 했습니다.

만들었던 django-prac-004 코드보기

다음계획은 소규모로...

처음에는 AWS를 이용해보고 공부하자는 목적으로 서비스를 만들게 되었는데, 생각보다 공식문서가 잘 되어있어, 영문에만 좀 익숙하면 다른 문서와 같이 참고하여 서비스를 연결하기 쉽다는 점을 알았습니다.

그럼에도 불구하고 AWS 내부의 구조와 서비스 자체를 이해하고 있어야, 서비스 활용도가 높고, 또 네트워크 지식의 활용도가 매우 높다는 것을 깨달았습니다. 토이프로젝트의 필요성을 많이 느끼는 대목이였던 것 같습니다.

프리티어를 벗어나게 되면, 생각보다 비용이 많이 듭니다. 비록 컴퓨터를 사는 것 보다야 싸겠지만. 서비스를 구축하게 되면 아무래도 옮기기가 쉽지 않은것도 프리티어를 제공하는 이유가 아닐까 생각합니다. (다른 방법을 못 찾으면 새로운 프리티어를 구해봐야 겠네요.)

그래서 다음에는 그냥 프론트를 좀 더 열심히 공부해서 github pages를 이용하거나, ec2 두개를 올려서 한쪽에 was, 다른쪽에 rds, redis, nosql 등을 올려 사용할 것 같습니다. 아니면 micro web service인 lambda를 이용하거나요. (어쨋든 .dev는 구입했으니 활용해야 합니다.) ALB의 경우에도 공부는 하고 싶지만, ec2 한대를 이용하는 이상 nginx만 사용하는게 비용부담이 덜합니다.

나중에는 k8s를 공부해서 eks로 한번 시도해보고, 그전까지는 열심히 강의를 들어야 할 것 같습니다. 긴 글 읽어주셔서 감사합니다.

profile
설명을 쉽게 잘하는 개발자를 꿈꾸는 웹 개발 주니어

2개의 댓글

comment-user-thumbnail
2022년 12월 9일

하아... dev 도메인 사고 일주일삽질했는데 ssl만되는군요... 너무 허무하다...

1개의 답글