[AWS] CI/CD - Github Actions

박하늘·2025년 4월 4일

AWS

목록 보기
4/4

▪️ React 프로젝트에 CI/CD 적용하기 (S3, Cloudfront)

▪️ CI/CD란?

CI/CD란 지속적 통합(Continuous Integration)과 지속적 배포(Continuous Deployment)라는 의미를 가지고 있다. 쉽게 표현하자면 CI/CD는 테스트(Test), 통합(Merge), 배포(Deploy)의 과정 즉, 소프트웨어 개발 및 배포 프로세스를 자동화하는 방법론 의미한다.

📍 [ CI (Continuous Integration, 지속적 통합) ]

  •	개발자가 코드를 중앙 저장소(GitHub, GitLab 등)에 자주 푸시함
  •	푸시된 코드가 자동으로 빌드되고, 유닛 테스트를 수행함
  •	코드 충돌을 빠르게 감지하여 품질을 유지함

📍 [ CD (Continuous Delivery/Deployment, 지속적 배포/전달) ]

  •	CI 후, 테스트를 통과한 코드가 운영 환경(Production)에 배포될 준비가 완료됨
  •	Continuous Delivery: 배포는 수동으로 진행 (운영팀이 최종 승인)
  •	Continuous Deployment: 테스트를 통과하면 자동으로 운영 환경에 배포됨

[CI/CD 환경 구축 필요성]

  • 빠르고 안정적인 배포
    코드 변경 사항이 자동으로 빌드, 테스트, 배포되어 배포 주기가 단축됨 → 개발 속도 증가

  • 자동화된 테스트로 품질 유지
    코드 변경 시마다 자동으로 테스트하여 버그를 조기에 발견 → 코드 품질 유지 및 안정성 향상

  • 팀 협업 강화
    여러 개발자가 동시에 작업해도 코드 충돌을 빠르게 해결할 수 있음

  • 인프라 운영 부담 감소
    수작업 배포 대신 자동화를 통해 효율적인 운영 가능 → 배포 자동화로 실수 감소

[CI/CD의 작동 과정]

1. 개발자가 코드 변경 & Push
GitHub/GitLab 등 중앙 저장소에 코드가 푸시됨

2. CI(지속적 통합) 실행
빌드 & 유닛 테스트 자동 실행

3. 테스트 결과 확인 & 코드 병합
테스트 성공 시, main 브랜치로 병합 (PR 기반)

4. CD(지속적 배포) 실행
Docker 이미지 빌드 후 컨테이너 레지스트리에 업로드
Kubernetes, AWS ECS/Fargate, Vercel, Netlify 등의 환경에 자동 배포

5. 서비스 배포 완료 & 모니터링
배포된 서비스의 상태를 확인하고 모니터링 (로그 분석, 에러 감지)

▪️ CI/CD 구축 서비스

[CI/CD를 구축할 때 사용할 툴]

  • Github Actions
  • Jenkins
  • Circle CI
  • Travis CI
  • 등등

[Github Actions와 Jenkins 간단비교]

Jenkins의 단점으로는 별도의 서버에 구축을 해야 한다는 단점이 있다. 이 때문에 서버를 빌리는 비용이 발생하게 된다. 하지만 Github Actions는 별도의 서버 구축 없이 Github에 내장되어 있는 Github Actions 기능을 사용할 수 있다. 비용적인 측면도 유리하고 셋팅하는 데 시간을 쓸 필요도 없다.

▪️ Github Actions

Github Actions를 로직을 실행시킬 수 있는 일종의 컴퓨터라고 생각하면 된다. CI/CD 자동화 도구로, 코드 변경이 있을 때 “빌드, 테스트, 배포”에 대한 로직을 자동으로 실행시키는 역할을 하게 된다.

Github Actions 사용 방법

1️⃣ 프로젝트 생성 후 git 초기화 및 push

git init
git add . // 전체 파일
git commit -m "커밋내용"
git branch -M main
git remote add origin [깃주소]
git push -u origin main

2️⃣ Github Actions 설정 폴더 및 파일 생성

해당 프로젝트 파일 가장 상단에 폴더 생성

.github - 폴더 생성 (고정값)
workflows - 폴더 생성 (고정값)
deploy.yml - [원하는파일명].yml

3️⃣ deploy.yml - 파일 수정

해당 파일은 들여쓰기 중요


[1] Action 실행 여부 확인

name: Github Actions 실행시켜보기

on:
  push:
    branches:
      -main
  • main 이라는 branch 가 push 될 때마다 동작하는 코드

  • 위 코드 작성 및 commit 후에 github 해당 레포지토리 Actions 탭 확인해보면, 아래처럼 인식이 된다.

    • ✨ 5.. 이라는 커밋이 액션에 남아있다

    • 해당 코드의 오류는 추가적인 액션 코드를 미작성 하였기 때문

[2] 추가코드작성

# Workflow의 이름
# Workflow : 하나의 yml 파일을 하나의 Workflow라고 부른다. 
name: Github Actions 실행시켜보기

# Event : 실행되는 시점을 설정
# main이라는 브랜치에 push 될 때 아래 Workflow를 실행
on:
  push:
    branches:
      - main

# 하나의 Workflow는 1개 이상의 Job으로 구성된다. 
# 여러 Job은 기본적으로 병렬적으로 수행된다.
jobs: 
  # Job을 식별하기 위한 id
  My-Deploy-Job: 
	  # Github Actions를 실행시킬 서버 종류 선택
    runs-on: ubuntu-latest
    
    # Step : 특정 작업을 수행하는 가장 작은 단위
    # Job은 여러 Step들로 구성되어 있다.
    steps: 
      - name: Hello World 찍기 # Step에 이름 붙이는 기능
        run: echo "Hello World" # 실행시킬 명령어 작성
        
      - name: 여러 명령어 문장 작성하기
        run: |
          echo "Good"
          echo "Morning"
          pwd

			# 참고: https://docs.github.com/en/actions/learn-github-actions/variables
      - name: Github Actions 자체에 저장되어 있는 변수 사용해보기
        run: |
          echo $GITHUB_SHA
          echo $GITHUB_REPOSITORY

		- name: Github Actions Secret 변수 사용해보기
		  run: |
			echo ${{ secrets.MY_NAME }}
			echo ${{ secrets.MY_HOBBY }}
  • 위 파일 저장 및 commit , push 후 github에서 레포지토리 Actions 탭 들어가면 ...

    이처럼 순차적으로 Actions 가 실행된다

🎱 steps - [name: Hello World 찍기 # Step에 이름 붙이는 기능]

  • echo : JavaScript 에서 console.log 와 동일한 역할 → "Hello World" 를 출력해줌
  • shell: /usr/bin/bash -e {0} : GitHub Actions가 실행 환경을 로그에 출력

🎱 steps - [name: 여러 명령어 문장 작성하기]

  • 여러 개 작성 시 : run: | 작성 후 하단에 여러개 작성 해주기 !
  • pwd : 현재 경로
    현재 이 명령어를 실행시키는 경로 즉, Github Actions라는 외부 Github이 가지고 있는 컴퓨터에서 출력이 되는 경로

🎱 steps - [name: Github Actions 자체에 저장되어 있는 변수 사용해보기]

  • GITHUB_SHA : 커밋 해시값 출력
  • GITHUB_REPOSITORY : 현재 레포지토리 이름

🎱 steps - [name: Github Actions Secret 변수 사용해보기]

  • 출력 값이 나오지 않은 이유는 MY_NAME 과 MY_HOBBY 라는 Secret 변수를 설정하지 않았기 때문

▶︎ [ Secret 변수를 설정 ]

  • githunb 에서 해당 레포지토리 settings > Secrets and variables > Actions > New repository secret
  • Name : secret 변수명
  • Seceret : 해당 변수에 대한 값
    => Add secret
  • 완료 후 다시 commit 하면 *** 으로 출력. secrets 값을 로그에서 직접 노출되지 않도록 자동으로 마스킹 처리

▪️ github 액세스 키 발급

깃허브는 S3 외부서비스 이기 때문에 AWS 서비스에 접근할 때 암호키 필요 아무나 외부에서 접근할 수 있게 하면 안 됨 인증된 사용자만 출입 가능하게 하는 출입증 같은 느낌

1️⃣ IAM 서비스 접속

users 에서 Create User

2️⃣ 이름 설정

원하는 액세스 키 이름으로 설정

3️⃣ 정책 설정

정책 직접 연결 ( Attach policies directly ) 선택

[정책 1] AmazonS3FullAccess
: S3 에 대한 권한 부여

[정책 2] CloudFrontFullAccess
: 캐시 무효화 및 최신 업데이트 된 파일로 업데이트

[정책 1, 2] 설정 후 사용자 생성

4️⃣ 액세스 키 생성

해당 액세스 키 이름 클릭 후 Security credentials > Create access key 접속

  • Application running outside AWS : AWS 외부에서 실행되는 애플리케이션 선택

[완료]

  • 완료하면 이렇게 Access key / Secret access key 가 발급이 된다

5️⃣ 에서 Actions secret 키 생성

IAM 에서 발급받은 Access key / Secret access key 둘 다 모두 Actions secret 키 생성

▪️ CI/CD 코드 작성

1️⃣ Action 이 정상 작동 하는 지 확인 하는 코드

name: Deploy To S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Github Repository 파일 불러오기
        uses: actions/checkout@v4

      - name: Github Repository 파일 출력하기 (확인하기)
        run: ls
  • uses: actions/checkout@v4 : github 에 있는 checkout 이라는 라이브러리를 실행 (이는 레포지토리에 있는 코드가 저장되어있다고 생각하면 됨)
  • ls : 현재 추가된 파일명을 나열해줌 (파일이 맞게 올라갔는 지 확인)

2️⃣ 최종 코드 작성

name: Deploy To S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Github Repository 파일 불러오기
        uses: actions/checkout@v4

      - name: AWS Resource에 접근할 수 있게 AWS credentials 설정
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ap-northeast-2
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: S3 기존 파일들 전체 삭제 후 새로 업로드
        run: |
          aws s3 rm s3://insta-web-neul --recursive || echo "S3 삭제 실패 또는 버킷 없음"
          aws s3 cp ./ s3://insta-web-neul/ --recursive

      - name: Cloudfront 캐시 무효화
        run: |
          aws cloudfront create-invalidation --distribution-id ED5O7HAB3C1QS --paths "/*" || echo "CloudFront 캐시 무효화 실패"

목표: main 브랜치에 push할 때마다
→ S3 버킷에 정적 파일 전체 업로드
→ CloudFront 캐시 무효화해서 최신 파일이 반영되도록 처리

0개의 댓글