GitHub Actions 에서 두개의 S3 주소를 이용하여 리액트와 서버 배포를 한번에 해결하기

이정연·2023년 6월 2일
0

project034

목록 보기
7/10
  • 저번 블로깅에서 보았듯 깃헙액션을 이용하면 두가지 빌드를 동시에 할 수 있었다(우선순위는 정하기 나름)

  • 이론적으로 생각해보면 s3에 업로드 되는 리액트 파일에는 .env 파일이 포함되어있다. env 파일에는 서버의 EC2 인스턴스 주소가 포함되어 있을것이다.

  • 그렇다면, 서버와 클라이언트를 분리해서 배포할 순 없을까 생각하게 되었다.


생각해보기

  • 우리는 s3를 이용한 정적 웹호스팅을 이용하기 때문에, s3의 버켓 주소가 곧 배포 주소가된다.

  • 서버파일은 s3에 업로드되고 그다음 codedeploy에서 사용된다. 이 둘은 떼어놓을 수 없다.

  • 하지만, s3에 업로드되는 클라이언트 파일은 굳이 서버와 같은 s3가 아니어도 된다 단지 .env파일에 서버의 EC2 DNS 주소만 넣어두면 그것으로 호스팅을 제공하기 때문이다.

  • 그래서 이론적으로 다음의 방법이 가능하다고 생각하여 실행해봤다. 내 aws 아이디로 s3와 codedeploy, ec2를 이용하여 서버배포를 진행하고, 협업하는 프론트분의 s3에 클라이언트 배포를 진행하였다.

  • 깃헙 액션의 gradle.yml 코드는 다음과 같이 구성하였다.

name: Java CI with Gradle

on:
  push:
    branches: [ "dev" ]
  pull_request:
    branches: [ "dev" ]

permissions:
  contents: read
  
env:
  S3_BUCKET_NAME: jungyeon222
  RESOURCE_PATH: ./Server/tripAdvisor/tripAdvisor/src/main/resources/application.yml
 

jobs:
  build1: ---------------------------------------->(1)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code.
        uses: actions/checkout@v2
        
      - name: Install dependencies
        run: npm install
        working-directory: ./Client
        
      - name: Build
        run: npm run build
        working-directory: ./Client
        env:
          REACT_APP_HOST: ${{ secrets.REACT_APP_HOST }}
          REACT_APP_KAKAO_MAP_KEY: ${{ secrets.REACT_APP_KAKAO_MAP_KEY }}
          REACT_APP_GEOCODER_KEY: ${{ secrets.REACT_APP_GEOCODER_KEY }}
          
      - name: Configure AWS credentials                     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.REACT_APP_AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
          aws-secret-access-key: ${{ secrets.REACT_APP_AWS_SECRET_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
          aws-region: ap-northeast-2
      
      - name: Upload to S3
        run: |
          aws s3 sync \
            --region ap-northeast-2 \
            build s3://mainproproject34 \
            --delete
        working-directory: ./Client
  #----------------------------------------------------------------------------------------
  
  build2: --------------------------------------------->(2)
    needs: build1
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
       
        
    - name: Set yml file 
      uses: microsoft/variable-substitution@v1
      with:
        files: ${{ env.RESOURCE_PATH }} 
      env:
        spring.datasource.url: ${{ secrets.RDS_HOST }} 
        spring.datasource.username: ${{ secrets.RDS_USERNAME }} 
        spring.datasource.password: ${{ secrets.RDS_PASSWORD }} 
        jwt.key: ${{ secrets.JWT_KEY }}
        naver.map.client.id: ${{ secrets.NAVER_CLIENT_ID }}
        naver.map.client.secret: ${{ secrets.NAVER_CLIENT_SECRET }}
        
    - name: Add permission
      run: chmod +x gradlew
      working-directory: ./Server/tripAdvisor/tripAdvisor
    - name: Build with Gradle
      run : ./gradlew clean build --exclude-task test
      working-directory: ./Server/tripAdvisor/tripAdvisor
    
    # build한 후 프로젝트를 압축합니다.
    - name: Make zip file
      run: zip -r ./tripAdvisor.zip .
      shell: bash
    
    # Access Key와 Secret Access Key를 통해 권한을 확인합니다.
    # 아래 코드에 Access Key와 Secret Key를 직접 작성하지 않습니다.
    - name: Configure AWS credentials                   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
        aws-region: ap-northeast-2
    
    # 압축한 프로젝트를 S3로 전송합니다.
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./tripAdvisor.zip s3://jungyeon222/tripAdvisor.zip
      
      
    # CodeDeploy에게 배포 명령을 내립니다.
    - name: Code Deploy
      run: >
        aws deploy create-deployment --application-name project034
        --deployment-config-name CodeDeployDefault.AllAtOnce
        --deployment-group-name project034-group
        --s3-location bucket=jungyeon222,bundleType=zip,key=tripAdvisor.zip
  • (1)의 build는 클라이언트 파일의 build 이고, (2)는 서버 파일의 build이다.
  • <<로 표시된 (1)과 (2) 둘다 가지고 있는 name: Configure AWS credentials의 기능은 aws IAM에서 발급받은 ACCESS_KEY와 SECRET_ACCESS_KEY를 이용해 aws의 s3에 접근할 수 있도록 인증받는 것이다.
  • 보면알겠지만, 둘의 secrets의 이름이 다르다. 하나는 REACT_APP_AWS이고, 다른 하나는 AWS로 되어있다.

결과

  • 결과적으로 클라이언트 파일은 프론트계정 s3에 배포하였고, 서버파일은 내 s3에 배포하였다. 그리고, 프론트계정 s3파일의 .env에 내 ec2 인스턴스의 DNS 주소를 넣으면서 무중단 배포가 완성할 수 있었다.

이유

  • 굳이 이렇게 배포를 하게된 이유를 이제 설명하고자 한다.

  • 프론트분께서 배포주소를 바꾸는 기능을 aws에서 구매하신것을 뒤늦게 알게되었다.

  • 그래서 s3는 프론트계정, 서버배포는 내 계정으로 할 수 있는 방법을 찾고자 했다.

  • 사실 그냥 프론트계정으로 서버배포까지 해도되지만, EC2 인스턴스 환경을 다시 만들어야해서 이 부분에서 시간이 더 걸릴 것 같았다.

  • 서버배포는 내 aws 계정으로 하고있고, 내 s3버켓 주소를 이용하면 클라이언트 배포까지 한 계정안에 전부 가능했지만, 배포주소 바꾸는 기능을 잃을 순 없었다.

  • 또한 프론트랑 백엔드랑 나눠져있으니, 클라이언트 배포는 프론트계정에서, 서버 배포는 백엔드 계정에서 관리하는 편이 더 좋을 것 같았다.

profile
반갑습니다.

0개의 댓글