프론트엔드/etc

프론트 배포 실습

Hyeon_E 2023. 10. 30. 01:49

S3 + cloudfront를 활용하여 배포후 GitHub Action으로 CI/CD 적용 실습

실습하기 전 배포 이론

https://hyeon-e.tistory.com/219?category=1107791

 

프론트 배포 이론

[ AWS 배포 방법들 ] AWS EC2를 활용한 배포 AWS S3와 CloudFront를 활용한 배포 AWS amplify를 활용한 배포 Nginx를 활용한 배포 각 방법에 따라 배포할 수 있는 서버가 다르며 배포할수 있는 서버란 웹서버와

hyeon-e.tistory.com

배포순서

  1. AWS IAM 사용자 생성
  2. S3 버킷 설정
  3. cloundfront 배포
  4. GitHub Action CI/CD 적용
  5. 완료 후 캐쉬 무효화 추가!!

 

[ AWS IAM ]

사용자 생성

자신이 원하는 이름을 지으면 되는데 사용자는 여러개를 만들 수 있기 때문에 자신이 알아보기 쉽게 정하면 됨

 

그룹에 사용자 추가를 하거나 기존에 있는 사용자에 권한 복사를 하듯 상관없음

직접 정책을 연결시켜주어도 되지만 그룹을 생성해놓으면 사용자를 여러개 만들어서 관리할때 권한을 그룹으로 관리하기 쉬우니 그룹생성을 하는것이 편한듯

 

그룹이름을 정한뒤 s3와 CloudFront을 이용하여 배포하기 때문에 각 권한 정책(S3FullAccess, CloudFrontFullAccess)을 추가시킨 다음 사용자 그룹을 생성함

 

만들어놓은 그룹을 선택후 사용자를 생성하면 사용사 생성은 완료됨

 

사용자 액세스 키

GitHub Action에서 사용해야 하므로 액세스 키를 만들어서 이용해야함 

 

 

비밀액세스 키는 액세스 키 검색 부분에 완료를 누르면 다신 알수 없기 때문에 파일 다운로드를 해놓고 사용하는 것이 좋음

참고로 나는 CI/CD할때 키 잘못 넣어서 이유를 모른채 3시간동안 고통속에 살았으니 잘 확인하는것이 좋음

액세스 키까지 잘 완료하면 IAM 작업이 완료

 

[ S3 버킷 ]

버킷 만들기

버킷을 만들기를 눌러 새로운 버킷을 만듬

 

버킷이름은 아무거나 하면 되며 만약 도메인을 구입한다면 도메인 이름이랑 똑같이 짓는게 헷갈리지 않는 듯

 

IAM에서 사용자를 만들어서 사용

 

S3를 이용하여 정적 호스팅을 하는게 아니라 CloundFront를 이용해 캐시된 CDN 서버에 데이터를 요청해서 배포하기 때문에 모든 퍼블릭 액세스를 차단함

 

버킷 설정

속성에 정적웹 사이트 호스팅 편집을 해서

 

정적 웹 사이트 호스팅을 활성화 시키고 인덱스 문서와 오류문서로 index.html를 지정함

 

[ CloudFront 배포 ]

CloudFront 배포 생성

CloudFront페이지에 들어가 CloudFront 배포 생성을 누름

 

원본 도메인으로 원하는 S3 버킷 이름의 도메인 선택. 선택하면 이름도 같이 변경될 것임

그리고 원본 액세스까지 따라 선택한 S3 버킷이름의 도메인으로 변경하면 됨

Origin Shield 활성화 리전으로 자신의 지역을 선택하면 되는데 Origin Shield는 CDN과 Origin server 사이에 추가적인 캐싱 레이어를 둬서 컨텐츠를 캐싱하기 때문에 S3에 직관적으로 요청할 확률이 줄어듬

 

Origin에 대한 모든 요청이 Origin Shield를 거쳐가기 때문에 캐시 적중률이 높아지고 동일 객체에 대한 요청을 합쳐서 동시 요청수를 줄이는 장점을 가짐

 

디폴트인 Catching Optimized는 배포 후 24 이내에 배포가 이루어지면 변경 사항을 확인 하기까지 24시간이 걸림

변경사항을 바로바로 확인하기 위해는 CachingDisabled 선택

 

가격분류에서 비용을 감소시키려면 특정 리전을 선택하면 됨 보통 모든 엣지 로케이션을 하는것 같음

 

CloudFront 배포 설정

만든 CloudFront 오류페이지에 사용자 정의 오류 응답을 생성

 

S3만을 사용하여 배포할때와는 다르게 CloudFront로 배포를 하면 403 error( Access Denied )가 뜨는데 S3, Cloudfron로 서비스하는 구조에서 S3에 SPA(React)를 이용하여 구성을 하면 Redirect가 발생하여 403/404와 같은 Access Denied가 발생하게 되는 것. 그렇기에 사용자 정의 오류 응답을 생성하여 403에러일 경우에 응답 페이지 경로를 지정해주어 에러를 해결해줌

 

[ GitHub Action CI/CD 적용 ]

프로젝트에 .github/workflows에 자신이 하고자하는 바에 맞춰 yaml파일을 작성하여 정의하면됨

 

name: front-dev-deploy
on:
  push:
    branches: main
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v3

      - name: Install Dependencies
        run: yarn

      - name: Build
        run: yarn build
        env:
          VITE_URL: ${{ secrets.VITE_URL }}

      - name: S3 Deploy
        run: aws s3 sync ./dist s3://${{ secrets.AWS_S3_BUCKET }} --acl bucket-owner-full-control
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_BUCKET_REGION }}

내가 작성한 yaml파일로 main 브랜치로 푸쉬될때 동작함

name을 붙이면 작업의 그룹화가 되어 어떤 동작을 하고 있는지 어디서 오류가 나는지 파악하는데 큰 도움이 됨

AWS 액세스 키라든가 백서버의 주소등은 사람들이 보이게 올리면 안되기 때문에 비밀스럽게 감추게 됨

  • AWS_ACCESS_KEY_ID = S3 권한이 있는 유저 엑세스 키
  • AWS_SECRET_ACCESS_KEY = S3 권한이 있는 유저 시크릿 엑세스 키
  • AWS_S3_BUCKET_NAME = 정적 리소스 배포할 S3 버킷 이름
  • AWS_REGION = AWS 지역

 

감추는 것들의 값은 해당 레포지토리 Setting - Secrets and variables - Actions로 들어가 repository secret를 설정

repository secret 설정한후 yaml파일도 레퍼지토리에 올리게되면 Actions로 잘돌아가는것을 확인

잘 완료되면 초록불이 뜨며 오류가나면 도중멈추고 빨간불이 뜨게됨

초록불이 뜨며 배포가 잘 된것을 확인하면 최종 완료!!

 

[ 완료 후 캐쉬 무효화 추가 ]

CloudFront는 캐쉬를 하기 때문에 S3에 배포를 해도 24시간뒤에 CloudFront에 적용되는 불편함 점이 있음

배포를 할때는 불편하지만  CloudFront에서 캐쉬는 매우 중요한 요소

물론 후에 캐쉬 정책을 변경할수 있으나 캐쉬 자체를 disable하는 것자체가 마음에 계속 걸려서 다른 방법은 없는지 공부해 보았고 방법을 찾았음

 

CloudFront 캐쉬 정책 변경

CloudFront를 들어가 동작에서 캐쉬 정책을 바꿀 것을 체크한후 편집에 들어감

 

그리고 캐시 정책을 CachingOptimized로 변경함(초록색으로 S3에 권장된다고 되어있음)

바로 테스트 해보면 캐쉬가 안되고 바뀔수 있는데 캐쉬되는데 시간이 걸리는 좀 기다리면 캐쉬가 잘 되는것을 확인할 수 있음

 

yaml 파일 수정

name: front-dev-deploy

on:
  push:
    branches: main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v3

      - name: Install Dependencies
        run: yarn

      - name: Build
        env:
          VITE_URL: ${{ secrets.VITE_URL }}
        run: yarn build

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_BUCKET_REGION }}

      - name: S3 Deploy
        run: aws s3 sync ./dist s3://${{ secrets.AWS_S3_BUCKET }} --acl bucket-owner-full-control

      - name: Invalidate CloudFront Cache
        run: aws cloudfront create-invalidation --distribution-id ${{secrets.CLOUD_FRONT_ID}} --paths "/*"

S3에 배포한후 CloudFront 캐쉬를 무효화하는 코드를 적어놓음

 

여기서 CLOUD_FRONT_ID는 저부분이며 repository secret에 넣어주면 됨