https://bcp0109.tistory.com/363
태그는 AWS의 자원 관리와 비용 추적에 사용되는 메타데이터로 간주된다. CodeDeploy에서 인스턴스를 특정하여 작업을 진행하기 위한 구분 값으로 사용되기 때문에 중요하다.
인스턴스 생성 시점에서 이미 태그 설정이 완료되었으면, 해당 과정은 생략될 수 있다.
태그 관리 방법
IAM 역할은 AWS 서비스를 위해 특정 권한을 부여하는 방식으로 동작한다. 이를 통해 EC2 인스턴스가 S3에 저장된 파일에 접근하는 권한을 부여한다.
CodeDeploy Agent는 AWS CodeDeploy 서비스와 통신하여 배포 작업을 수행하는 소프트웨어 패키지이다.
$ sudo apt update
$ sudo apt install ruby-full
$ sudo apt install wget
$ cd /home/ubuntu
$ wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto > /tmp/logfile
$ sudo service codedeploy-agent status
AWS S3는 객체 스토리지 서비스로, 큰 양의 데이터를 저장하고 검색하는 데 적합하다.
이미지, zip 파일 등 다양한 데이터를 저장할 수 있다. 빌드된 프로젝트 코드를 압축하여 저장한 후, EC2 인스턴스에서 해당 코드를 불러오기 위해 사용한다.
S3 버킷 생성
작업 순서
버킷 구성 설정
추가 설정
버킷에 대한 추가 설정이 필요할 경우, 다음 사항을 참고한다
버킷 생성 완료
CodeDeploy는 AWS의 배포 서비스로, EC2 인스턴스나 온프레미스 환경 등에서 애플리케이션 배포를 지원한다.
CodeDeploy를 위한 IAM 역할 생성
서비스 선택
AWS 서비스 리스트에서 'CodeDeploy'를 검색하고 기본 설정으로 선택한다.
역할 이름 지정
역할의 이름을 정의한다.
CodeDeploy 애플리케이션 생성
작업 순서
CodeDeploy 배포 그룹 생성
배포 그룹 선택
생성한 애플리케이션 내에서 '배포 그룹 생성'을 클릭한다.
배포 그룹 설정
배포 그룹의 이름, 서비스 역할 등을 설정한다. 이 때, 앞서 생성한 IAM 역할을 선택할 수 있다.
타겟 EC2 인스턴스 설정
배포할 EC2 인스턴스를 선택한다. 태그를 통해 인스턴스를 지정할 수 있으며, 이전 단계에서 태그를 설정한 EC2 인스턴스를 선택한다.
추가 설정 및 완료
AWS Systems Manager의 선택은 별도의 요구사항이 없다면 기본 설정을 사용한다. 로드 밸런서를 사용하지 않는 경우, 해당 옵션의 체크를 해제한다. 모든 설정을 마친 후 '배포 그룹 생성' 버튼을 클릭하여 완료한다.
AWS 리소스에 Github Actions 워크플로우를 통해 접근하려면 적절한 권한을 가진 IAM 사용자가 필요하다.
AWSCodeDeployFullAccess
와 AmazonS3FullAccess
를 추가한다.CodeDeploy 배포를 위한 핵심 파일인 AppSpec 파일을 작성한다.
이 파일은 AWS CodeDeploy가 애플리케이션을 EC2 인스턴스에 배포하는 방법을 지시한다.
# AppSpec 파일의 버전을 정의한다.
version: 0.0
# 배포 대상 운영 체제를 정의한다.
os: linux
# 배포 파일과 대상 디렉터리를 지정한다.
files:
# 원본 파일 또는 디렉터리의 경로를 정의한다.
- source: /
# 대상 인스턴스에서 해당 파일/디렉터리의 위치를 지정한다.
destination: /home/ubuntu/app
# 기존의 파일 또는 디렉터리가 존재하는 경우에 대체 여부를 지정한다.
overwrite: yes
# 배포된 파일 또는 디렉터리의 권한을 설정한다.
permissions:
# 권한 변경 대상 파일 또는 디렉터리를 정의한다.
- object: /
# 권한 적용 대상 패턴을 지정한다.
pattern: "**"
# 파일 또는 디렉터리의 소유자를 정의한다.
owner: ubuntu
# 파일 또는 디렉터리의 그룹을 정의한다.
group: ubuntu
# 배포 프로세스 도중 실행될 스크립트를 정의한다.
hooks:
# AfterInstall 이벤트 시 실행될 스크립트를 지정한다.
AfterInstall:
- location: scripts/stop.sh # 스크립트의 경로를 지정한다.
timeout: 60 # 허용되는 최대 실행 시간을 초로 지정한다.
runas: ubuntu # 스크립트 실행 사용자를 지정한다.
# ApplicationStart 이벤트 시 실행될 스크립트를 지정한다.
ApplicationStart:
- location: scripts/start.sh # 스크립트의 경로를 지정한다.
timeout: 60 # 허용되는 최대 실행 시간을 초로 지정한다.
runas: ubuntu # 스크립트 실행 사용자를 지정한다.
AppSpec Hooks에 명시된 stop.sh 및 start.sh 스크립트를 구현한다.
해당 스크립트는 현재 구동 중인 애플리케이션의 PID를 확인하고, 실행 중인 프로세스가 있다면 종료한다.
#!/usr/bin/env bash
PROJECT_ROOT="/home/ubuntu/app"
JAR_FILE="$PROJECT_ROOT/spring-server.jar"
CURRENT_PID=$(pgrep -f $JAR_FILE)
if [ -n "$CURRENT_PID" ]; then
echo "$(date +%c) > app stop" >> $DEPLOY_LOG
kill -15 $CURRENT_PID
fi
이 스크립트는 애플리케이션을 실행한다. JAR 파일을 복사하고 해당 JAR 파일을 실행한다.
#!/usr/bin/env bash
PROJECT_ROOT="/home/ubuntu/app"
JAR_FILE="$PROJECT_ROOT/spring-server.jar"
cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE
# jar 파일 실행
nohup java -jar $JAR_FILE &
Spring Boot 2.5 버전 이후로 빌드 시 기본 JAR 파일과 함께 -plain.jar 파일도 생성된다.
이를 방지하기 위해 build.gradle 파일에 수정이 필요하다.
build.gradle 파일에 다음을 추가한다.
jar {
enabled = false
}
Github Actions 워크 플로우를 설정한다.
name: Java CI with Gradle
on:
push:
branches: [ "deployTest"]
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: team258-bucket
CODE_DEPLOY_APPLICATION_NAME: team258-codedeploy-app
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: team258-codedeploy-deployment-group
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Check current working directory
run: pwd
- name: List directory contents
run: ls -al
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
# properties 파일 수정
- name: Update properties file
run: |
sed -i "s/spring.datasource.password=.*/spring.datasource.password=${{ secrets.DB_PASSWORD }}/" src/main/resources/application.properties
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
uses: gradle/gradle-build-action@v2.6.0
with:
arguments: build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Upload to AWS S3
run: |
aws deploy push \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--ignore-hidden-files \
--s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \
--source .
- name: Deploy to AWS EC2 from S3
run: |
aws deploy create-deployment \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
--s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip