1. workflow는 정상 작동, 배포 페이지는 변경이 없다?
기존 React 프로젝트를 AWS의 S3, CloudFront, Route53 을 활용하여 배포 환경을 구축하였다. 이 환경에서 GitHub Action을 통한 CI/CD 파이프라인을 아래와 같이 구성하였다.
name: Front Deployment
on:
pull_request:
branches:
- main
jobs:
build:
name: react build & deploy
runs-on: ubuntu-latest
steps:
- name: checkout Github Action
uses: actions/checkout@v3
- name: Get npm cache directory
id: npm-cache-dir
run: |
echo "::set-output name=dir::$(npm config get cache)"
- uses: actions/cache@v3
id: npm-cache
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: install npm dependencies
run: npm install
- name: react build
run: npm run build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_ACCESS_KEY_ID }}
aws-region: ap-northeast-2
- name: Upload to S3
env:
BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME}}
run: |
aws s3 sync \
./dist s3://$BUCKET_NAME
- name: CloudFront Invalidation
env:
CLOUD_FRONT_ID: ${{ secrets.AWS_CLOUDFRONT_ID}}
run: |
aws cloudfront create-invalidation \
--distribution-id $CLOUD_FRONT_ID --paths /*
main에 pull-request를 하는 경우 github action을 통해 아래 과정을 진행하도록 구축하였다.
1. npm 캐시확인
2. npm build
3. AWS s3버킷에 빌드 파일을 업로드
4. Cloudfront 캐시무효화

핫픽스 적용 후 main 브랜치에 PR을 생성했으나, 배포된 사이트에서는 오류가 수정되지 않은 상태로 남아있었다.
문제 원인을 파악하기 위해 GitHub Actions 탭을 확인해보니, 워크플로우는 오류 없이 정상적으로 실행된 것으로 표시되었다.

더 자세히 살펴보기 위해 실행 로그를 확인했지만, 모든 단계가 성공적으로 완료된 것으로 나타났다. 빌드, S3 업로드, 그리고 CloudFront 무효화 단계까지 모두 정상적으로 처리된 것으로 기록되어 있었다.
그렇다면 무엇이 문제일까? AWS s3를 들어가 최신 갱신이 언제인지 확인하였지만 정상이었다.
s3에 업로드는 되었지만, 오류 해결은 되지 않았다? 그렇다면 CloudFront 캐시가 갱신 안된 문제인 것으로 보고 AWS CloudFront 무효화 기록을 살펴 보았다.

무효화 기록을 확인해보니 /* 로 무효화 된 것이 아닌, 위 사진과 같이 /data, /tmp, /lib ... 등 이상한 경로로 무효화 된 것을 확인할 수 있다. 실제 내프로젝트에 존재하지 않는 경로이기 때문에 정상적으로 무효화가 작동됐을 리가 없다.
2. 원인 분석
그렇다면 원인은 이러한 캐시 무효화 동작이 일어난 원인은 무엇일까?
위 경로를 살펴보면 Ubuntu 운영체제의 경로 방식이라는 것을 알 수 있다.
GitHub Actions 워크플로우 파일에서 --paths /*라고 작성했을 때, 이 명령은 Ubuntu 러너에서 실행된다. 여기서 중요한 점은 /* 가 Ubuntu Shell에서 해석되는 포인트이다.
- name: CloudFront Invalidation
env:
CLOUD_FRONT_ID: ${{ secrets.AWS_CLOUDFRONT_ID}}
run: |
aws cloudfront create-invalidation \
--distribution-id $CLOUD_FRONT_ID --paths /*
기존 위처럼 CloudFront 캐싱 무효화를 진행하는 경우 /* 라는 경로가 AWS CLI에 도착하기 전에, Ubuntu Shell에서 /* 가 의미하는 루트디렉토리 바로 아래에 있는 모든 파일과 디렉토리를 의미하기 때문에 /bin /boot /dev /etc /home... 와 같이 펼쳐진 상태로 AWS CLI로 전달되게 된다.
결과적으로 AWS CLI는 --paths /bin /boot /dev /etc /home... 같은 형태로 실행된다.
3. 해결 방법
따옴표를 추가하여 --paths "/*"로 작성하면, Ubuntu Shell이 /*(글로브 패턴)을 확장하지 않고 문자 그대로 /*를 AWS CLI에 전달하게 된다.
# cloudfront로 무효화
- name: CloudFront Invalidation
env:
CLOUD_FRONT_ID: ${{ secrets.AWS_CLOUDFRONT_ID}}
run: |
aws cloudfront create-invalidation \
--distribution-id $CLOUD_FRONT_ID --paths "/*"
작은 따옴표 두 개를 추가하는 간단한 수정이었지만, 생각보다 CI/CD 파이프라인 흐름에 대해 담겨져 있기에 글로 작성하게 되었다.