Intro.
github repository를 dev와 prod로 나누어놓았다. 그래서 branch는 하나만 사용하고 repo로 환경을 분리한 구조로 세팅을 해보았다.
1. github action in dev repo
(1) deploy.yaml
name: test-dev
on:
workflow_dispatch:
jobs:
build_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_S3_REGION }}
- name: Set Environment Variable
run: |
echo "HASH_TAG=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
shell: bash
- name: Cache node modules
id: node-cache
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install dependencies
if: steps.node-cache.outputs.cache-hit != 'true'
run: npm install --save --legacy-peer-deps
- name: Dev build angular
run: |
npm run build:dev
- name: Generate deployment dev package
run: |
mkdir -p deploy/dev/${{ env.HASH_TAG }}
cp -r dist/work-caring-client/* deploy/dev/${{ env.HASH_TAG }}
- name: Upload to S3 bucket env repo dev directory
run: |
aws s3 cp ./deploy/dev/ s3://${{ secrets.AWS_S3_BUCKET_ENV_REPO }}/dev --recursive
- name: Upload to S3 bucket dev
run: |
aws s3 sync ./deploy/dev/${{ env.HASH_TAG }}/ s3://${{ secrets.AWS_S3_BUCKET_DEV }} --delete
- name: Apply dev cloudfront invalidation generation
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.AWS_CLOUD_FRONT_ID_DEV }} \
--path "/*"
- name: Prod build angular
run: |
npm run build:prod
- name: Generate deployment prod package
run: |
mkdir -p deploy/prod/${{ env.HASH_TAG }}
cp -r dist/work-caring-client/* deploy/prod/${{ env.HASH_TAG }}
- name: Upload to S3 bucket env repo prod directory
run: |
aws s3 cp ./deploy/prod/ s3://${{ secrets.AWS_S3_BUCKET_ENV_REPO }}/prod --recursive
1) checkout
- name: Checkout
uses: actions/checkout@v3
- git init을 하고 git branch를 배포할 브런치에 맞추는 작업을 진행한다.
2) setup node
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
- node를 set up하고 npm packages를 caching할 수 있는지 체크하는 단계이다.
- cache할 수 있다면, Cache restored successfully 를 볼 수 있다.
3) configure-aws-credentials
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_S3_REGION }}
- aws에 접근할 수 있도록 자격증명을 하는 단계이다.
4) set global env variable
- name: Set Environment Variable
run: |
echo "HASH_TAG=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
shell: bash
- GitHUB_ENV 에 HASH_TAG 이름으로 hash값을 저장해 추가해놓는다.
5) caching
- name: Cache node modules
id: node-cache
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
[1] 캐싱이 되었다면
- 위에서 캐싱 restore가 성공했으면 해당 작업에서 cache size를 확인하고 Cache restored successfully 을 리턴한다.
[2] 캐싱이 안 되었다면
- key : 캐시 복원 및 저장을 위한 키
- restore-keys : 캐시 hit가 안 된다면, 캐시 복원에 사용될 키의 목록
- cache-hit 는 false를 return
6) install dependencies
- name: Install dependencies
if: steps.node-cache.outputs.cache-hit != 'true'
run: npm install --save --legacy-peer-deps
- caching에 성공했다면, 해당 작업은 건너뛴다.
- caching에 성공하지 못했다면, 해당 명령어를 실행해 필요한 라이브러리들을 다운받는다.
7) apply them for dev
- name: Dev build angular
run: |
npm run build:dev
- name: Generate deployment dev package
run: |
mkdir -p deploy/dev/${{ env.HASH_TAG }}
cp -r dist/work-caring-client/* deploy/dev/${{ env.HASH_TAG }}
- name: Upload to S3 bucket env repo dev directory
run: |
aws s3 cp ./deploy/dev/ s3://${{ secrets.AWS_S3_BUCKET_ENV_REPO }}/dev --recursive
- name: Upload to S3 bucket dev
run: |
aws s3 sync ./deploy/dev/${{ env.HASH_TAG }}/ s3://${{ secrets.AWS_S3_BUCKET_DEV }} --delete
- name: Apply dev cloudfront invalidation generation
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.AWS_CLOUD_FRONT_ID_DEV }} \
--path "/*"
[1] dev build를 실행한다.
[2] 해당 빌드된 파일을 deploy/dev/[hash] 경로에 복사한다.
[3] 복사된 빌드된 파일을 S3 버킷 env-repo/dev 디렉터리에 복사한다.
[4] 복사된 빌드된 파일을 S3 버킷 dev에 배포한다.
[5] cloudFront에 이전 버전이 적용된 캐싱을 삭제한다.
8) apply them for prod
- name: Prod build angular
run: |
npm run build:prod
- name: Generate deployment prod package
run: |
mkdir -p deploy/prod/${{ env.HASH_TAG }}
cp -r dist/work-caring-client/* deploy/prod/${{ env.HASH_TAG }}
- name: Upload to S3 bucket env repo prod directory
run: |
aws s3 cp ./deploy/prod/ s3://${{ secrets.AWS_S3_BUCKET_ENV_REPO }}/prod --recursive
[1] prod build를 실행한다.
[2] 해당 빌드된 파일을 deploy/prod/[hash] 경로에 복사한다.
[3] 복사된 빌드된 파일을 S3 버킷 env-repo/prod 디렉터리에 복사한다.
**여기에서 prod에 배포할 것이 아니므로 repo에만 static files를 저장해 놓는다.
(2) rollback.yaml
name: rollback
on:
workflow_dispatch:
inputs:
hash-tag:
description: 'git commit hash name'
required: true
type: string
jobs:
build_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_S3_REGION }}
- name: Upload to S3 bucket dev
run: |
aws s3 sync s3://${{ secrets.AWS_S3_BUCKET_ENV_REPO }}/dev/${{ inputs.hash-tag }}/ s3://${{ secrets.AWS_S3_BUCKET_DEV }} --delete
- name: Apply dev cloudfront invalidation generation
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.AWS_CLOUD_FRONT_ID_DEV }} \
--path "/*"
- 롤백하고 싶은 해쉬값을 입력하면 해당하는 버전의 static files를 aws cli를 통해 S3 repo dev 디렉터리에 있는 파일을 dev 버킷에 배포한다.
- 그 후 cloudfront에 기존 버전의 해싱된 값을 제거한다.
2. github action in prod repo
(1) deploy.yaml
name: prod-test
on:
workflow_dispatch:
inputs:
hash-tag:
description: 'git commit hash name'
required: true
type: string
jobs:
build_deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_S3_REGION }}
- name: Upload to S3 bucket prod from bucket env repo
run: |
aws s3 sync s3://${{ secrets.AWS_S3_BUCKET_ENV_REPO }}/prod/${{ inputs.hash-tag }}/ s3://${{ secrets.AWS_S3_BUCKET_PROD }} --delete
- name: Apply dev cloudfront invalidation generation
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.AWS_CLOUD_FRONT_ID_PROD }} \
--path "/*"
- 실서버에 배포하고 싶은 해쉬값을 입력하면 해당하는 버전의 static files를 aws cli를 통해 S3 repo prod 디렉터리에 있는 파일을 prod 버킷에 배포한다.
- 그 후 cloudfront에 기존 버전의 해싱된 값을 제거한다.
3. aws cli
1) aws s3 cp vs sync
[1] cp는 해당 내용을 복사해서 그대로 s3 버킷에 업로드를 하는 것.
- --recursive 옵션을 제공하여 디렉터리 아래의 모든 파일을 s3 버킷에 업로드할 수 있다
- 그래서 cp를 사용한다면 --recursive 옵션을 일반적으로 넣어준다. (하나의 파일만 업로드할 것이 아니라면)
[2] sync는 해당 내용을 그대로 s3에 덮어씌우는 것.
- --delete 옵션을 제공하여 원본에 없는 파일이나 객체를 대상에서 제거할 수도 있다.
- 그래서 sync를 사용한다면 --delete 옵션을 일반적으로 넣어준다.
2) aws cloudfront invalidation 의미
[1] invalidation(무효화)
- 무효화 기능은 말 그대로 CloudFront 에지 로케이션에 저장된 파일의 캐시를 삭제하는 기능
- 이걸 해줘야 이전에 캐쉬를 삭제하고 새로운 값으로 캐쉬를 적용해준다.
- 아마존 CloudFront 는 전 세계 엣지 로케이션에 정적/동적 파일의 복사본을 캐싱합니다. 모든 엣지 로케이션에서 파일을 제거하거나 업데이트하려면 각 파일 또는 파일 그룹마다 무효화를 생성합니다.(aws 공식문서 참조)
references
1) github action
https://docs.github.com/en/actions
https://github.com/actions/cache
https://github.com/actions/setup-node
2) aws cli for s3
https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-services-s3-commands.html
https://www.techdevpillar.com/blog/difference-between-s3-cp-and-sync-command/
3) aws cli for cloudFront
https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html