본문 바로가기
TIL

Github Action 하나로 자동 배포 WorkFlow 만들기 ( Spring Boot )

by qbinee 2023. 3. 31.

고민 사안

1. application.yml 에 있는 민감정보 관리
2.. 배포시 workflow 하나로 진행하고 싶음

S3 + CodeDeploy 를 선택하지 않은 이유

빠른 시간안에 개발 환경을 구성하고 싶기 때문이다
AWS CodeDeploy 는 배포 파이프 라인을 구성하는데 많은 설정과 시간이 필요하다
현재 서비스는 백앤드 (1명 ) + 프론트 (1명) 이기 때문에  빠른 개발을 위해 배포된 개발 환경을 빠르게 적용시킬 수 있어야한다
그리고 예상된 서비스 규모가 작다 즉 많은 배포 파이프 라인은 쓸모없는 리소스라고 판단했다

그러나 AWS CodeDeploy를 사용하면 애플리케이션의 상태를 모니터링하고 문제가 발생하면 롤백하는 등의 기능을 제공하기 때문에 안정성이 높아진다. 또한 다수의 인스턴스를 사용하는 경우에는 AWS CodeDeploy를 사용하는 것이 더 유리하다.
따라서 추후의 프로덕션 환경에서는 AWS CodeDeploy를 사용하는것으로 마이크레이션을 한다면 좋을 듯 싶다

해결 방안

Github Action 은 개인 레포의 Setting 에서  action secret 설정이 가능하다

 

** environment secrets 와 repository secrets 차이 ( ChatGPT )

  1. Environment Secrets 환경 변수(Environment Variables)에 저장되는 시크릿입니다. 이 시크릿은 특정 환경(예: 빌드나 배포 작업)에서만 사용되도록 지정됩니다.
  2. Repository Secrets 리포지토리에서 사용되는 시크릿으로, 리포지토리 전체에서 사용할 수 있습니다. 이 시크릿은 작업 흐름에서 사용됩니다.

WorkFlow 내에서 setting에서 설정한 키를 접근하도록 한다

aws.yml

name: Deploy to AWS EC2

on:
  push:
    branches:
      - main
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'

    - name: Build with Gradle
      run: ./gradlew build -x test

    - name: Install SSH
      run: sudo apt-get install openssh-client

    - name: Remove old JAR file from EC2 instance
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USERNAME }}
        key: ${{ secrets.EC2_PRIVATE_KEY }}
        script: |
          sudo rm -rf /home/ubuntu/infocat

    - name: Copy files to EC2 instance
      uses: appleboy/scp-action@master
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USERNAME }}
        key: ${{ secrets.EC2_PRIVATE_KEY }}
        source: 'build/libs/resumerry-v2-0.0.1-SNAPSHOT.jar'
        target: '/home/ubuntu/infocat'

    - name: SSH into EC2 instance and start the application
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USERNAME }}
        key: ${{ secrets.EC2_PRIVATE_KEY }}
        run: |
          cd /home/ubuntu/infocat/build/libs/
          java -jar -DDB_URL=${{ secrets.DB_URL }} \
                -DDB_USERNAME=${{ secrets.DB_USERNAME }} \
                -DDB_PASSWORD=${{ secrets.DB_PASSWORD }} \
                -DMAIL_USERNAME=${{ secrets.MAIL_USERNAME }} \
                -DMAIL_PASSWORD=${{ secrets.MAIL_PASSWORD }} \
                -DJWT_SECRET=${{ secrets.JWT_SECRET }} \
                resumerry-v2-0.0.1-SNAPSHOT.jar

${{ }} 은 Github Action에서만 사용되는 문법으로 secret에 설정된 키를 참고한다

 

거의 마지막 라인의 -D 명령어는 자바 어플리케이션 실행시 시스템 프로퍼티를 설정

prod 에서 사용되는 yml에서 접근가능 하도록 돕는다

 

application.yml

spring:
  profiles:
    active: prod

 

application-prod.yml

spring:
  jackson:
    serialization:
      fail-on-empty-beans: false
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  application:
    bane: user-service
  sql:
    init:
      mode: always
  datasource:
    url: ${DB_URL}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database: mysql
    database-platform: org.hibernate.dialect.MySQL8Dialect
    hibernate:
      ddl-auto: none
    show-sql: true
    defer-datasource-initialization: false
  mail:
    host: smtp.gmail.com
    port: 587
    username: ${MAIL_USERNAME}
    password: ${MAIL_PASSWORD}
    properties:
      mail:
        smtp:
          starttls:
            enable: true
            required: true
          auth: true
          connectiontimeout: 5000
          timeout: 5000
          writetimeout: 5000
jwt:
  secret: ${JWT_SECRET}

swagger-ui:
  path: http://localhost:8080

yml 의 ${}은 프로퍼티값을 변수명으로 접근 간으하게 한다

해결방안 해설

직접 SSH 에 접근하여 코드를 복사하는 방식이다.
이전 코드는 모두 깃허브에 남아있기 때문에 이전 jar 파일을 ssh 의 삭제 명령어로 삭제하였다
그리고 다시 빌드시킨 jar 파일을 ec2 인스턴스에 복사하여 넣는다

아무래도 직접 복사하는것이다 보니까 사용량 걱정이 좀 있었는데, 버틸만 한가보다

나중에는 도커 이미지 설정해서 부담을 줄여줘야지