[AWS CI/CD]ubuntu22.04환경에서 CI/CD 구축하기(Nginx, GitAction, CodeDeploy)
서버개발

[AWS CI/CD]ubuntu22.04환경에서 CI/CD 구축하기(Nginx, GitAction, CodeDeploy)

 

약간 다르지만 위와 비슷한 형태로 구현했다

로컬 프로젝트 기본 세팅

# 프로젝트 최상단에 .github/workflows/gradle.yml 생성

- GitAction에 사용 될 코드로 추가해야한다. gradle 세팅이며, maven 코드는 다른 곳에서 새로 찾아야한다.

한글로 적힌 부분은 각 적합한 곳에서 추출해서 큰 따옴표를 지우고 치환하여야한다.

- secrets.DEV_AWS_ACCESS_KEY_DEPLOY와 같은 secret.에 들어가있는 것은

github repository > Settings > Secrets에 추가하면 된다.

깃허브에서 깃액션으로 추가해도 되지만 깃랩을 사용해서 로컬에서 추가했다.

# 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://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle

name: Java CI with Gradle

on:
  push:
    branches: [ "Branch명" ]
  pull_request:
    branches: [ "Branch명" ]

permissions:
  contents: read

jobs:
  build:
    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: Build with Gradle
        uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
        with:
          arguments: build
      # 전송할 파일을 담을 디렉토리 생성
      - name: Make Directory for deliver
        run: mkdir deploy && cp build/libs/*.jar deploy/ && cp appspec.yml deploy/ && cp script/deploy.sh deploy/
      # 압축
      - name: Make zip file
        run: zip -r -qq -j "압축파일명".zip deploy
      # AWS 인증
      - name: AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_DEPLOY }}
          aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_KEY_DEPLOY }}
          aws-region: ap-northeast-2
      # S3에 빌드된 파일 업로드
      - name: Upload to AWS S3
        run: aws s3 cp --region ap-northeast-2 "압축파일명".zip s3://"S3 버켓명"/"압축파일명".zip
      # Deploy
      - name: Code Deploy
        run: aws deploy create-deployment --application-name "AWS CodeDeploy Application명" 
        --deployment-config-name CodeDeployDefault.AllAtOnce --file-exists-behavior OVERWRITE 
        --deployment-group-name "AWS 배포그룹명" --s3-location bucket="S3 버켓명",
        bundleType=zip,key="압축파일명".zip

 

# 최상단에 script/deploy.sh 생성

- EC2까지 접속하게 된다면 그 곳에서 이루어질 작업을 sh파일로 만든 것이다.

jar파일이 생길 위치를 입력하고, SNAPSHOT.jar를 잡아서 실행할 예정이다.

pgrep -f jar를 이용해 이미 실행중인 jar파일의 pid를 받아와서 존재할 경우 kill 시킨다.

그리고 이전에 실행했던 대로 nohup으로 jar를 실행시킨다.

spring 프로젝트의 profile에 따라서 마지막 줄을 변경해주어야 한다.

#!/usr/bin/env bash

REPOSITORY=/home/ubuntu/"실행될 jar가 있을 폴더"

cd $REPOSITORY

JAR_NAME=$(ls $REPOSITORY/ | grep 'SNAPSHOT.jar' | tail -n 1)
echo "$JAR_NAME"
JAR_PATH=$REPOSITORY/$JAR_NAME
echo "$JAR_PATH"

CURRENT_PID=$(pgrep -f jar)

if [ -z $CURRENT_PID ]
then
  echo "> Nothing to end."
else
  echo "> kill -9 $CURRENT_PID"
  kill -15 $CURRENT_PID
  sleep 5
fi

echo "> $JAR_PATH deploy"
nohup java -jar $JAR_PATH --spring.profiles.active=dev > /dev/null 2> /dev/null < /dev/null &

 

# 최상단에 appspec.yml

- 세팅 파일 중 하나이다.

version: 0.0
os: linux

files:
  - source: /
    destination: /home/ubuntu/"jar파일이 있을 폴더"
permissions:
  - object: /
    pattern: "**"
    owner: ubuntu
    group: ubuntu
    mode: 755
hooks:
  AfterInstall:
    - location: deploy.sh
      timeout: 60
      runas: root

 

생길 수 있는 오류들

- refusing to allow a Personal Access Token to create or update workflow error

깃랩을 사용할 경우 github에서 미러링을 위해 발급한 토큰이 repository만 허용하기 때문에 깃 액션을 취할때 workflow를 사용하여 미러링이 깨지는 오류. 깃허브 토큰에 workflows를 허용해주면 해결된다.

 

- gradle-wrapper.jar를 찾지 못하여 깃 액션에서 빌드하지 못하는 오류

gitignore에 yml, jar등을 업로드하지 않도록 설정했더니 생겼던 오류이다. gitignore에서 제외해주도록 하자.

 

- 환경변수 등 오류

yml파일을 제외했더니 기존 빌드 방식은 jar파일을 올렸던 반면, 이 방법은 깃 허브 코드 바탕으로 jar파일을 생성하므로 환경변수 등이 들어있는 yml을 프로젝트에 포함하여야 한다.

AWS IAM USER 및 ROLE 생성

# 배포를 위한 IAM User 생성(deploy)

- 후에 사용될 gradle.yml에서 AWS에 접근해 배포에 해당되는 기능들을 사용할 수 있도록 IAM 계정을 생성해준다

AWS > IAM > USERS > ADD USERS

에서 Access key - Programmatic access로 제작하고 아래의 권한들을 추가한다.

후에 나오는 access key와 secret key는 반드시 메모해두어야한다.

IAM user

# EC2 codedeploy 이용을 위한 역할 생성(ec2-deploy-role)

- EC2에서 사용될 IAM으로 EC2에서 codedeploy를 이용 가능하게끔 하려는 역할을 생성한다

IAM role

# 배포그룹을 위한 역할 생성(deploy-grp-role)

- deploy group을 생성할 때 사용됩니다. 생성 시 EC2 대신 하단에서 CodeDeploy 검색 후 생성합니다.

 

AWS EC2 설정

# CodeDeploy설치 & JAVA 설치

22.04에서는 Ruby3.X버전이 깔리는데 2.X버전으로 깔지 않으면 제대로 실행되지 않는다

구글링하여 해결해야 한다

sudo apt-get install ruby-full ruby-webrick wget -y

cd /tmp

wget https://aws-codedeploy-us-east-1.s3.us-east-1.amazonaws.com/releases/codedeploy-agent_1.3.2-1902_all.deb

mkdir codedeploy-agent_1.3.2-1902_ubuntu22

dpkg-deb -R codedeploy-agent_1.3.2-1902_all.deb codedeploy-agent_1.3.2-1902_ubuntu22

sed 's/Depends:.*/Depends:ruby3.0/' -i ./codedeploy-agent_1.3.2-1902_ubuntu22/DEBIAN/control

dpkg-deb -b codedeploy-agent_1.3.2-1902_ubuntu22/

sudo dpkg -i codedeploy-agent_1.3.2-1902_ubuntu22.deb

sudo systemctl list-units --type=service | grep codedeploy

sudo service codedeploy-agent status

 

-  다음 글을 참고하자.

 

How to Install Ruby 2.7 & Rails 6 on Ubuntu 20.04 | Techiediaries

How to Install Ruby 2.7 & Rails 6 on Ubuntu 20.04 In this tutorial, we'll see how we can install the latest version of Ruby v2. 7on Ubuntu 20.04 Disco Dingo. and next we'll see how to set up a development environment for Ruby on Rails 6. As of this writing

www.techiediaries.com

 

# IAM role 지정

EC2의 Actions > Security > Modify IAM role로 위에서 제작한 CodeDeploy를 포함한 role로 지정해주고 EC2를 재부팅하면 된다.

 

AWS S3 설정

# S3 생성

- bucket은 소문자만 가능하며, 다른 버킷과 중복된 이름을 가질 수 없다.

- Block all public aceess를 체크하고 생성하면 된다. 위의 설정파일을 제작할 때 사용되므로 이름들을 잘 기억해야한다.

생성된 zip파일을 보관하고 ec2에 배포하는데 사용된다.

 

AWS CodeDeploy & DeployGroup 설정

# CodeDeploy Application 생성

- Application명 및 Compute platform은 EC2로 지정 후 생성한다

Deployment groups로 위에서 생성한 배포그룹을 지정한다.

 

# Deployment groups 생성

- Deploy Application을 생성하면서 생성할 수 있다.

이름과 service role에 위에서 제작한 codeDeployRole을 가진 Service role을 넣어준다.

Environment configuration에서 EC2 instances를 고른 후 Enable load balancing을 check 해제 후 생성한다.

 

결과확인

# 자주 사용되는 명령어

// codedeploy 로그확인, CodeDeploy에서 오류가 날 시 이곳을 확인하면 된다
cat /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log

// 실행중인 jar파일 pid 가져오기
pgrep -f jar

// 실행중인 파일 실행시간 조회
ps -eo pid,etime,cmd | grep 프로세스명 | grep -v grep

# develop branch에서 push/PR 시 CI/CD 성공!

- push를 할 경우 자동으로 GitAction에서 test를 해주고, 지정해준 build를 수행한 후 AWS에 접근해 S3에 build한 파일을 압축해서 보낸다. S3에서 CodeDeploy Application이 EC2로 보내 지정된 폴더에서 이미 실행중인 프로세스를 종료시키고, 새로운 jar파일을 백그라운드에서 실행함으로 써 배포까지 완료하였다.

커밋만 push해도 build에서 test를 자동으로 해줍니다
GitAction & CodeDeploy

 

참고할만한 블로그

 

Github Actions + CodeDeploy + Nginx 로 무중단 배포하기 (2)

CodeDeploy 소개 전 시간에 이어 다음으로는 Github Actions 에서 CodeDeploy 에게 S3에 있는 jar 파일을 가져가서 담당한 배포 그룹의 EC2에 배포해 줘! 라는 명령을 내릴 수 있도록 구성해 보겠습니다. 먼저

wbluke.tistory.com

 

 

CodeDeploy 에이전트가 실행 중인지 확인 - AWS CodeDeploy

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

 

deploy.sh _트러블슈팅

deploy.sh 작성 → 리눅스 쉘 스크립트 작성 : CI/CD는 개발자가 하는 작업을 다양한 프로그램들을 활용하여 자동으로 통합배포하는 것이다. 따라서 자동배포에 사용하는 프로그램들이 어떤 과정으

velog.io

 

 

[Devops] Github Action을 사용한 Spring boot & gradle CI/CD 구축 - 3

github action, AWS S3, AWS CodeDeploy, AWS EC2를 사용하여 CI/CD 환경을 구성해봅시다

stalker5217.github.io

 

 

Spring Boot 배포 자동화(CI/CD) : Github Actions와 AWS CodeDeploy

먼저 AWS Cloud 환경에서 필요한 선행 작업을 안내하고, Github Actions와 AWS CodeDeploy에서 사용할 스크립트에 대해 설명하겠다. 👉 AWS 사전 구성하기 1. IAM 사용자 생성 디플로이용 계정을 만들어 아래

prohannah.tistory.com

 

 

#스프링 CI/CD #스프링 자동배포 #AWS 자동배포 #ubuntu ci cd #ubuntu codedeploy #ubuntu ruby오류 #ubuntu22.04 cicd

#스프링 깃액션 #스프링 깃랩 CICD