군붕이의 메모장

S3로 배포한 React에 CI/CD 구축하기 with Github Actions 본문

클라우드/AWS

S3로 배포한 React에 CI/CD 구축하기 with Github Actions

초보군붕이 2023. 4. 19. 20:54
반응형

우선 현재 클라이언트의 경우 인프라가 아래처럼 구성되어 있다.

 

클라이언트 인프라 구성

 

만약 클라이언트에서 코드를 몇줄만 수정해도 아래 과정을 거쳐서 다시 배포해야 한다.

  • 1. 리액트 프로젝트 빌드
  • 2. S3에 업로드
  • 3. CloudFront 캐시 무력화

변경 작업은 유지보수를 하면서 계속해서 일어나게 되는데 매우 비효율적으로 생각됬다.

그래서 repository에 push될 경우 github actions를 사용하여 위 과정을 자동화해서 배포가 되도록 구성했다.

 

 

● Github Actions

Github Actions의 경우 가장 최상위 개념인 Workflow가 존재한다.

Workflow는 특정 로직을 자동화해둔 파일(과정)이라고 생각하면 된다.

프로젝트 루트폴더 안에 ./github/workflows/main.yaml 형식으로 생성해서 workflow 생성이 가능하다.

workflow 생성 경로

우선 전체적인 코드는 아래와 같다.

name: CI/CD hdev_client to AWS S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 코드 체크아웃
        uses: actions/checkout@v3
        
      // more step...
  • on : 아래 이벤트를 트리거 한다. 푸쉬 이벤트가 발생했을때 workflow가 실행되도록 하기위해 on으로 시작한다.
    • push : 이벤트를 지정한다. 위 코드에서는 push 이벤트가 발생했음을 지정한다.
      • branches : 어떠한 branch에 push 되었는지를 나타낸다. main branch에 push가 발생하면 실행된다.
  • jobs : workflow의 실행할 작업의 단위이다. 1개 이상의 job을 포함시킬수 있다.
    • deploy : 작업의 이름이다. 주로 실행될 작업을 식별할 때 사용한다.
      • runs-on : 작업을 실행할 환경(Github Actions Agent)을 정의한다. 위 코드에선 우분투 환경에서 실행된다.
  • steps : 실행될 작업들을 정의하는 부분이다.
    • name : 작업의 이름이다. 중복되지 않게 고유하게 작성하는것이 좋다.
    • uses : 실행할 액션을 지정한다. github actions에서 제공하는 빌트인액션 또는 개발자가 만든 액션을 사용할 수 있다.
    • with : uses에서 사용한 action에 필요한 인수를 전달하기 위한 키워드이다.

● Github Actions Secrets

Github Actions를 사용할때 일반적으로 보안을 위해 사용하는 환경변수 처럼 비밀값 설정이 가능하다.

 

우선 Github Actions를 작성할 Repository에 들어간뒤 상단 메뉴중 Settings를 들어가준다.

Settings 위치

 

 

그리고 좌측 메뉴에서 Security → Secrets And Variables → Actions를 들어가준다.

그러면 우측 메뉴에서 New Repository Secret 버튼이 있는데 해당 버튼을 눌러서 비밀값을 추가할 수 있다.

Actions 위치

 

그리고 아래 사진처럼 이름과 값을 지정해주면 된다. 변수와 유사하니 어렵지않게 세팅이 가능하다.

Secret 설정

 

설정이 완료되면 workflow 내부에서 아래 형식으로 Secret 값 사용이 가능하다.

something: ${{ secrets.something }}

 

 

● Workflow 작성하기

깃 체크아웃

우선 workflow에서 repostiroy에 업로드한 코드를 사용하기 위해서는 git checkout을 해주어야 한다.

Github Actions에서 제공하는 actions/checkout@v3을 활용했다.

- name: 코드 체크아웃
  uses: actions/checkout@v3

 

actions/checkout : https://github.com/actions/checkout

 

GitHub - actions/checkout: Action for checking out a repo

Action for checking out a repo. Contribute to actions/checkout development by creating an account on GitHub.

github.com

 

 

AWS IAM 사용자설정

aws에서 제공하는 서비스를 CLI 환경에서 간단하게 사용할 수 있게 aws cli를 제공해준다.

해당 서비스를 사용하기 이전에 AWS IAM 사용자를 먼저 설정해줘야 한다.

 

우선 액션의 경우 aws-actions에서 제공해주는 configure-aws-credentials@v2를 사용했다.

해당 액션의 인자는 아래 with 키워드와 같이 3개의 값이 필요하다.

 

 

  - name: AWS IAM 사용자 설정
    uses: aws-actions/configure-aws-credentials@v2
    with:
      aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      aws-region: ${{ secrets.AWS_REGION }}

AWS IAM profile : https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-configure-profiles.html

 

AWS CLI에 사용되는 명명된 프로파일 - AWS Command Line Interface

개별 명령에서 --profile로 프로파일을 지정하면 해당 명령에 대해서만 환경 변수에 지정된 설정을 재정의합니다.

docs.aws.amazon.com

aws-actions/configure-aws-credentials : https://github.com/aws-actions/configure-aws-credentials

 

GitHub - aws-actions/configure-aws-credentials: Configure AWS credential environment variables for use in other GitHub Actions.

Configure AWS credential environment variables for use in other GitHub Actions. - GitHub - aws-actions/configure-aws-credentials: Configure AWS credential environment variables for use in other Git...

github.com

 

 

리액트 프로젝트 빌드

우선 S3 정적 웹 호스팅을 사용해야 하므로 실제 배포시에는 리액트를 빌드하여 실행가능하게 만들어줘야 한다.

순서는 아래와 같다.

  • npm install : package.json에서 관리하는 패키지들을 다운로드 해준다.
  • npm run build : 프로젝트를 빌드해준다.
  - name: 리액트 빌드
    run: |
      npm install
      npm run build

프로젝트를 빌드하고나면 로컬환경과 마찬가지로 build 폴더가 생긴다.

 

 

빌드 결과물을 AWS S3에 업로드

빌드된 프로젝트를 S3에 업로드해서 접근이 가능하도록 해준다.

  - name: 빌드한 파일 S3에 업로드
    run: aws s3 sync build/ s3://${{ secrets.AWS_S3_BUCKET }} --acl public-read
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

build 폴더를 지정된 s3 버킷에 업로드하는 작업이다. acl은 public-read로 설정해서 외부접근이 가능하게 해준다.

또한 env의 경우 업로드에 필요한 정보를 설정해주는 구문이다.

 

또한 aws cli를 사용해서 s3에 업로드 할려면 IAM 유저에게 S3 Access 권한이 필요하니 아래 게시글을 참고해서 권한을 설정해준다.

 

https://iamiet.tistory.com/entry/Nodejs-AWS-S3-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%97%85%EB%A1%9C%EB%93%9C%ED%95%98%EA%B8%B0-feat-AWS-SDK-V3

 

Node.js AWS S3 이미지 업로드하기 feat. AWS-SDK v3

● AWS IAM 유저 추가하기 우선 AWS 콘솔에서 iam을 검색해서 들어가준다 좌측 사용자를 누르고 사용자 추가를 눌러준다 사용자 이름을 적절하게 지정해준다 다음 권한설정에서 "직접 정책 연결" 을

iamiet.tistory.com

 

 

CloudFront 캐시 무력화 설정

CloudFront의 경우 기본적으로 콘텐츠를 캐시에 저장해두고, 배포된 URL에 접근시 빠른 반응속도를 위하여 캐시에 저장된 콘텐츠를 반환해주게 된다.

 

하지만 이러한 특성때문에 S3에 업로드한 파일이 사용자에게 바로 반영이 되지않는 단점이 있다.

 

이를 해결하기 위해서 캐시 무력화 설정을 해주면 된다.

  - name: CloudFront 캐시 무력화 설정
    uses: chetan/invalidate-cloudfront-action@v2
    env:
      DISTRIBUTION: ${{ secrets.AWS_CLOUDFRONT_ID }}
      PATHS: "/*"
      AWS_REGION: ${{ secrets.AWS_REGION }}
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

chetan/invalidate-cloudfront-action : https://github.com/chetan/invalidate-cloudfront-action

 

GitHub - chetan/invalidate-cloudfront-action: Invalidate AWS CloudFront distribution paths

Invalidate AWS CloudFront distribution paths. Contribute to chetan/invalidate-cloudfront-action development by creating an account on GitHub.

github.com

 

 

● 테스트

우선 actions는 repository의 Actions 탭에서 확인이 가능하다

열심히 스크립트가 돌아가는중...

 

성공..!

 

작업내역

모든 작업내역이 에러없이 마무리된 모습이다.

 

 

● 삽질..

실패한 workflow 항목들

중간에 에러가 많이 났지만 계속 커밋을 해가면서 성공했다..

 

 

● 전체코드

name: CI/CD hdev_client to AWS S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 코드 체크아웃
        uses: actions/checkout@v3

      - name: AWS IAM 사용자 설정
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: 리액트 빌드
        run: |
          npm install
          npm run build

      - name: 빌드한 파일 S3에 업로드
        run: aws s3 sync build/ s3://${{ secrets.AWS_S3_BUCKET }} --acl public-read
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: CloudFront 캐시 무력화 설정
        uses: chetan/invalidate-cloudfront-action@v2
        env:
          DISTRIBUTION: ${{ secrets.AWS_CLOUDFRONT_ID }}
          PATHS: "/*"
          AWS_REGION: ${{ secrets.AWS_REGION }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

 

깃허브에서도 확인 가능합니다.

 

https://github.com/imkdw/hello_developer/blob/main/.github/workflows/main.yml

 

GitHub - imkdw/hello_developer: 개발자를 위한 커뮤니티, 헬로 디벨로퍼 입니다!

개발자를 위한 커뮤니티, 헬로 디벨로퍼 입니다! Contribute to imkdw/hello_developer development by creating an account on GitHub.

github.com

 

● 최종구성도

반응형