[CI/CD 실습(1)] Github Actions와 AWS EC2를 활용하여 CI/CD 파이프라인 구축하기

Turtle·2024년 8월 12일
0

[인프라] CI/CD

목록 보기
4/5
post-thumbnail

👉전체적인 흐름

  • Github Repository에 코드를 푸시하면 Github Actions를 통한 CI가 이루어지고 우리가 대여한 AWS EC2 인스턴스에 최신 내용을 반영하는 식으로 이루어진다.
  • Git pull을 활용해서 변경된 부분의 프로젝트 코드에 대해서만 업데이트 하기 때문에 CI/CD 속도가 빠르다.
    • 대부분의 CI/CD 방식들은 전체 프로젝트를 통으로 갈아끼우는 방식을 사용한다.
  • CI/CD 툴로 Github Actions만 사용하기 때문에 인프라 구조가 그리 복잡하지 않다.

👍장점

  • git pull을 활용해서 변경된 부분의 프로젝트 코드에 대해서만 업데이트를 하기 때문에 CI/CD 속도가 빠르다.
  • 대부분의 CI/CD 방식들은 전체를 통으로 바꾸는 방식이기에 타 방식에 비해서 월등히 빠르다.
  • CI/CD 툴로 Github Actions만 사용하기 때문에 인프라 구조가 복잡하지 않고 간단하다.

👎단점

  • 빌드 작업을 EC2에서 직접 진행하기 때문에 운영하고 있는 서버 성능에 영향을 미칠 수 있다.
  • Github 계정 정보가 EC2에 저장되기 때문에 둘 이상의 팀원이 협업을 하는 경우 노출에 민감한 정보들을 볼 수 있어 신뢰성이 보장된 사람들하고만 사용해야 한다.

❗중간 정리 - Github Token

  • 리포지토리에 코드를 올릴 때마다 바뀐 Github 정책에 의해 토큰 값을 넣어줘야 했는데 이 부분을 해결하기 위해 아래와 같은 명령어를 사용했다.
git config --global credential.helper store

❗중간 정리 - AWS 보안 그룹

  • 내가 설정한 보안 그룹 인바운드 규칙은 아래와 같다.
  1. SSH로 원격 접속할 수 있도록 22번 포트 설정(TCP 프로토콜)
  2. HTTPS(Http + Security) 443번 포트 설정(TCP 프로토콜)
  3. HTTP 80번 포트 설정(TCP 프로토콜)
  4. Spring Boot 8080번 포트 설정(TCP 프로토콜)

❗CI를 위해 작성한 Github Actions .yml 파일 정리

name: Github Actions & AWS EC2를 사용하여 CI/CD 직접 구축하는 실습

on:
  push:
    branches:
      - main

jobs:
  Deploy:
    runs-on: ubuntu-latest

    # EC2_HOST : Public IPs
    # EC2_USERNAME : ubuntu
    # EC2_PRIVATE_KEY : 키 페어

    # EC2 인스턴스에 접속해서 개발자가 직접 수행해야했던 내용들을 이 steps에 기록
    # 경로 이동 - cd /home/ubuntu/GithubActions_EC2_PipeLine/
    # 코드 최신화 - git pull origin main
    # 코드 실행 권한 변경 - chmod +x ./gradlew build
    # 빌드 파일 만들기 - ./gradlew clean build
    # 스프링 부트 8080 서버 돌아가는 경우 끄기 - sudo fuser -k -n tcp 8080 || true
    # 경로 이동 - cd build/libs
    # 백그라운드로 실행 & 로그 기록을 리눅스 표준 출력으로 기록 - nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &
    steps:
      - name: SSH(원격 접속)로 EC2에 접속하기
      	# 👎단점으로 지적됐던 부분 : 외부 라이브러리를 통해 EC2에 접속한 상태에서 빌드를 수행
        # 👎빌드는 무거운 과정으로 서버 성능에 영향을 미칠 수 있음
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_PRIVATE_KEY }}
          script_stop: true
          script: |
            cd /home/ubuntu/GithubActions_EC2_PipeLine
            git pull origin main
            chmod +x ./gradlew build
            ./gradlew clean build
            sudo fuser -k -n tcp 8080 || true
            nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &

❓키 페어를 읽는 방법

  1. 키 페어가 있는 곳에서 터미널을 연다.
  2. 리눅스에서 파일을 출력하는 명령어인 cat으로 키 페어 내용을 출력하면 예시로 아래와 같이 나오게 된다.
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAiscjIJtOzxFmnNZtdVdKTqsx0uCITMFi2FWhuQpCNgMdYi2Y
YiYOq13S+hFPpYlcG4Z3mrqI6CHLk1K0QsiWJb9RFYrAXpeJDUtNmhNk7ZxOpd70
r9ZRryH0KqUPnhL/9mLZo+Pf+LC3XULS2E00ABckeLvawF+zM4+GKCISMTW4J0LT
1EOVAH6JRb3iOWGg7yPy21vDT7RosxhZ0KtzsCZgvimdh4thSDKBX+DjqampVQWS
7TeVoGmptxYh7EspjSLIa4IoUfAPJW6f0oBlTMPJs3O03FtR/BeOTIBEepy1VHwk
B6Jij8wWob35WerZ1ZjIpc4n8SncxjfSogzyhQIDAQABAoIBABEm86yABYmKOQiB
aB3sn/6BIjNSFQaHkFP0oXxhTDWoxOTxhbf7xCxh+EV4BkQLahrsz7OMAofORX77
5dOrPwODVd43u/b0+7ds6zZz1zGW9BGEMPHap1Xh+G+c3wVGi+RD62paK8Bs9vzL
2YtqX1bzhUp2zV6hdWCWCJrFO0Jhlp2u26v7Lpj2HHM4DbmFd8bqPVQCy6JWiix+
H86tZA40NkL0NgAFL27pxbqF9reeToNPh8x9JC/qvj/NjRt64goNOj8nKX9irkAy
7RKmjtFXeywEu3dzgbDaKmOO0LlbdjX/f39AD7mNRAlWaNRO+VDF8Y0erVSnd/6+
icgb7bECgYEAysLrZHGco+9Veu52PHCRo4I9g5WWn5fYGonxyIeTC2acmFg4GRzz
7sSkd456FsgPDk+IPwSLLoJFmLPTpX2oyqdblyNJpct1BMdXGf4cZHVHJoAlzHqS
GyOruvnEfPsLFXemxkNkrkErBx9nMHQogdRJqA1KSYdXPGfBIRAo398CgYEArzdq
e041VdGs3gGtgxh7gCGd3K5Qt9ipNy7UgvmKGUmn+3+HS2TNUcSfdshPHuCvxtaF
89RKR5sT0PbAHlfhBuFAClUyjC3a0KEOohkMWRX98txUn8+tXaUZbH1MhWAVns4d
YNcXbnjyzdCkVoc0EfoACqDaAnbRmDVMEtRVahsCgYEAw+iVvBUx/guPkhm50CgL
7+o1OWBdipISUYIbRWAJKajZgTEr8sfQwVDqgEH/oOdn9LHPuOPQ/v0L9cE6q9nA
Lx6JFn0X+cOdqyJX/FtUX5QZTQ/gdbOwW9yZXy1ZNlDxoqpbT5FqRBvfUSB8eYqi
YN8W0/MTZfwIw+qT5jhQ5g0CgYAXvbp/2qj/Z9m0eyW3jamuQt/Q9w2Y25KSF5ZT
6Nv9cS2BtlXusUngunOg9KND2831czvTPgCSk0CsH8MIWX/0HrE+tSyUMeJkQm5p
KFuz9nbiYVhWDx2+gpBfUtr7d3l2excf+AUEwv6jRJH/53H2vZkj14eyrcbYiOA1
7O9l4QKBgQDFkCnWFAJGhKcOFK65ytdvRHobjEDHrSLUz4VTl3T9Hs0jIX1OJmxY
/aRVh03m/6sYrF06FhZMv1I5E8m8Wv3BuC1JFyptVmn3uBF96MDCdJNq/aKuKid1
xqM3wsog6zuB9PuN5me+NGQXcWLY3dsjpBATfYDEqc8hYY6rrshROg==
-----END RSA PRIVATE KEY-----
  1. 위의 파일을 복사해서 Github Secrets에 복사해서 넣는다.

❗스프링 부트에서 설정 파일로 사용하는 applicaiton.yml을 CI/CD로 관리해보기 + 테스트 코드 실행 결과가 FAILED로 나올 때 배포가 자동으로 되지 않도록 하기

  • application.yml과 같은 노출에 민감한 설정 파일의 경우 .gitignore에 아래와 같이 추가하여 git에 푸시되지 않도록 한다.
src/main/resources/application.yml
  • application.yml 작성 내용을 Github Secrets에 등록한다. 그리고 앞서 작성했던 deploy.yml에 이 application.yml 관련 설정을 자동으로 수행해주는 코드를 추가해야 한다.
aws:
  access-key: RANDOM_ACCESS_KEY
  secret-key: RANDOM_SECRET_KEY

# 데이터베이스에 대한 설정 사항이 변경되었다고 가정
db:
  root: root
  password: 1234
name: Github Actions & AWS EC2를 사용하여 CI/CD 직접 구축하는 실습

on:
  push:
    branches:
      - main

jobs:
  Deploy:
    runs-on: ubuntu-latest

    # EC2_HOST : Public IPs
    # EC2_USERNAME : ubuntu
    # EC2_PRIVATE_KEY : 키 페어

    # EC2 인스턴스에 접속해서 개발자가 직접 수행해야했던 내용들을 이 steps에 기록
    # 경로 이동 - cd /home/ubuntu/GithubActions_EC2_PipeLine/
    # 코드 최신화 - git pull origin main
    # 코드 실행 권한 변경 - chmod +x ./gradlew build
    # 빌드 파일 만들기 - ./gradlew clean build
    # 스프링 부트 8080 서버 돌아가는 경우 끄기 - sudo fuser -k -n tcp 8080 || true
    # 경로 이동 - cd build/libs
    # 백그라운드로 실행 & 로그 기록을 리눅스 표준 출력으로 기록 - nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &

    # 추가 : application.yml을 CI/CD로 관리
    steps:
      - name: SSH(원격 접속)로 EC2에 접속하기
        uses: appleboy/ssh-action@v1.0.3
        # 환경 변수 선언
        env:
          APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_PRIVATE_KEY }}
          envs: APPLICATION_PROPERTIES
          script_stop: true
          script: |
            cd /home/ubuntu/GithubActions_EC2_PipeLine
            rm -rf src/main/resources/application.yml	// 있다면 삭제
            git pull origin main
            echo "$APPLICATION_PROPERTIES" > src/main/resources/application.yml		// 리눅스 표준 출력으로 src/main/resources/application.yml에 변경 내용이 반영되도록 설정		
            chmod +x ./gradlew build
            ./gradlew clean build
            sudo fuser -k -n tcp 8080 || true
            nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &

0개의 댓글