배포 자동화를 도입한 이유는 3가지이다.
1. 효율성 : 배포를 위한 매번 같은 프로세스를 줄이자
2. 일관성: 프로젝트를 누가 변경했는지에 관계없이 모든 코드 변경이 동일한 방식으로 테스트되고 배포되도록 하자. 이는 최종 빌드에서 휴먼에러 및 환경변수의 리스크를 줄여줌.
3. 정확성 : 프로젝트는 여러 환경 변수에 의해 다양한 버전으로 운용한다(prod/dev/test)이 때, 자동화가 안되어있는 프로젝트에서 배포 하기 전 환경 변수설정을 깜빡하여 빌드를 다시 시도해본 경험이 있다면 무조건 도입을 추천한다.
AWS환경을 이용하기 위해 KEY가 필요하다. IAM에서 accesskey, secret access key 발급 먼저 하자.
AWS 접근 키는 외부에 노출되면 아주 치명적이다. 배포가 진행되기 위해선 AWS credentials를 생성해야 하기 때문에 외부에 노출이 안되는 github secrets 변수에 시크릿 키를 설정하여 Gitflow가 진행될 때 secrets 변수로 credentials를 생성한다.
AWS_ACCESS_KEY, AWS_SECRETS_ACCESS_KEY, AWS_REGION 등록하자
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이 진행된다. 이렇게나 쉽다~
자동으로 진행이 잘 된다. 하지만 매번 디펜던시 인스톨을 진행하기 때문에 오래걸려~ 속터진다. 노드 모듈 캐싱전략 적용하자.
- 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
한눈에 보이는 시간 단축 👍
위에 단계에서 에러가 발생했다면 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 }}
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/