Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] Frontend CD 환경 재구축 #870

Open
wants to merge 4 commits into
base: fe-dev
Choose a base branch
from
Open

[FE] Frontend CD 환경 재구축 #870

wants to merge 4 commits into from

Conversation

jinhokim98
Copy link
Contributor

@jinhokim98 jinhokim98 commented Dec 20, 2024

issue

구현 사항

이전 AWS Pipeline 방식에서 github action으로 CD 변경 결정과 장점

이전에는 AWS의 access key를 발급 받을 수 없어 S3에 접근할 수 있는 권한이 없었습니다. 그래서 AWS Pipeline을 사용해서 S3에 배포했었는데 이제는 AWS access key를 발급 받을 수 있어 github action으로 CD 체계를 변경했습니다.

github action으로 옮겼을 때의 장점은 env의 수정 사항이 생겼을 때 aws에 로그인하지 않고 github secrets를 수정하면 돼서 간편하다는 것이라고 생각합니다.

action이 발생하는 조건

개발 환경은 fe-dev에 push 될 때, 운영 환경은 main에 push 될 때 action이 발생하도록 설정했습니다. 또한 paths 설정으로 client 파일이 수정됐을 때만 action이 실행됩니다.
fe-dev를 base로 올라온 pr이 fe-dev에 머지, main을 base로 올라온 pr이 main에 머지될 때 action이 발생하여 배포가 되는 설정입니다.

dev deploy 설명

working directory 설정

 defaults:
      run:
        shell: bash
        working-directory: ./client

github action 환경에서 실행될 디렉토리를 먼저 설정해줍니다.

브랜치 코드 가져온 후 Node setting

 # 1. Git 리포지토리 체크아웃
      - name: Checkout code
        uses: actions/checkout@v4

      # 2. Node.js 20.15.1 version으로 셋팅
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20.15.1"

      # 3. 의존성 설치
      - name: Install Dependencies
        run: npm install

여기까지는 기존의 frontend-pull-request와 설정이 비슷합니다.
git repository checkout을 해서 github workflow환경에 해당 브랜치의 코드를 가져온 후, node를 20.15.1로 셋팅, npm install을 하는 과정입니다.

개발 환경으로 빌드

      # 4. Dev 환경으로 빌드
      - name: Build for Dev environment
        run: npm run build-dev
        env:
          API_BASE_URL: ${{ secrets.API_BASE_URL }}
          AMPLITUDE_KEY: ${{ secrets.AMPLITUDE_KEY }}
          KAKAO_JAVASCRIPT_KEY: ${{ secrets.KAKAO_JAVASCRIPT_KEY }}
          IMAGE_URL: ${{ secrets.IMAGE_URL }}
          KAKAO_REDIRECT_URI: ${{ secrets.KAKAO_REDIRECT_URI }}
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}

여기서 기존의 내용과 달라지는 것이 CD는 정적 파일을 배포하는 것이므로 빌드하는 과정이 들어가야합니다.
그래서 dev 환경으로 빌드하는 명령어 npm run build-dev를 실행합니다. 여기서 필요한 환경변수들을 github secrets에서 가져오게 됩니다.

AWS 인증

 # 5. AWS 인증 설정
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

S3와 CloudFront의 기능을 사용하기 위해서는 AWS 인증이 필요합니다. 그래서 access key를 넣어줘서 액션 상에서 S3와 CloudFront 기능을 이용할 수 있도록 했습니다. 또한 AWS IAM에서 access key에 대한 사용자 권한에 amazon s3 full access 권한을 추가해서 github action이 S3에 접근해서 파일을 업로드 할 수 있도록 권한을 추가해줬습니다.

image

S3에 빌드 결과 업로드

  # 6. S3에 빌드 결과 업로드
      - name: Upload build results to S3
        run: aws s3 sync ./dist s3://${{ secrets.S3_BUCKET_NAME }}/dev/ --delete

npm run build-dev 명령어를 수행하면 빌드된 결과는 ./dist에 저장됩니다.
이 디렉토리에 저장된 정적 파일을 S3 우리 버킷 내 dev 디렉토리에 동기화시킵니다.
여기서 delete 옵션을 주어서 S3에 로컬의 빌드 결과만 남을 수 있도록 했습니다.

CloudFront 캐시 무효화

# 7. CloudFront 캐시 무효화
      - name: Invalidate CloudFront Cache
        run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.DEV_CLOUDFRONT_DISTRIBUTION_ID }} \
            --paths "/*"

마지막으로 CloudFront에서 캐시를 지우고 새로운 정적 파일을 볼 수 있도록 캐시 무효화를 해주면 끝입니다.
여기서 paths를 /*로 준 이유는 CloudFront dev 배포의 원본은 dev를 바라보고 있으므로 /*를 해주면 알아서 /dev 이하의 캐시를 지운다는 의미가 됩니다.

Prod deploy 설명

전반적으로 dev와 비슷합니다. 하지만 하나 차이점이 있어 따로 설명합니다

S3 업로드할 때 차이점

 # 6. S3에 빌드 결과 업로드
      - name: Upload build results to S3
        run: aws s3 sync ./dist s3://${{ secrets.S3_BUCKET_NAME }}/prod/ --delete

prod 환경에서는 --delete 옵션을 넣지 않습니다.
이전 빌드 파일을 지우지 않고 새로운 빌드 내역을 S3에 담습니다.
기존에 aws pipeline 방식으로 할 때도 prod 환경에서는 이전 정적 파일을 지우지 않고 새로운 빌드 파일을 추가하는 형식으로 되어있어 이를 유지한 것도 있고, prod 디렉토리 안에는 /assets 라는 디렉토리가 있는데 여기에는 행동대장에서 사용하는 행댕이 이미지와 랜딩 페이지의 이미지들이 담겨있으므로 디렉토리 내 파일을 전부 지워버린다면 /assets의 이미지들도 전부 삭제가 되는 불상사가 일어나기 때문에 prod 환경에서는 새로운 파일을 단순 올려놓는 작업을 하도록 작성했습니다.

=> prod 환경에서도 지우도록 변경합니다. 내부의 assets 디렉토리를 버킷 내 image 디렉토리로 옮겨 놓아서 prod 디렉토리가 지워져도 문제가 생기지 않게 됐습니다. 이제 이미지 url을 s3/bucket/image/assets을 바라보도록 변경했습니다.

논의하고 싶은 부분

dev deploy action 발생 조건에 대해서

우리의 협업 방식은 fe-dev를 base로 pr을 쌓아두고 배포일이나 그 전에 한 번에 머지하는 방식입니다.
예를 들어 pr이 5개가 있고 이를 한 번에 머지를 하게 되면 fe-dev에 머지 할 때마다 dev.haengdong.pro에 계속 자동 배포가 되는 상황이 일어나게 되어 S3에 다섯 번 접근하게 되는 상황이 일어납니다.
하지만 우리가 원하는 결과는 모든 브랜치가 머지가 된 후의 fe-dev의 결과라고 생각합니다. 그래서 의견을 나누고 싶어요

  1. fe-dev에 push 될 때마다 자동배포 (아마 기존의 AWS Pipeline이 이 방식이었다고 생각해요)
  2. fe-dev로 머지가 끝난 후 따로 action 탭에서 액션을 발생 시켜 자동배포

어떤 방식이 좋을지 논의해봐요

feature 브랜치 별 자동배포에 대해서

레벨 3 때 인프라 논의를 하던 중, 브랜치 별로 작업한 결과를 배포된 링크에서 볼 수 있다면 상호 리뷰를 하는 과정에서 편할 것이라는 의견이 있었습니다. 그 때 제 기억으로는 구축하기 어려워서? 방법이 어려워서? 라고 기억하는데 (이건 제 기억 기반이라 확실하지는 않네요..) 최근에 제가 개별적으로 CI/CD를 공부하고 연습하면서 브랜치 별로 자동배포하는 방법을 연구했고 방법을 알아냈습니다. 브랜치 별 자동배포 연구해본 글

제가 개인적으로 연습해본 것이라 번들링 도구가 webpack이 아니라 vite이지만 webpack으로 충분히 할 수 있다고 생각합니다. 그래서 브랜치 별 자동배포를 도입해보는 것은 어떨지 의견 나누고 싶어요!

🫡 참고사항

@jinhokim98 jinhokim98 added this to the v3.1.0 milestone Dec 20, 2024
@jinhokim98 jinhokim98 self-assigned this Dec 20, 2024
@jinhokim98 jinhokim98 linked an issue Dec 20, 2024 that may be closed by this pull request
1 task
Copy link
Contributor

@pakxe pakxe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋아용조하요!~~
다만 accessKey를 직접 사용할 수 있게 되었다면 /assets에 직접접근할 수 있어지니 경로를 상위 폴더로 옮기고 env에 지정 후 접근하면 될 것 같습니다.

그러면 prod도 delete로 기존 파일들을 모두 지우게할 수 있을 것 같아요.

dev deploy action 트리거에 대해서는 둘 다 상관없다고 생각합니다.(돈이 안드니까요..)
feature 브랜치 별 자동 배포는 있으면 좋겠네요! 하지만 세팅하는데 드는 품이 너무 많다면 꼭 안해도 될 것 같아요. 지금도 pr을 잘 작성하니 코드 읽는게 어렵진 않으니까요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🤼 In Review
Development

Successfully merging this pull request may close these issues.

[FE] Frontend CD 환경 재구축
2 participants