저번 블로깅에서 보았듯 깃헙액션을 이용하면 두가지 빌드를 동시에 할 수 있었다(우선순위는 정하기 나름)
이론적으로 생각해보면 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로 되어있다.
굳이 이렇게 배포를 하게된 이유를 이제 설명하고자 한다.
프론트분께서 배포주소를 바꾸는 기능을 aws에서 구매하신것을 뒤늦게 알게되었다.
그래서 s3는 프론트계정, 서버배포는 내 계정으로 할 수 있는 방법을 찾고자 했다.
사실 그냥 프론트계정으로 서버배포까지 해도되지만, EC2 인스턴스 환경을 다시 만들어야해서 이 부분에서 시간이 더 걸릴 것 같았다.
서버배포는 내 aws 계정으로 하고있고, 내 s3버켓 주소를 이용하면 클라이언트 배포까지 한 계정안에 전부 가능했지만, 배포주소 바꾸는 기능을 잃을 순 없었다.
또한 프론트랑 백엔드랑 나눠져있으니, 클라이언트 배포는 프론트계정에서, 서버 배포는 백엔드 계정에서 관리하는 편이 더 좋을 것 같았다.