Github Action으로 CI/CD (feat. AWS S3 CloudFront)

Chaeyoung·2024년 9월 9일
0

2024.09.09 기준 작성된 포스팅입니다.

먼저 s3 cloudfront 배포방법이 알고싶다면 하단 포스팅을 참고할 수 있다.

개념과 함께 아는 것이아니라 순서대로 cicd를 적용하고 싶은 사람은 목차 중에 순서대로 github cicd 준비하기 를 바로 참고하길 바란다.

github-cicd

먼저 아래는 작성한 전체 workflow.yml 파일이다.

name: DEV CI

on:
  push:
    branches: ["dev"]
  pull_request:
    branches: ["dev"]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [20.x]

    steps:
      - uses: actions/checkout@v4

      - name: Create dotenv file
        run: |
          touch .env
          echo "VITE_BASE_URL=${{secrets.VITE_BASE_URL}}" >> .env 
 # ... env 파일에 생성할 객체 echo 명령어로 추가하기        
          cat .env

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: yarn # yarn으로 설정

      - name: Yarn install
        run: yarn

      - name: Yarn build
        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_DEFAULT_REGION }}

      - name: Deploy to S3
        uses: jakejarvis/s3-sync-action@master
        with:
          args: --delete
        env:
          AWS_S3_BUCKET: ${{ secrets.DEV_AWS_S3_BUCKET_NAME }}
          SOURCE_DIR: "dist"

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

workflows를 통해 할 수 있는 동작

workflows 작성이 어색한 사람들은 해당 섹션을 가볍게 읽어보면 이해하는데 조금 도움이 될 것이다.

1. 특정 브랜치에 push가 일어났을 때 동작 지시하기( = 트리거 조건 설정)

깃 브랜치별로 push가 일어났을 때 다른 동작을 수행하게 하려면 on: 명령어를 통해 동작이 일어날 브랜치를 지정할 수 있다. 해당 스크립트로 main 브랜치와 dev브랜치를 구분하여 배포나 테스트 작업에 구분을 둘 수 있다.
추가적인 스크립트로 매번 수동으로 하던 빌드 -> 업로드 -> 배포 -> 캐싱 무효화 등등과 같은 작업들을 한번에 끝낼 수 있다.

2. 미리 작성해둔 aws 권한으로 번거로운 수동 aws 작업 줄이기

aws access key와 secret access key와 같이 노출되면 안되는 정보들은 미리 github secrets에 등록해둠으로써 보안을 강화할 수 있다. 이때 저장해둔 값들은 workflow에 미리 등록해둔 key를 이용해 불러와 사용할 수 있다. 이때 주로 저장되어 사용하는 값이 aws 권한 인증에 필요한 aws access key와 secret access key이다. 해당 작업은 상단에 작성된 전체 스크립트에 Configure AWS Credentials 부분에 해당한다.

3. github action으로 s3에 빌드파일 자동 업데이트하기

name 스크립트로 구간별 동작을 지정할 수 있다. 이 때, 파일 빌드 작업일 경우 jobs 스크립트 안에 실행될 환경을 설정할 수 있다. 위 스크립트는 우분투 최신버전으로 동작하도록 작성되었다. 후에 순차적으로 strategy.matrix로 node버전을 설정,uses-with 스크립트로 배포파일 지정 등 동작을 지정해둘 수 있다. 마지막으로 env환경 변수에 aws bucket 이름을 지정해줌으로써 파일 업로드가 완료된다. 스크립트에 dist는 해당 스크립트의 프로젝트가 vite-react기준이라 build파일이 dist폴더내에 저장되었기 때문에, dist로 작성되었다.

4. s3업로드 완료 후 cloudfront 캐싱 무효화하기

cloudfront의 장점은 캐싱이 된다는 장점이 있지만, 새로 업데이트를 할 경우 수동으로 캐싱을 무효화해줘야한다. 이ㄸㅐ 할 작업을 workflow에 함께 작성할 수 있다. 아래 명령어를 참고하면 된다. AWS_DISTRIBUTION_ID에는 cloudfront id값을 git secret에 AWS_DISTRIBUTION_ID 변수명으로 작성해주면된다.

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

순서대로 github cicd 준비하기

이제 본론으로 들어가 순서대로 cicd를 적용해보자ㅏ.

순서를 간략하게 요약하면 아래와 같다.

  • aws 권한 부여를 위한 aws access key 발급
    • 권한 부여 방법은 따로 IAM 계정을 생성해서 해도 되지만 이번 포스팅에는 access key를 직접적으로 활용하였다
  • git secret 등록
  • workflows .yml 파일 작성

1. aws access key 발급

aws에서 우측 상단에 아이디 탭을 누르고 보안 자격 증명 메뉴를 클릭한다.

용도에 맞게 사용 사례를 선택한다.

생성된 엑세스 키는 보안을 위해 따로 저장하지 않는 편이 좋으며, 생성시에 바로 깃허브 레포 secret에 등록하는 편이 좋다.

2. Git secret 추가

발급받는 엑세스키워 시크릿 엑세스 키를 두고 아래 경로로 접속하여 새로 변수를 등록한다.

접속 순서 : cicd 적용할 레포 > 설정 > secrets and variables > action > new repository secret

아래와 같이 원하는 변수명으로 변경/등록 할 수 있다.

작성된 내용을 github내에서도 두번은 볼 수 없으니 혹시나 잊을까 걱정된다면 다로 메모해둬도 좋지만, 보안을 걱정한다면 주기적으로 엑세스키를 업데이트 하는 것도 방법이다!

cicd 등록시 저장할 변수 목록 ( s3 cloudfront로 배포했을 경우 )

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_DEFAULT_REGION
  • AWS_DISTRIBUTION_ID
  • AWS_S3_BUCKET_NAME

3. workflows .yml 파일 작성

name: MAIN CI

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [20.x]

    steps:
      - uses: actions/checkout@v4

      - name: Create dotenv file
        run: |
          touch .env
          echo "VITE_BASE_URL=${{secrets.VITE_BASE_URL}}" >> .env 
 # ... env 파일에 생성할 객체 echo 명령어로 추가하기        
          cat .env

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: yarn # yarn으로 설정

      - name: Yarn install
        run: yarn

      - name: Yarn build
        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_DEFAULT_REGION }}

      - name: Deploy to S3
        uses: jakejarvis/s3-sync-action@master
        with:
          args: --delete
        env:
          AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET_NAME }}
          SOURCE_DIR: "dist"

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

위 코드가 동작하는 방식을 간략하게 작서하면 다음과 같다.

  • main 브랜치에 push나 pull request가 일어날 시 아래 스크립트를 실행한다.
  • yarn을 이용해 필요한 package.json 파일을 다운받고, build를 진행한다.
  • aws 인증
  • s3에 기존에 저장된 파일들을 삭제 후 build된 파일이 있는 dist폴더를 지정된 s3버킷에 저장한다.
  • 마지막으로 cloudfront에 있는 캐싱 무효화 작업을 실행한다.

4. 마무리 잘 동작하는지 확인하기

action 카테고리에 들어가면 잘 동작하는지 확인할 수 있다. 프로젝트 크기에따라 오래걸릴 수도 있으니 잠깐 다른 작업을 하고 있으면 된다.

디테일을 보려면 Show all jobs 버튼을 프로그램이 동작하는 것을 확인할 수 있다.

모두 완료된 후 배포 url로 접속하여 업로드가 잘 되었는지 또는 workflows 마지막 단계인 캐싱 무효화가 잘되었는지 등을 통해 잘 동작이 되었는지 확인할 수 있다.

참고

0개의 댓글