-
[GIT&AWS] 깃헙액션으로 CI/CD 배포 자동화 하기!Git 2023. 2. 27. 13:47
📖 EC2에 프로젝트 빌드하여 올리는 것까지 완료했다. 이제는 CI/CD 배포 자동화를 해볼 차례!
실제 배포된 인스턴스는 ubuntu이지만 포스팅이 죄다 linux 인스턴스로 되어있어서 일단 연습할 겸 새 인스턴스는 linux 기반으로 생성했다. 연습은 linux대로 하고 실제 적용할 땐 ubuntu 기준으로 살짝만 변경해주면 될 것이다.
1. ec2 인스턴스에서 자동배포를 위해 필요한 codedeploy를 설치해줘야 한다.
# 패키지 매니저 업데이트, ruby 설치 sudo yum update sudo yum install ruby sudo yum install wget # 서울 리전에 있는 CodeDeploy 리소스 키트 파일 다운로드 cd /home/ec2-user wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install # 설치 파일에 실행 권한 부여 chmod +x ./install # 설치 진행 및 Agent 상태 확인 sudo ./install auto sudo service codedeploy-agent status
Agent 상태 확인을 했을 때 위와 같이 나오면다면 성공이다.
2. 깃허브 액션에서 new workflow를 들어간다. 우리는 springboot를 사용했고, 이 프로젝트를 서버에 배포할 것이기 때문에 'Java with Gradle' 으로 선택한다.
3. gradle.yml 파일에 아래 내용으로 넣어준다. 설명은 아래에서 차근차근 살펴보도록 하자.
# This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle name: Java CI with Gradle on: push: branches: [ "develop" ] pull_request: branches: [ "develop" ] permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' # - name: Build with Gradle # uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 # with: # arguments: build - uses : actions/checkout@v3 #1 # 해당 부분은 상당히 중요함 (글에서 부가설명) # application.properties는 외부에 노출되면 안되므로 Actions가 빌드될때마다 해당 Repository의 Secret 설정을 # 이용하여서 설정 파일을 생성해줌 (github에 commit 되는게 아님!) - run : touch ./src/main/resources/application.yml - run : echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml - run : cat ./src/main/resources/application.yml # gradlew에 권한 부여 - name: Grant execute permission for gradlew run: chmod +x gradlew # gradlew 빌드 - name: Build with Gradle run: ./gradlew clean build # 이름은 run 에서 설정 가능 # 빌드를 성공하면 해당 프로젝트를 zip로 만듬 - name: Make zip file run: zip -r ./<자신이 만든 ZIP 파일 이름>.zip . shell: bash #2 # AWS 계정 설정 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: # 깃허브 Secret에 넣어둔 Access key aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} # 깃허브 Secret에 넣어둔 Secret key aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 깃허브 Secret에 넣어둔 Region aws-region: ${{ secrets.AWS_REGION }} #3 # 만들어 놓은 S3에 해당 zip 파일 저장 - name: Upload to S3 run: aws s3 cp --region ${{ secrets.AWS_REGION }} ./<자신이 만든 ZIP 파일 이름>.zip s3://<만들어 놓은 버킷 이름>/<자신이 만든 ZIP 파일 이름>.zip #4 # AWS CodeDeploy에 배포 - name: Deploy env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | aws deploy create-deployment \ --application-name <AWS codeDeploy 애플리케이션 이름> \ --deployment-group-name <codeDeploy group 이름> \ --file-exists-behavior OVERWRITE \ --s3-location bucket=<만들어 놓은 버킷 이름>,bundleType=zip,key=<자신이 만든 ZIP 파일 이름>.zip \ --region ${{ secrets.AWS_REGION }}
#1 application.yml 설정하기
보안상 이유로 application.yml는 github에 올리지 않는다. 그러면 어떻게 CI를 구축할 수 있을까?
[ Repository > Settings > 좌측에 Secrets and variables > Actions ] 탭을 들어간 뒤 'New repository secret' 을 클릭한다. #1 주석의 ${{ secrets.APPLICATION }}는 secrets의 APPLICATION이라는 이름으로 Secret을 작성해주고, 내용은 application.yml의 내용을 붙여넣는다.
이렇게 해주면 CI가 작동될 때마다 secret에서 코드를 가져와 application.yml을 자체적으로 생성 후 빌드해준다. 결과적으로 yml 파일을 github에 올리지 않더라도 CI를 구축할 수 있다.
#2 AWS 계정 설정하기
여기에 있는 ${{ secrets.AWS_ACCESS_KEY_ID }}와 ${{ secrets.AWS_SECRET_ACCESS_KEY }}도 마찬가지로 Secret을 생성해주면 되며, 각각 IAM의 액세스 키와 시크릿 키를 넣어준다. ${{ secrets.AWS_REGION }}은 사용하고 있는 리전 주소를 Secret에 넣어주면 된다. ex) ap-northeast-2
#3 CI를 통해 만든 zip 파일을 S3에 저장하기
gradle.yml에 파일에서 자신이 만들 ZIP 파일 이름을 그대로 넣어주고, 자신이 AWS에서 만들어놓은 S3 버킷 이름을 넣어주면 된다.
#4 AWS CodeDeploy에 배포하기
${{ secrets.AWS_ACCESS_KEY_ID }}와 ${{ secrets.AWS_SECRET_ACCESS_KEY }}는 앞서 넣어둔 액세스키와 시크릿 키가 들어갈 테고, run 부분에서 주석에 맞게끔 값들을 넣어준다.
주의할 점
Gradle.yml이 어떤 브랜치에 있는지에 따라 나뉜다. 작성후 커밋할 때 delvelop 브랜치 쪽으로 머지해주는 과정이 필요하다.
여기까지 완료했으면 이번엔 AWS에서 세팅을 시작해보자.
1. IAM 역할을 생성한다.
[ IAM > 좌측 '역할' > 역할만들기 ] 를 클릭한다.
일반 사용 사례는 EC2를 선택하고 '다음'으로 간다.
위 2개의 정책을 선택하고 넘어간다.
마지막으로 역할 이름을 입력하고 역할 생성을 눌러준다.
2. EC2 인스턴스에 생성한 역할을 연결한다.
3. CodeDeploy 역할을 하나 더 만들어준다. 이번엔 'AWSCodeDeployRole' 정책만 추가한다.
4. CodeDeploy 애플리케이션을 생성해준다.
[ AWS > CodeDeploy > 애플리케이션 > 애플리케이션 생성 ]을 클릭한다.
위와 같이 설정하고 생성을 누른다.
5. 배포 그룹을 생성해준다.
위 값들을 넣어준다.
나머지 설정은 그대로 두고 로드 밸런싱 활성화 체크는 해제한 뒤 '배포 그룹 생성'을 클릭한다.
혹시 위와 같은 에러창이 뜬다면 설정해줄 부분이 있다.
[ IAM > 역할 ]에서 내가 선택한 역할을 들어간 뒤 '신뢰관계' 탭으로 들어간다.
신뢰 정책 편집에 들어가서 위에 박스친 부분처럼 수정해준다.
6. IAM 사용자를 추가한다. 기존에 사용자가 있다면 'AWSCodeDeployFullAccess' 권한을 추가해준다.
이 사용자의 Access Key와 Secret Access Key는 당연하겠지만 잘 보관해두자.
7. Github secret에 환경변수를 추가해준다.
위 화면에선 이미 다 추가한 모습이 있는데, 위와 같이 하나씩 추가해주면 된다.
이번엔 코드로 돌아가서 좀더 세팅을 해보자
1. 프로젝트 내부 최상단에 appspec.yml 파일을 만들어준다.
version: 0.0 os: linux files: - source: / destination: /home/ec2-user/app/deploy hooks: AfterInstall: - location: scripts/stop.sh timeout: 60 runas: ec2-user ApplicationStart: - location: scripts/start.sh timeout: 60 runas: ec2-user
destination의 경우 EC2내부에 저장 될 경로이다. 그리고 hooks를 통해 쉘 스크립트를 실행해줄 것인데 location으로 해당 쉘의 위치를 잡아 주고 실행줄 것이다.
2. 프로젝트 최상단에 scripts 폴더를 만들어 start.sh와 stop.sh를 만들어준다.
start.sh
#!/usr/bin/env bash PROJECT_ROOT="/home/ec2-user/app/deploy" JAR_FILE="$PROJECT_ROOT/build/libs/sparta-0.0.1-SNAPSHOT.jar" APP_LOG="$PROJECT_ROOT/application.log" ERROR_LOG="$PROJECT_ROOT/error.log" DEPLOY_LOG="$PROJECT_ROOT/deploy.log" TIME_NOW=$(date +%c) # build 파일 복사 echo "$TIME_NOW > $JAR_FILE 파일 복사" >> $DEPLOY_LOG cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE # jar 파일 실행 echo "$TIME_NOW > $JAR_FILE 파일 실행" >> $DEPLOY_LOG nohup java -jar $JAR_FILE > $APP_LOG 2> $ERROR_LOG & CURRENT_PID=$(pgrep -f $JAR_FILE) echo "$TIME_NOW > 실행된 프로세스 아이디 $CURRENT_PID 입니다." >> $DEPLOY_LOG
stop.sh
#!/usr/bin/env bash PROJECT_ROOT="/home/ec2-user/app/deploy" JAR_FILE="$PROJECT_ROOT/build/libs/sparta-0.0.1-SNAPSHOT.jar" DEPLOY_LOG="$PROJECT_ROOT/deploy.log" TIME_NOW=$(date +%c) # 현재 구동 중인 애플리케이션 pid 확인 CURRENT_PID=$(pgrep -f $JAR_FILE) # 프로세스가 켜져 있으면 종료 if [ -z $CURRENT_PID ]; then echo "$TIME_NOW > 현재 실행중인 애플리케이션이 없습니다" >> $DEPLOY_LOG else echo "$TIME_NOW > 실행중인 $CURRENT_PID 애플리케이션 종료 " >> $DEPLOY_LOG kill -15 $CURRENT_PID fi
여기까지가 끝이다. 이제 develop 브랜치에서 푸시하여 CI/CD를 작동시켜보자.
[ AWS > CodeDeploy ]로 들어가면 배포그룹에 현재 진행중인 것을 볼 수 있다.
https://zzang9ha.tistory.com/404
GitHub-Actions로 CI/CD 구축하기(AWS, Docker, SpringBoot)
GitHub-Actions로 CI/CD 구축하기(AWS, Docker, SpringBoot) 안녕하세요, 이번 시간에는 GitHub-Actions로 CI/CD를 구축하는 방법에 대해 알아보겠습니다. 해당 포스팅이 CI/CD를 전체적으로 포함하고 있기는 하지만
zzang9ha.tistory.com
Github Actions, AWS CodeDeploy를 활용한 CI/CD - Node.js(2)
📌 Node.js 프로젝트를 Github Actions, AWS CodeDeploy를 활용하여 CI/CD 하는 과정을 다룹니다.
velog.io
[Github Action + AWS CodeDeploy] Spring Boot 서버 자동 배포 및 실행하기
이번 글은 공유하기도 위함이지만 내가 프로젝트를 진행할때마다 잊지않기 위함이 더 크긴하다. 글대로 따라온다면 큰 문제없이 자신의 프로젝트를 Github Action과 AWS CodeDeploy를 통해 자동으로 서
velog.io
Ubuntu Server용 CodeDeploy 에이전트 설치 - AWS CodeDeploy
출력을 임시 로그 파일에 쓰는 것은 Ubuntu 20.04에서 install 스크립트를 사용하여 알려진 버그를 해결하는 동안 사용해야 하는 해결 방법입니다.
docs.aws.amazon.com
Github Action 으로 CI workflow 생성해보기(w/ Spring Boot)
안녕하세요! 제인입니다 :) 최근 진행하고 있는 사이드 프로젝트에서 CI를 어떤 툴로 적용을 해볼건지에 대한 논의가 있었는데요, 기존에 익숙하게 사용하던 Jenkins를 택하지 않고 새롭게 Github Act
jane514.tistory.com
GitHub Actions - 환경변수 등록 방법
github actions환경변수 등록하기 1. 상단 탭의 Settings 로 이동합니다. 2. 좌측 Secrets 항목으로 이동합니다. 3. "Add a New secret" 항목 클릭 4. Name , Value 를 작성합니다. 5. "Add secret" 클릭 6. 등록된 Name 을 복
dnight.tistory.com
https://zzang9ha.tistory.com/404
GitHub-Actions로 CI/CD 구축하기(AWS, Docker, SpringBoot)
GitHub-Actions로 CI/CD 구축하기(AWS, Docker, SpringBoot) 안녕하세요, 이번 시간에는 GitHub-Actions로 CI/CD를 구축하는 방법에 대해 알아보겠습니다. 해당 포스팅이 CI/CD를 전체적으로 포함하고 있기는 하지만
zzang9ha.tistory.com
디버깅
AWS CodeDeploy 그룹 생성, 역할 에러
디버깅
velog.io
'Git' 카테고리의 다른 글
깃허브 이슈만들기 (0) 2022.11.16 깃허브 팀프로젝트 관리 다양한 상황극 (0) 2022.09.18