AWS ANGULAR UNIVERSAL 배포

kdy·2023년 5월 2일
0

어쩌다보니까 앵귤러 SSR적용 프로젝트를 진행하게되었고 이를 AWS를 사용해 배포하는 과정에서 여러 문제를 만났고 결과적으론 여러방법중 한가지를 선택하여 해결하였다.

AWS를 처음 사용해보았고 용어또한 익숙하지못해 개념을 익히고 사용법을 익히는대 많은 시간을 사용하였다.

배포 방법

배포 방법은 총 3가지를 사용하였고 대부분의 시간은 serverless와 pipeline에 사용하였다. 아래 방법론 3가지를 사용해보았다.

  1. SERVERLESS LIB + API GATEWAY + LAMBDA + CLOUDFRONT +S3
  2. AMPLIFY +S3
  3. CODECOMMIT + PIPELINE + BEANSTALK +S3

Serverless LIB를 사용한 배포

앵귤러 유니버설로 작성한 node 서버를 배포과정에 올리는 방법론은 다양하였고, 첫번째로 전용 라이브러리가 존재하여 손쉬워보이는 방법을 사용했다.

하지만 이는 착각이였다.

내가 선택한 방법은 결과적으로 이런 구조 였는대, 웹서버의 역할(nginx) 및 로드밸런서(리버스 프록시 + 포트포워딩 ) 를 cloudFront+api gateway가 대신한다. 위 2가지를 통해 온 요청은 lambda가 받아서 지정해놓은 함수를 실행시키는대 이 함수는 결과적으로 s3에 빌드된 파일을 읽어서 SSR웹을 라우팅 해주는 역할을 한다.

이를 위해선 몇가지 요구사항이 있는대

  1. 각각의 서비스에 대한 권한 획득 및 권한 설정
  2. 각각의 AWS 서비스를 순서에 맞게 연결해줘야함.
  3. S3에 올릴 빌드된 앵귤러 유니버설 프로젝트

였고, 여기서 어려운건 1,3번이다.

1번은 어떤 IAM계정을 사용해 서비스를 실행할것이냐와, 서비스 자체의 권한을 어디까지 줄것이냐 2가지를 요구하였고, 이 범위를 설정하는대 상당히 힘이 들었다.

각자 정확히 어떠한 권한이 어떤 서비스에 요구되는지를 정확히 알아야 설정가능하였으며, aws를 처음 사용해본 나에겐 너무나도 많은 에러와 마주하게 되었다.

1번 과정 마지막에 알게되었지만 admin계정 권한으로 설정을 해주면 세세한 설정은 필요가없었다.

2번은 aws 각각의 서비스마다 cli로 서비스 인스턴스의 id값을 지정해줘서 연결을 하였다.

문제가 3번인대, 3번을 s3에 업로드하는건 쉽지만, serverless.yml파일을 통해 s3의 빌드된 파일을 lambda와 node서버가 소통하도록 만드는 설정이 여러 레퍼런스와 달라 굉장히 난해 하였다.

serverless.yml 파일

service: ngx-serverless-starter
plugins:

  • serverless-offline
    provider:
    name: aws
    runtime: nodejs14.x
    lambdaHashingVersion: 20201221
    memorySize: 192
    timeout: 10
    package:
    patterns:
    - "!/"
    - "node_modules/@vendia/serverless-express/
    "
    - "dist/**" // dist아래 빌드된 node 서버
    - "lambda.js" //람다 설정및 실행 코드
    functions:
    api:
    handler: lambda.handler
    events:
    - http: GET /
    - http: GET /{proxy+}

이것과 유사한 코드를 빌드시 동봉해야했으며 이 파일을 통해 어떻게 람다가 동작해야할지 설정할 수 있다. 또한 serverless를 위한 전용 tsconfig , 앵귤러의 server.ts 외에도 serverless.ts server.ts에서 listen 제거 및 람다 연결 등 여러 추가적인 코드와 설정들을 같이 해줘야했다.

이렇게 겨우겨우 배포를 하고니까, 뭔가 잘못되었다는 생각이 들었고 다시 알아보니까

해당 방식은 aws 서비스가 많이 없어 ssr프로젝트를 클라우드 플랫폼에서 개발자가 수동으로 동작시킨것에 가깝다는 것이였다.

심지어 비용또한 더 높다 Fin ops 개념을 아는 나에겐 충격이였다.

amplify를 사용한 배포

그래서 바로 다음 방법론인 amplify를 사용해보았다.

amplify가 프론트 엔드 서버를 배포하기 가장 쉬운 방법이자 가장 최근aws에서 제공하는 방법론이였고 , 이를 사용해 배포를 시도해보았지만, 앵귤러 유니버설을 지원하지 않아 사용이 불가능 하였다.

amplify는 주로 정적 웹사이트( 예시) next의 ssg방식)를 미리 빌드해놓고 주는 방식이기때문에 완전한 ssr방식인 universal은 사용이 힘들다는 이유이다. 만약 여기서 ssr 방식을 고수하고자 한다면 다른 서비스를 복잡하게 섞어 사용해야하며 amplify는 단순히 라우팅하는 기능 이상을 하지못한다. 그래서 3가지중 2번째 방법인 amplify는 사용중단하였다.

Beanstalk를 사용한 배포

결과적으로 CodeCommit과 Beanstalk를 PipeLine에 태워 프론트서버 배포를 하였다
빌드를 미리하는 방법과, 파이프라인에서 aws빌드를 사용해 직접 빌드하는 방법이 있는대

나는 미리 프로젝트를 빌드한 후 코드커밋에 업로드하는 방법을 사용하였다. 이렇게 사용하면

  1. 코드커밋에 빌드된 프로젝트 업로드
  2. 코드커밋에 새 내용이 업로드 될 시 자동으로 빈스톡에 업로드
  3. 빌드된 프로젝트를 빈스톡가 읽고 미리 설정된 로드밸런서 설정이 사용된
    ec2인스턴스 확보, s3공간에 저장,ec2인스턴스상에 존재하는 웹서버에서 node서버 실행
  4. 라우트 53으로 지정된 도메인을 사용해 연결

이 순서이다. 여기서 필요한건 코드커밋 접속 권한 설정과, 파이프 라인 코드커밋 빈스톡 s3를 위한 간단한 iam설정 정도이다. s3는 빈스톡가 빌드된 프로젝트를 보관하기위해 필요하다.

여기서 막혔던부분은

  • 앵귤러 서버 동작시 메모리 부족 오류
  • 빈즈토크가 자동으로 실행하는 빌드된 서버 파일 실행 불가 오류
  • 빈즈토크가 사용가능한 로드밸런서 설정 오류

정도였으며
메모리 부족은 t3.micro 에서 t3.small로 메모리용량을 늘려주니까 해결되었다. 앵귤러 프로젝트는 리액트 프로젝트에 비해 조금 더 많은 메모리를 필요로 한다.
또한 메모리를 올려놓으면 많은 동시접속자도 감당가능하기때문에 좋다.

서버파일 실행 불가 오류 는 앵귤러의 server.ts설정 변경 및 빌드된 파일이 있는 dist아래 폴더구조를 명확히 package.json의 start 명령어에 기입하지 않아서였다.

(빈즈토크가 프로젝트를 실행하기 위해선 ec2인스턴스 위의 웹서버에서 실행되며 이때 자동으로 npm start 명령어를 통해 실행되기에 start명령어를 빌드된 dist/projectName/server/server.ts로 변경해야한다. )

또한 로드밸런서가 문제였는대, 로드밸런서를 빈즈토크 내에서 설정 할 수 있다는 사실을 처음엔 몰랐고 이를 설정해준 후 route 53과 잘 연결 시켜주니 멀끔히 동작 하였다.

결론:

이전엔 gcp app engine으로 개발의존성 문제를 제외하고 다른 오류는 없을정도로
정말 편하게 배포 하였는대,이번엔 달랐다.

aws의 다양한 서비스와 그것들을 지원하는 라이브러리를 사용해보면서 클라우드 네트워크가 어떤방법으로 동작하는지 약간이지만 이해도가 늘었다.

또한 아키텍쳐 구성이 얼마나 중요한지도 느꼇다.
앵귤러가 풀스택 전용 SPA라는 뜬소문도 어느정도 맞다고 느꼈다.

profile
빠르고 정확해야 혈압이 안오른다

0개의 댓글