React 프로젝트를 AWS에 배포를 하고 코드가 수정될 때마다, 매번 S3에 빌드 파일을 업로드 하고 CloudFront 캐시 무효화 등을 진행하는 과정은 어렵진 않지만 너어무 귀찮다...
이를 해결하고자 자동 배포를 알아보게 되었고 Github Actions로 간단하게 할 수 있어서 나중에 또 까먹을 수 있으니 글로 남기려고 합니다.
Vite
+TypeScript
+React
프로젝트입니다.- 현재는
develop
브랜치에서 개발 및 테스트를 진행하고 이상이 없으면main
브랜치에 push를 하고AWS CLI
명령어로S3
에dist
파일을 업로드 후CloudFront
캐시 무효화를 진행합니다.
AWS에 배포가 되어야지 진행이 가능하기 때문에 이전 글을 참고 후 배포를 완료하신 다음에 진행하시면 됩니다.
지속적인 통합(Continuous Integration, CI)
지속적인 배포(Continuous Deployment, CD) 또는 지속적인 서비스 제공(Continuous Delivery)
이러한 CI/CD 파이프라인은 개발 과정을 자동화하여 소프트웨어의 품질을 향상시키고, 배포 시간을 단축할 수 있습니다.
내장된 CI/CD
GitHub 저장소 내에서 직접 CI/CD 파이프라인을 구성하고 관리할 수 있음
이벤트 기반 트리거
코드 푸시, 풀 리퀘스트, 릴리스 등 다양한 GitHub 이벤트에 따라 워크플로우를 자동으로 실행
YAML 기반 구성
워크플로우를 정의하는 데 YAML 파일을 사용하여 가독성과 관리의 용이성을 제공
마켓플레이스 통합
필요한 작업을 위해 사전 빌드된 액션을 찾거나 공유할 수 있는 광범위한 GitHub 마켓플레이스에 액세스할 수 있음
접근성
GitHub 사용자라면 추가적인 도구 없이 바로 CI/CD 파이프라인을 설정할 수 있음
무료 사용량
공개 레포지토리는 무제한으로, 비공개 레포지토리에도 상당한 무료 분량을 제공받아 사용할 수 있음
확장성
사용자 정의 액션을 생성하거나, 마켓플레이스에서 다른 사용자가 만든 액션을 사용하여 워크플로우를 확장할 수 있음
간편한 설정과 관리
웹 인터페이스를 통한 간편한 워크플로우 설정과 세밀한 관리가 가능
프로젝트의 .github/workflows
디렉토리에 YAML 파일을 생성합니다. 이 파일은 배포 워크플로우를 정의합니다.
프로젝트에 직접 .github/workflows
폴더를 생성 후 yaml 파일을 생성해도 되고
깃허브 페이지에서 Actions
탭에서 Node.js
워크플로우를 선택해서 생성해도 됩니다.
AWS에 접근하기 위한 자격증명(Access Key ID와 Secret Access Key 등)을 GitHub Secrets에 저장합니다. 이는 워크플로우에서 안전하게 사용하기 때문에 작성하면 되고 프로젝트에서 환경 변수 .env
등을 사용한다면 입력하면 됩니다.
깃허브 페이지에서 Settings
탭에서 Secrets and variables/Actions
에 들어가서 New repository secrets
로 숨겨야 하는 값들을 넣으면 됩니다.
AWS 자격증명을 위한 값들과 .env
에서 사용하는 값을 넣었습니다.
AWS_ACCESS_KEY_ID
:AWS IAM
에서 발급 받은 엑세스 키입니다.
AWS_CLOUDFRONT_ID
: CloudFront Id
AWS_REGION
: S3 버킷 리전
AWS_S3_BUCKET_NAME
: S3 버킷 이름
AWS_SECRET_ACCESS_KEY_ID
:AWS IAM
에서 발급 받은 시크릿 키입니다.
VITE_APP_API_ENDPOINT
:.env
파일에서 사용하는 환경 변수 값
워크플로우에서 진행해야 할 것들을 코드상에 작성해야 되고 이 프로젝트에서는 S3 업로드 및 CloudFront 캐시 무효화를 진행해야 되기 때문에 위의 5가지로 작성할 것입니다.
아래는 현재 프로젝트에서 사용하는 워크플로우 yaml 코드입니다.
name: Deploy to AWS S3 and Invalidate CloudFront
on:
push:
branches: [ "main" ] # 메인 브랜치에 코드가 푸시될 때 이 워크플로우를 실행
jobs:
build:
runs-on: ubuntu-latest # 이 작업은 최신 Ubuntu 버전에서 실행됩니다.
strategy:
matrix:
node-version: [18.x] # Node.js 18.x 버전을 사용합니다.
steps:
- uses: actions/checkout@v3 # GitHub 저장소를 체크아웃하여 작업 디렉토리에 소스 코드를 가져옵니다.
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3 # Node.js를 설정합니다. 버전은 matrix에서 정의된 Node.js 버전을 사용합니다.
with:
node-version: ${{ matrix.node-version }}
cache: 'npm' # npm 캐시를 사용하여 의존성 설치 시간을 단축합니다.
# npm 캐시 디렉토리 설정
- name: Get npm cache directory
id: npm-cache-dir
run: |
echo "::set-output name=dir::$(npm config get cache)"
# 의존성 캐시 사용
- uses: actions/cache@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
# 환경변수 .env 파일 생성
- name: Generate Environment Variables File for .env
run: |
touch .env
echo "VITE_APP_API_ENDPOINT=$VITE_APP_API_ENDPOINT" >> .env
env:
VITE_APP_API_ENDPOINT: ${{ secrets.VITE_APP_API_ENDPOINT }}
# npm 패키지 설치
- name: Install dependencies
run: npm install
# 빌드 실행
- name: Build
run: npm run build
# AWS 자격증명 설정
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1 # AWS 자격증명을 설정합니다.
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
# S3에 빌드 폴더 업로드
- name: S3 Deploy
run: aws s3 sync ./dist s3://${{ secrets.AWS_S3_BUCKET_NAME }}/ --acl bucket-owner-full-control # 빌드된 폴더를 S3 버킷에 동기화합니다.
# CloudFront 캐시 무효화
- name: Invalidate CloudFront Cache
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_ID }} --paths "/*"
코드 체크아웃 및 Node.js 설정
actions/checkout@v3
을 사용하여 저장소의 코드를 체크아웃합니다.
actions/setup-node@v3
을 사용하여 Node.js 환경을 설정하고, npm 캐시를 활성화합니다.
의존성 설치 및 빌드
npm 캐시 디렉토리를 설정하고 캐시를 구성합니다.
npm install 명령어로 프로젝트 의존성을 설치합니다.
npm run build 명령어로 프로젝트를 빌드합니다.
AWS 자격증명 구성
aws-actions/configure-aws-credentials@v1
을 사용하여 AWS 자격증명을 구성합니다.
S3에 빌드된 파일 업로드
aws s3 sync
명령어를 사용하여 빌드된 파일을 AWS S3 버킷에 업로드합니다.
CloudFront 캐시 무효화
aws cloudfront create-invalidation
명령어를 사용하여 CloudFront의 캐시를 무효화합니다.
main
브랜치에 push를 하면 Github Actions
워크플로우가 실행되어 자동으로 build가 진행되고 AWS S3
에 업로드 후 CloudFront
캐시 무효화까지 진행을 합니다.