반응형

먼저 AWS Cloud 환경에서 필요한 선행 작업을 안내하고, Github Actions와 AWS CodeDeploy에서 사용할 스크립트에 대해 설명하겠다.

👉 AWS 사전 구성하기

1. IAM 사용자 생성

  • 디플로이용 계정을 만들어 아래 정책을 연결
    • AmazonS3FullAccess
    • AWSCodeDeployFullAccess
    • 이 사용자는 Github Actions에서 S3, CodeDeploy에 접근하기 위해 사용하는 IAM 계정이다.
    • 액세스키와 시크릿키를 잘 저장해두자. Github Secret에 저장할거다.
    • 참고 : 아래 EC2, CodeDeploy에서 생성하는 IAM 서비스역할과 사용자는 다르다.
  • Github Secret에 등록
    • DEV_AWS_ACCESS_KEY_DEPLOY : 액세스키 등록
    • DEV_AWS_SECRET_KEY_DEPLOY : 시크릿키 등록

2. EC2

  • EC2 생성
  • EC2에서 사용할 서비스 역할 생성
    • AmazonEC2RoleforAWSCodeDeploy 정책 부여
    • EC2의 IAM 역할에 생성한 서비스역할을 연결
  • EC2 내 Java와 CodeDeploy 클라이언트 설치
    • 코드디플로이 생성 시 에이전트 설치/업데이트 옵션이 있기 때문에 CodeDeploy 클라이언트 설치는 옵셔널로 보임 (본 포스팅를 작성하면서 EC2에 미리 설치해둠)
    • 참고 : AWS 오토스케일링을 위해 서버 의존성을 자동화할 필요가 있으나, 이 포스팅에서는 안내하지 않음

3. S3

  • 버킷 생성 : 빌드된 파일을 업로드할 버킷이 필요함

4. CodeDeploy

  • CodeDeploy 어플리케이션 생성
  • CodeDeploy 서비스역할 생성
    • AWSCodeDeployRole 정책 부여
  • 배포그룹 생성
    • 생성해둔 EC2 연결
    • 로드밸런서 활성화 옵션은 off
    • 참고 : 이번 포스팅에서 무중단 배포 설정은 안내하지 않음

👉 CodeDeploy 스크립트 작성

프로젝트 최상단에 appspec.yml를 생성한다. CodeDeploy가 제일 먼저 호출할 설정파일이다. 루트에 있는 deploy.sh 라는 파일을 수행하게 해두었다.

version: 0.0
os: linux

files:
  - source: /
    destination: /home/ubuntu
permissions:
  - object: /
    pattern: "**"
    owner: ubuntu
    group: ubuntu
    mode: 755
hooks:
  AfterInstall:
    - location: deploy.sh
      timeout: 60
      runas: root

deploy.sh 파일을 생성한다. 위치와 명칭은 자유롭게 바꿔도 되는데, Github Actions 스크립트에도 동일하게 반영해주어야 한다. 본 포스팅에서는 script/deploy.sh 로 명명함.

해당 스크립트는 기존에 실행중이던 jar 프로세스를 종료하고, 새로운 jar를 실행시키는 작업을 수행한다.

#!/usr/bin/env bash

REPOSITORY=/home/ubuntu

cd $REPOSITORY

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

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 &

👉 Github Actions 스크립트 작성

프로젝트 최상단에 .github/workflows 폴더를 만들고 deploy-dev.yml 를 생성한다.
dev 브랜치에 push 혹은 pull request가 발생했을 때 Github Actions이 수행되도록 하였다.
한글로 작성해둔 부분은 프로젝트 명칭에 알맞게 수정하도록 하자.
(참고로 deploy.sh 는 script 내에 있지만, 압축을 해제하고 나면 최상위 디렉토리에 위치하게 된다)

name: Deploy dev

on:
  push:
    branches: [ dev ]

jobs:

  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 11
        uses: actions/setup-java@v2
        with:
          java-version: '11'
          distribution: 'adopt'
          cache: maven
      # Caching dependencies
      - name: Cache Maven packages
        uses: actions/cache@v2
        with:
          path: ~/.m2
          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
          restore-keys: ${{ runner.os }}-m2
      # Build
      - name: Build with Maven
        run: mvn -Dmaven.test.skip=true -B package --file pom.xml
      # 전송할 파일을 담을 디렉토리 생성
      - name: Make Directory for deliver
        run: mkdir deploy && cp target/*.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 어플리케이션명 --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name 배포그룹명 --s3-location bucket=S3버킷명,bundleType=zip,key=폴더위치/압축파일.zip

dev 브랜치에 push 이벤트가 발생하면 위 스크립트에서 정의해놓은 Github Actions 가 트리거 된다. 아래처럼 수행되는 것을 확인할 수 있다.

Github Actions 수행된 모습


👉 오류 케이스

  • CodeDeploy 배포 이벤트가 blockTraffic에서 멈췄다면?

로드밸런서 활성화 옵션을 확인하라. 이 옵션은 배포대상 인스턴스에 연결된 로드밸런서가 받는 트래픽을 차단하고, 인스턴스 배포 성공 이후 로드밸런서에 다시 인스턴스를 붙여서 트래픽을 허용하는 작업이다. 별도의 설정없이 사용하면 트래픽 차단하는 부분에서 무한로딩되는 현상이 있다. 본 포스팅에서는 이 옵션을 비활성화해두었다.

  • 정상 배포가 안되었다면? 코드디플로이 확인하기 (설정문제)

AWS CodeDeploy에 직접 들어가서 배포 단계를 확인해보자. 특정 배포 단계에서 멈추었거나 오류가 난 것을 확인할 수 있다.

  • 정상 배포가 안되었다면? EC2내 로그 확인하기 (권한문제)

코드디플로이 작업은 정상적으로 완료되었는데, 배포가 정상적으로 되지 않았다면 EC2 내에 있는 코드 디플로이 로그를 확인해보자.
로그 위치는 /var/log/aws/codedeploy-agent 이다.
나같은 경우 EC2에 권한이 없어 아래와 같은 오류가 발생했다.

2021-10-08 12:20:11 INFO  [codedeploy-agent(1368)]: Version file found in /opt/codedeploy-agent/.version with agent version OFFICIAL_1.3.2-1902_deb.
2021-10-08 12:20:11 ERROR [codedeploy-agent(1368)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Missing credentials - please check if this instance was started with an IAM instance profile

참고하면 좋은 글

반응형