Github action을 이용해 배포자동화(static host)

김규빈·2023년 2월 28일
2

배포 자동화를 도입한 이유는 3가지이다.
1. 효율성 : 배포를 위한 매번 같은 프로세스를 줄이자
2. 일관성: 프로젝트를 누가 변경했는지에 관계없이 모든 코드 변경이 동일한 방식으로 테스트되고 배포되도록 하자. 이는 최종 빌드에서 휴먼에러 및 환경변수의 리스크를 줄여줌.
3. 정확성 : 프로젝트는 여러 환경 변수에 의해 다양한 버전으로 운용한다(prod/dev/test)이 때, 자동화가 안되어있는 프로젝트에서 배포 하기 전 환경 변수설정을 깜빡하여 빌드를 다시 시도해본 경험이 있다면 무조건 도입을 추천한다.

1. AWS IAM KEY

AWS환경을 이용하기 위해 KEY가 필요하다. IAM에서 accesskey, secret access key 발급 먼저 하자.

2. 레포지토리 secrets 변수 등록

AWS 접근 키는 외부에 노출되면 아주 치명적이다. 배포가 진행되기 위해선 AWS credentials를 생성해야 하기 때문에 외부에 노출이 안되는 github secrets 변수에 시크릿 키를 설정하여 Gitflow가 진행될 때 secrets 변수로 credentials를 생성한다.

AWS_ACCESS_KEY, AWS_SECRETS_ACCESS_KEY, AWS_REGION 등록하자

3. github.yml 작성

주의!! yml 파일은 들여쓰기를 준수함!

name: Deploy to Amazon ECS 

on:
  push:
    branches: ["master"]					#push 반응을 할 브런치
jobs:
  deploy:
    name: build and upload to s3
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - uses: actions/setup-node@v2		#node 17 >= SSL이슈 우회하기 위해 14버전 사용
        with:
          node-version: "14"
          
      - name: Install Dependencies		#디펜던시 인스톨
        run: npm install

      - name: build						#빌드
        run: npm run build
	
      - name: Configure AWS credentials		#aws credentials 생성
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}	#secrets 변수 사용
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 
          aws-region: ${{ secrets.AWS_REGION }}

      # s3 업로드
      - name: upload build directory to s3
        run: aws s3 cp dist/ s3://your_bucket --recursive  #s3 bucket에 업로드

작성 후 브런치에 merge동작이 이루어 지면 자동으로 yml이 진행된다. 이렇게나 쉽다~

4. 노드 모듈 캐싱

자동으로 진행이 잘 된다. 하지만 매번 디펜던시 인스톨을 진행하기 때문에 오래걸려~ 속터진다. 노드 모듈 캐싱전략 적용하자.


- name: Cache node modules
        uses: actions/cache@v2
        id: cache
        with:
          path: node_modules
          key: npm-packages-${{ hashFiles('**/package-lock.json') }}
#첫 노드모듈 인스톨 후 디펜던시 key 생성, 이 후 빌드 적용시 노드모듈(package-lock 추적)에 변화가 없으면(Key가 있으면) 재사용
      
      - name: Install Dependencies	# 디펜던시 키가 없으면 디펜던시 인스톨
        if: steps.cache.outputs.cache-hit != 'true'
        run: npm install

한눈에 보이는 시간 단축 👍

5. .env 파일 생성

위에 단계에서 에러가 발생했다면 env파일을 읽을 수 없어서 발생한 에러일 확률이 높다. 당신의 레포에 env파일이 없지 않은가? 빌드전 gitflow 스탭에 env파일을 추가해주고 함께 빌드하자. env엔 대다수가 외부 노출이 꺼려지는 정보가 포함되어 있기 때문에 위에서 사용했던 secrets변수를 이용하여 만들어 주는게 좋겠다.
(VUE_APP_MODE_PROD,
VUE_APP_PROD_API_BASE_URL,
VUE_APP_DEV_API_BASE_URL
등록 후 echo를 통해 .env파일로 작성하는 예시)

 # 빌드 전 .env파일 생성
      - name: Generate Environment Variables File for Production
      #2.$를 통해 변수 할당
        run: |
          echo "VUE_APP_MODE=$VUE_APP_MODE" >> .env
          echo "VUE_APP_PROD_API_BASE_URL=$VUE_APP_PROD_API_BASE_URL" >> .env
          echo "VUE_APP_DEV_API_BASE_URL=$VUE_APP_DEV_API_BASE_URL" >> .env
       #1.여기서 secrets변수를 가져오고
        env:
          VUE_APP_MODE: ${{ secrets.VUE_APP_MODE_PROD }}
          VUE_APP_PROD_API_BASE_URL: ${{ secrets.VUE_APP_PROD_API_BASE_URL }}
          VUE_APP_DEV_API_BASE_URL: ${{ secrets.VUE_APP_DEV_API_BASE_URL }}

s3 업로드 후 cloudfront 캐시 무효화

cloudfront를 이용하여 https를 사용하고 있다면 s3버킷에 업로드 후 cloudfront 캐싱을 날려줘야 적용을 확인 할 수 있다. 그것도 한번에 진행 시켜주자.

- name: cloudfront invalidate
  run: aws cloudfront create-invalidation --distribution-id your_cloudfront_id --paths '/*'

이렇게나 쉽다. 끝.

모든 코드

name: Deploy to Amazon ECS

on:
  push:
    branches: ["master"]
jobs:
  deploy:
    name: build and upload to s3
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      # node 17 >= SSL이슈 우회하기 위해 14버전 사용
      - uses: actions/setup-node@v2
        with:
          node-version: "14"

      # 빌드 전 .env파일 생성
      - name: Generate Environment Variables File for Production
        run: |
          echo "VUE_APP_MODE=$VUE_APP_MODE" >> .env
          echo "VUE_APP_PROD_API_BASE_URL=$VUE_APP_PROD_API_BASE_URL" >> .env
          echo "VUE_APP_DEV_API_BASE_URL=$VUE_APP_DEV_API_BASE_URL" >> .env
        env:
          VUE_APP_MODE: ${{ secrets.VUE_APP_MODE_PROD }}
          VUE_APP_PROD_API_BASE_URL: ${{ secrets.VUE_APP_PROD_API_BASE_URL }}
          VUE_APP_DEV_API_BASE_URL: ${{ secrets.VUE_APP_DEV_API_BASE_URL }}

      # Cache node module use
      - name: Cache node modules
        uses: actions/cache@v2
        id: cache
        with:
          path: node_modules
          key: npm-packages-${{ hashFiles('**/package-lock.json') }}

      # 노드 모듈이 바뀌면 디펜던시 인스톨
      - name: Install Dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: npm install

      - name: build
        run: npm run build

      # aws credentials 생성
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      # s3 업로드
      - name: upload build directory to s3
        run: aws s3 cp dist/ s3://your_bucket --recursive

      # cloudfront 무효화
      - name: cloudfront invalidate
        run: aws cloudfront create-invalidation --distribution-id your_cloudfront_id --paths '/*'

출처
https://meetup.nhncloud.com/posts/286
https://fe-developers.kakaoent.com/2022/220106-github-actions/

profile
FrontEnd Developer

0개의 댓글