AWS S3와 CloudFront, Route53과 godday로 커스텀 도메인 + GithubActions로 자동 배포까지! 리액트 웹페이지 배포 완전판!

ChanghyeonO·2023년 10월 10일
3

오늘은 기존 cloudtype을 이용해 배포해두었던 프론트엔드 파일을 aws s3로 배포를 시도해볼 예정이다.

AWS S3를 이용하는 이유.

AWS S3 서비스는 Simple Storage Service이다.
즉 쉽게 파일 저장이 가능하다.
서버를 구축해서 파일을 저장할 수도 있지만, 아마존에서 제공하는 S3를 이용할 경우 저장에만 초점을 맞춰 서비스를 사용할 수 있다.

AWS S3의 장점.

1. 높은 내구도로 중요한 정보를 안심하고 저장할 수 있다.

99.999의 객체 내구도를 가진 인프라다. 여기서 내구도는 유실될 가능성을 나타낸다.
여러시설과 각 시설에 중복 저장되므로 서버 하나가 파괴되더라도 다른 저장소에 남아있다.

2. S3는 저렴한 비용으로 사용가능하다.

서버를 운영한다고 하면 인스턴스를 구매해야하고, 이에 따른 비용이 만만치 않다.
S3는 사용하는 만큼만 비용을 내면 되기에, 서버에 대한 진입장벽이 낮고, 파일을 엑세스 하는 빈도에 따라서, 저장 방식을 다르게 설정함으로 비용이 다르게 적용 된다.

3. 객체 가용성이 높다.

파일이 서비스 되는 기간이 년 중 99.999% 이므로 서비스가 중단될 걱정 없이 S3를 사용할 수 있게 된다.

4. 보완성이 뛰어나다.

SSL을 통해 데이터 전송과 암호화를 하므로 해킹 걱정이 적어진다.

5. 이벤트 알림 전송.

S3로 파일이 업로드 되었을 때 그 사실을 다른 서비스에 알려서, 서비스를 트리거 할 수 있다. 즉, S3와 연계된 서비스들을 사용하는데 상당히 유용하다.

6. 고성능이다.

지역을 선택해서 빠르게 업/다운로드가 가능하다.
또한 지연시간 최소화를 위한 멀티 파트 업로드를 지원한다.

출처

CloudFront를 이용하는 이유.

AWS CloudFront란?

AWS에서 제공하는 CDN(Content Delivery Network) 서비스.
전세계 AWS 각 리전의 엣지 로케이션에 리소스의 복사본을 미리 로드해놓고, 사용자들이 짧은 지연 시간에 파일을 받을 수 있도록 해준다.
커스텀 도메인을 사용해서 Route53을 거쳐 HTTPS를 통해 정적 리소스를 호스팅하려면 S3만으로는 안 되기 때문에, CloudFront와 S3를 함께 이용하게 된다.

이점.

CloudFront를 S3와 함께 사용하면 다음과 같은 이점이 있다.

CDN을 통한 빠른 전송 속도.
S3에 직접 액세스 하는 것보다 싼 요금.
S3에 부하가 몰리지 않고 엣지 로케이션에 캐싱되어 부하 분산.
커스텀 도메인 사용 가능.
예: *.musma.net
HTTPS 사용 가능
예: https://
CloudFront에서 제공하는 각종 통계, 보안 기능 사용 가능
S3의 정적 사이트 호스팅 기능을 사용하면 http로는 되는데 https는 안된다.
CloudFront를 https로 시작하는 커스텀 도메인 주소를 사용할 수 있을 뿐만 아니라 위와 같이 여러가지 이점이 있다.

출처

과정 및 순서

  1. IAM 권한 설정하기
  2. S3에서 버킷 생성
  3. 빌드한 프로젝트 S3 버킷에 업로드
  4. CloudFront 배포

IAM 권한 설정.

AWS에서 IAM 검색 후 최상단 IAM 클릭.


사용자 클릭해서 들어가준다.

사용자 생성 클릭.

사용자 이름 적어주고 다음 클릭.

직접 정책 연결 - S3와 CloudFront 검색 후 체크 해주기 - 다음 버튼 클릭.

사용자 생성 버튼 클릭.
이제 엑세스 키를 생성해보자.
이전에는 사용자 생성할 때, 엑세스키 같이 발급 받는 체크란이 있었는데, 이제는 따로 설정해줘야하는 것 같다. 아무리 찾아봐도 없어서 한참 찾아 헤맸다.

사용자 이름 클릭.

엑세스 키 만들기 클릭.

위와 같이 체크해주고 다음 버튼 클릭.

태그 작성 후 엑세스키 만들기 클릭.

위처럼 나오는데 .csv 파일을 다운로드 받아 컴퓨터에 저장해두도록 하자.
aws 사이트에서는 나중에 다시 확인할 수 없다.
완료 버튼 누르면 생성 완료.

AWS S3 버킷 생성.


이제 S3 버킷을 만들어 설정해보자.
들어가서 버킷만들기 클릭.

버킷 이름을 정해주고 ACL 활성화됨 클릭.

객체 라이터 체크 후 모든 퍼블릭 엑세스 차단을 풀어주고 아래 동의란 체크.
나머지는 더 건들이지 말고 그냥 아래 쭉 내려서 버킷 만들기 클릭.

버킷 생성된 걸 확인할 수 있다. 위 사진과 같이 이름 클릭.

속성 클릭.

쭉내려서 정적 웹사이트 호스팅에 편집 버튼 클릭.

정적 웹 사이트 호스팅 활성화 버튼 눌러주고, 인덱스 문서와 오류문서 전부 index.html로 설정해주자. 그리고 아래 내려서 변경사항 저장.

권한에 들어가 버킷 정책에 편집 버튼 클릭.


버킷 ARN을 복사하고 우측 상단 정책 생성기 클릭.

Select Type of Policy에서 S3 Bucket Policy 클릭 및 Principal에 *입력, Actions에 getObject 선택.

arn에는 아까 복사했던 걸 복붙해준 뒤 Add Statement 클릭.
(실수했다 arn에 복붙 한 뒤 /*를 꼭 붙여주자...
arn:aws:s3:::bunnypit/*이런식으로 말이다.)

위처럼 나오는데 Generate Policy 누르자.

위처럼 Json document가 나오는데 전부 긁어서 복사.

아까 버킷 정책 편집에 정책쪽에 붙여넣어준다. 그리고 변경사항 저장.

여기에 npm build된 리액트 파일을 올려도 되지만 AWS CLI를 이용해보도록 하자.

AWS CLI로 S3버킷에 코드 업로드.

AWS CLI 다운로드 링크
위 링크에서 AWS CLI를 다운로드 한다. 나는 MAC OS라 거기에 맞는 버전으로 설치했다.

터미널을 열어 위와 같이 입력해준다.
aws configure --profile [유저명]
위에서 유저명은 아까 IAM에서 추가한 사용자의 이름이다.
secret key와 secret access key는 아까 다운로드 받은 IAM 엑세스키다.
Default region name [None]:에는 ap-northeast-2
Default output format [None]:에는 json
을 입력해주자.

그리고 배포할 프로젝트 디렉토리에서 명령어를 입력해야한다.
aws s3 sync ./build s3://[S3 버킷 이름] --profile=[사용자 아이디]

터미널에서 위와 같이 입력해주면 되는데, 자주 사용할 명령어라 package.json에 스크립트로 추가해두자.

이렇게 하면 npm run deploy 명령어로 입력하면 된다.

이런식으로 터미널에 입력하면 배포가 된다.
배포가 정상적으로 되었는지 확인해보자.

일단 S3에 다시 들어가 bunnypit을 클릭해보면 객체에 파일이 올라간 걸 확인할 수 있다.

아까 S3에 만들어두었던 버킷의 속성에 들어가서 아래로 내리면

위처럼 정적 웹 사이트 호스팅이라 되어있는데, 아래 링크가 배포주소다.

들어가면 위처럼 잘 나온다.

CloudFront 설정.


검색창에 cloudfront 검색해서 우측에 배포 생성 버튼 클릭.


원본 도메인 선택 누르면 S3 목록이 나온다.

원본 엑세스에서 세번째 버튼 체크, 새 OAI 생성을 눌면 자동으로 생성된다.

오리진 쉴드 활성화 하고 원하는 리전 선택한다. 난 가까운 서울로 했다.

그리고 아래로 내려 뷰어 프로토콜 정책에서 두번째 버튼 체크.
이렇게 하면 http 접속을 https로 리다이렉트 시킬 수 있다.

WAF는 활성화 할까 고민했는데, 사용한 만큼 돈나간다는 코멘트가 아래 달려있길래 비활성화, 하단에 기본값 루트 객체는 index.html로 설정해주었다.

그리고 난 구매한 도메인이 있어 해당 도메인으로 커스텀 도메인을 연결해주었다.(바로 안되니 아래에 사용법 그대로 따라하자)

아래 배포 생성 버튼 눌러주자.

배포된 사이트 들어가보니 위 같은 에러난다. 다음에 알아보자.
-배포에 커스텀 도메인까지 다 적용해서 왔다.... 이틀간 씨름하다 보니 결국 해결...

일단 위 원인은 내가 cloudfront 적용하고 나서, S3에서 퍼블릭 액세스를 다시 차단해버렸는데, 차단을 풀어주고 나니 잘되었다.

S3 버킷에서 위 같은 상태로 퍼블릭 액세스 차단이 비활성화 되어있어야 한다. 그래야 나중에 S3에 배포파일을 새로 올릴 때도 반영이 된다.

여튼 cloudfront에서 제공해주는 기본 도메인으로 들어가면 이제 잘 들어가진다.

Route53으로 커스텀 도메인 입히기.

이제 커스텀 도메인을 입혀보자.
도메인 구매는 Route53을 통해서도 할 수 있지만, 나는 이미 Godaddy라는 도메인 사이트에서 이미 구매해놓은 도메인이 있기 때문에 해당 도메인을 Route53에서 사용 가능하도록 옮기는 작업을 해주었다.

일단 위처럼 Route53을 검색해서 들어가자.

그리고 왼쪽 메뉴바에서 호스팅 영역을 눌러주고 우측 상단에 호스팅 영역 생성 버튼을 눌러준다.

그리고 적용할 도메인 이름과 설명을 작성해준다.

그리고 우측 하단 호스팅 영역 생성 버튼 클릭.

위처럼 만들어진 걸 확인할 수 있다.
호스팅 영역 이름쪽에 나의 경우엔 bunny-pit.com 이라 되어있는 걸 클릭해주면

위처럼 나온다. 여기서 NS 값을 도메인을 구매한 사이트로 들어가 입력해줘야한다.

나는 GoDaddy에서 DNS 관리를 들어가줬다.

이런식으로 DNS에 네임서버, 그리고 네임서버를 변경 버튼을 눌러주자.

위처럼 차례차례 아까전의 레코드에서 NS 값을 입력해주면 된다.
(마지막의 .은 꼭 빼고 넣어주자)

그리고 터미널에서 nslookup -type=NS 내주소 이런식으로 입력하면 nameserver가 aws로 제대로 이전되었는지 확인 가능하다.

그리고 cloudfront에 해당 도메인을 적용하려면 AWS Certificate Manager(ACM)에서 인증서를 받아야한다.

ACM을 검색해 들어온 다음 우측 상단에 요청버튼을 눌러준다.

퍼블릭 인증서 요청 체크 후 다음 버튼 누르기.

구매했던 도메인을 작성한뒤 다른 거 건들이지 말고 우측 하단 요청 버튼 누르자.
(나는 이상하게 www.페이지가 안들어가져 일단 www.까지 전부 다 때려넣었다,,, ㅎㅎ 여기가 문제인지는 잘 모르겠다,,,)

그럼 인증서 나열에 인증서가 발급 대기중 상태로 나오게 된다
(나는 이미 해놓은 거라 발급됨으로 나오지만 여튼,,,)
인증서 ID를 클릭해주자.

그럼 도메인에 Route53에서 레코드 생성 버튼이 있는데 이거 클릭해주자.

그럼 위처럼 나오고 클릭해서 레코드 생성 눌러주자.

그럼 아까 라우트53 레코드에 위처럼 CNAME 두개가 추가되는 걸 확인할 수 있다.
그리고 바로 우측 상단 레코드 생성 버튼을 눌러보자.

나는 위처럼 www.까지 각각 두개를 생성해주었다.
레코드 유형은 A, 별칭 체크, 엔드포인트 선택은 CloudFront 배포에 대한 별칭을 선택, 배포 선택은 cloudfront에 나온 기본 도메인을 작성해주자.

위처럼 생성된 것을 확인할 수 있다. 나는 두개 생성했으니까 두개가 나와야한다.

이제 다시 cloudfront로 들어가주자.

cloudfront에서 ID클릭하면 위와 같은 화면이 나오는데 설정 편집 버튼을 클릭해준다.

그럼 위처럼 CNAME에 내 도메인을 입력해주고 사용자 정의 SSL 인증서에 인증서가 생긴 걸 확인할 수 있다. 클릭해서 변경사항 저장을 눌러주자.
(여기서 도메인을 www.과 두개를 적용한 것도 www.으론 해당 도메인이 접속이 안되서 그랬다.)

여기까지 하면 기본 cloudfront 세팅은 끝난다.

Github Actions

이제 프론트엔드 코드의 환경변수를 세팅해주어야하는데 아무리 찾아봐도 s3든 cloudfront든 환경변수를 세팅하는 방법이 없다.
이거 때문에 이틀밤을 새면서 찾았는데,,, S3나 CloudFront 자체에서 환경변수 세팅이 불가하다는게 결론.
S3는 서버가 아니라 스토리지라 일반 서버에 비해 제약이 많다.

AWS CodeBuild나 Secrets Manager를 이용하면 가능하다고 하던데, 너무 복잡해서 패스하고 찾은게 Github Actions다.

일단 Github Actions를 이용하면 CI/CD가 가능하다.
그리고 무엇보다 Github Actions Secrets를 이용해 환경변수를 작성할 수 있다.

일단 깃헙 레포에 Settings를 들어가자.

좌측 메뉴에 있는 Security에 Secrets and variables - Actions를 들어가준다.

그럼 New respository secret이 있는데
Name에 AWS_ACCESS_KEY_ID와 IAM에서 발급 받았던 엑세스 키를 Secret에 넣어주고 Add secret 을 눌러 추가해준다.
AWS_SECRET_ACCESS_KEY도 추가해 IAM의 secret 엑세스 키를 작성해주자.
나머지 환경변수도 필요한 건 다 넣어주면 된다.
REACT_APP_API_URL은 백엔드 api url을 넣어주었다.

여기서 GithubActions Secrets의 단점? 이 있는데, 한번 등록한 환경변수는 다시는 확인이 불가능하다.
보안상 더 안전하니 좋은건가? 머 여튼 그렇다.

그리고 vscode로 들어가 내 레포 최상단 위치에 .github 폴더 생성 - workflows 폴더 생성 - deploy.yml 파일을 생성해주자.

name: CI/CD

# 'main' 브랜치에 푸시될 때 워크플로우를 실행
on:
  push:
    branches:
      - main

# 작업 정의
jobs:
  build:
    # 이 작업은 우분투 최신 버전에서 실행
    runs-on: ubuntu-latest

    steps:
      # 1단계: 레포지토리 코드 체크아웃
      - name: Checkout source code
        uses: actions/checkout@v2

      # 2단계: 우분투 버전을 확인 (선택)
      - name: Check Ubuntu version
        run: lsb_release -a

      # 3단계: 환경 변수 파일 생성
      - name: Create env file
        run: |
          touch .env
          echo REACT_APP_API_URL=${{ secrets.REACT_APP_API_URL }} >> .env
          cat .env

      # 4단계: 프로젝트 의존성을 설치
      - name: Install dependencies
        run: npm install

      # 5단계: 프로젝트를 빌드
      - name: Build
        run: npm run build

      # 6단계: AWS CLI 버전 표시(선택)
      - name: SHOW AWS CLI VERSION
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: aws --version

      # 7단계: 빌드 파일을 S3 버킷에 동기화.
      - name: Sync Bucket
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: |
          aws s3 sync \
            --region ap-northeast-2 \
            build s3://bunnypit\
            --delete

그리고 나는 위처럼 코드를 작성해주었다.
단계별로 실행되는 코드들인데 이해하기 쉽게 설명을 추가했다.
환경변수를 생성하는 코드는 npm build전에 작성해주어야한다.
그리고 커밋, 푸시를 해주자.

그럼 Actions의 workflow에 빙글빙글 노란색이 돌아가고 있을텐데, 나는 Eslint 설정과 타입스크립트 적용으로 생긴 경고문 때문에

위처럼 자꾸 빌드에 실패했었다. 꼭 경고문은 전부 해결하고 올려야한다...

여튼 위처럼 초록색 체크가 뜨면 성공.

S3 버킷에 들어가 파일이 잘 올라갔는지 마지막 수정시간을 확인해보자.

그리고 마지막으로 내가 적용한 커스텀 도메인을 들어가보면 적용이 잘된 것을 확인할 수 있다.

그리고 CloudFront에 도메인 적용하고 바로 해당 도메인을 쓸 수 있는게 아니라 완전히 구동되는데까지 시간이 좀 걸리니 해놓고 밥먹고 오든 놀다오든 하면 어느새 적용되어있는 모습을 볼 수 있다.

여기까지 S3 + CloudFront + Route53 + Github Action까지 적용법 설명을 마친다.

profile
꾸준한 기록을 통해, 좋은 개발자가 되겠습니다.

0개의 댓글