[AWS] GitHubActions에서 AWS CLI를 이용해 S3 + CloudFront로 스토리북 배포하기

Chex·2023년 10월 2일
1

우아한테크코스

목록 보기
17/19
post-thumbnail

깃허브액션 Ci환경에서 스토리북을 EC2 AWS CLI를 이용해 S3 + CloudFront로 배포하는 방법을 시도하게 된 이유?

문제상황
저희 팀의 프론트엔드 배포 과정에는,
'깃허브액션에서 도커 이미지 빌드 > 도커허브에 push > ec2서버에서 해당 이미지를 Pull 받아서 도커 컨테이너를 생성'하는 단계가 있습니다.
그런데 도커 컨테이너를 생성하는 과정에서 스토리북 빌드를 실행할 때 문제가 있었어요.(아래 주석처리한 부분)

 FROM --platform=linux/arm64 node:18.16.1-alpine as builder
 WORKDIR /app

 # build
 COPY . /app
 RUN yarn build:prod
 #RUN yarn build:sb

 # nginx 
 FROM nginx:latest
 RUN rm -rf /etc/nginx/conf.d
 COPY conf /etc/nginx
 COPY --from=builder /app/dist >/usr/share/nginx/html
 #COPY --from=builder /app/storybook-static /usr/share/nginx/html/storybook

 EXPOSE 3000
 CMD ["nginx", "-g", "daemon off;"]

시도한 다른 방법
배포 자동화를 젠킨스에서 깃허브액션으로 마이그레이션하면서부터 이 과정이 잘 작동하지 않았는데 추측하기로는 깃허브 액션에서의 환경(amd64)과 도커 컨테이너 내부 환경(arm64)이 다르기 때문에 제대로 패키지가 설치되지 않아서 생기는 문제라고 생각했기 때문에...
도커 베이스 이미지를 node:18.16.1-alpine에서 두 환경 모두 지원하는 node로 바꿔보았으나 해결 되지 않았습니다.

또 다른 문제
깃허브액션에서 바로 s3로 파일을 업로드하기 위해서는 aws key가 필요했지만 보안상의 이유로 사용할 수 없었습니다. 하지만 ec2에서 s3에 접근할 수 있는 IAM 권한이 있었기 때문에 아래와 같은 방법으로 다시 도전해보았어요!

그래서

상황공유

기존의 ec2서버에서 nginx를 통해 스토리북을 배포하는 방식 대신,
깃허브액션 ci환경에서 스토리북 빌드 파일을 ec2를 거쳐 s3에 전달해 s3 + CloudFront로 배포하는 방법을 시도해보게되었습니다.
이 게시글은 프로젝트에 적용하기 전 연습했던 내용을 정리한 글입니다.

EC2 인스턴스 생성

EC2 인스턴스 생성하는 방법을 정리한 블로그를 참고하여 인스턴스를 생성해줍니다.
인스턴스 생성 완료

EC2 인스턴스 키페어(보안 인증서) 생성 및 권한 설정

  • ~/.ssh 경로에 키페어를 저장합니다.

    ls *.pem
    sudo mv chex-ec2-webserver-keypair.pem ~/.ssh

    EC2 인스턴스 키페어

  • 소유자만 읽기/쓰기할 수 있도록 권한을 설정합니다.

    chmod 600 chex-ec2-webserver-keypair.pem

    키페어 권한 설정

SSH 연결을 위한 Config 설정

config 설정을 하지 않을 경우 아래와 같이 입력해야하는 번거로움이 있습니다.

ssh -i chex-ec2-webserver-keypair.pem ubuntu@<ec2_ip_public_dns>
vi config // config 파일을 엽니다.

config파일내용

i (insert)→ 위 내용 입력 → esc:wq
위와 같이 config파일 내용을 수정해줍니다.

ssh [HostName]으로 실행할 수 있습니다.

AWS CLI 설치

인스턴스 아키텍처에 맞게 설치해주세요
(아래 명령어는 Linux ARM 기준입니다.)

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
$ unzip awscliv2.zip
$ sudo ./aws/install

$ aws --version
aws-cli/2.13.22 Python/3.11.5 Linux/5.19.0-1025-aws exe/aarch64.ubuntu.22 prompt/off

$ rm -f awscliv2.zip # 설치 되었으니 zip은 삭제합니다.

S3 버킷 생성

AWS - S3 버킷 생성 및 파일 업로드 하기글을 참고해 버킷을 생성합니다.

{
  "Id": "Policy1696247568640",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1696246121541",
      "Action": [
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::chex-bucket/*",
      "Principal": "*"
    }
  ]
}

위와 같이 버킷정책을 설정해주었습니다.
-> 이 부분은 CloudFront 배포 생성 시 바뀌는 부분이기 때문에 생략하셔도 됩니다.

IAM 역할 생성

역할 만들기 글을 참고해 역할을 생성해줍니다.

권한 정책

사용자 및 사용자그룹은 생성하지 않고 ec2-chex-role이라는 역할만 생성 후 AmazonEC2FullAccess, AmazonS3FullAccess 권한을 주었습니다.

EC2 IAM 권한 설정

IAM 역할 설정

EC2 인스턴스 선택 > 작업 > 보안 > IAM 역할 수정에서
위와 같이 ec2-chex-role이라는 역할을 인스턴스에 연결합니다.

이제 터미널에서 $ aws s3 ls 명령어를 통해 버킷 목록을 확인할 수 있습니다.

s3 목록확인

GitHub Actions에 Self-hosted Runner 등록

Self-hosted Runner 등록


$ mkdir actions-runner && cd actions-runner // 호스트 서버에서 디렉토리 생성
$ curl -o actions-runner-linux-arm64-2.309.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.309.0/actions-runner-linux-arm64-2.309.0.tar.gz // 가장 최신의 Runner 패키지 다운로드

$ tar xzf ./actions-runner-linux-arm64-2.309.0.tar.gz // 다운로드 받은 파일 압축해제

$ ./config.sh --url https://github.com/[저장소주소] --token [토큰값] // 저장소 연결

$ nohup ./run.sh // 등록한 Self-hosted Runner 활성화(세션이 종료되어도 실행이 유지되도록 함)

nohup(no hang up)

GitHub Actions 워크플로우 추가

name: Storybook Deploy To S3

on:
  push:
    branches:
      - hyeryongchoi

jobs:
  build:
    runs-on: ubuntu-22.04
    defaults:
      run:
        working-directory: ./
    concurrency:
      group: ${{ github.workflow }}
      cancel-in-progress: true

    steps:
      - name: Use repository source
        uses: actions/checkout@v3

      - name: Use node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18.x

      - name: Cache Yarn global cache
        uses: actions/cache@v3
        with:
          path: '**/.yarn'
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-

      - name: Cache Yarn project cache
        uses: actions/cache@v3
        with:
          path: '**/.yarn/cache'
          key: ${{ runner.os }}-yarn-project-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-project-

      - name: Install dependencies
        run: yarn install --immutable

      - name: Build Storybook
        run: yarn build-storybook

      - name: Upload storybook build files to temp artifact
        uses: actions/upload-artifact@v3
        with:
          name: Storybook
          path: ./storybook-static
  deploy:
    needs: build
    runs-on: [self-hosted, Linux, ARM64]
    steps:
      - name: Remove previous version app
        working-directory: .
        run: rm -rf frontend/storybook

      - name: Download the built file to AWS EC2
        uses: actions/download-artifact@v3
        with:
          name: Storybook
          path: frontend/storybook

      - name: Upload to S3
        run: |
          aws s3 sync frontend/storybook s3://chex-bucket/storybook --delete
      #- name: Cloudfront invalidation # 클라우드 프론트 연결 후 주석 제거
      #  run: |
      #    aws cloudfront create-invalidation \
      #      --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} \
      #      --paths "/storybook/*"

S3 버킷 확인

버킷내용

워크플로우 실행 후 S3 버킷으로 들어가보면 위와 같이 스토리북 빌드 파일들이 잘 들어가있는 것을 확인할 수 있습니다.

CloudFront 배포 생성

CloudFront 배포 생성 글을 참고하여 클라우드 프론트 배포를 생성합니다.

버킷 내의 storybook디렉토리 안에 index.html이 있기 때문에 원본 경로에 /storybook을 추가합니다.

사용하고 있는 역할에 CloudfrontFullAccess 권한 추가

GitHubActions 캐시 무효화 작업 추가

클라우드프론트 배포ID

깃허브 시크릿으로 등록

CloudFront 배포 ID(distribution id)를 GitHub Secrets에 등록해줍니다.

      - name: Cloudfront invalidation
        run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.AWS_DISTRIBUTION_ID }} \
            --paths "/storybook/*"

파일 업데이트 시 캐시 무효화를 해야 최신버전을 바라볼 수 있기 때문에 클라우드프론트 권한을 추가한 후 워크플로우 마지막 단계에 캐시 무효화를 추가해주었습니다.

스토리북 배포 완료 👏


참고

EC2 생성 및 접속하기
S3+Cloudfront를 활용한 정적 웹 배포
AWS - S3 버킷 생성 및 파일 업로드 하기
AWS IAM 계정 생성
EC2에 GitHub Actions self-hosted runner를 띄우는 방법
GitHub Actions에 Self-hosted Runner 등록하기
t4g 인스턴스와 ARM 아키텍처
뱅크샐러드 Web chapter에서 GitHub Action 기반의 CI 속도를 개선한 방법
[AWS] Cloudfront 캐시 무효화
AWS S3로 이미지 배포하기

profile
Fake It till you make It!

0개의 댓글

관련 채용 정보