8.9.가. AWS CodeDeploy를 이용한 EC2 인스턴스 배포 구성 및 실행 방법
1. 개요
AWS CodeDeploy는 EC2 인스턴스, 온프레미스 서버, Lambda 및 ECS 등의 환경에서 애플리케이션을 자동으로 배포할 수 있는 서비스입니다. 이 글에서는 CodeDeploy를 활용하여 EC2 인스턴스에 애플리케이션을 배포하는 방법을 단계별로 설명합니다.
2. 환경 설정
1) AWS 서비스 준비
배포를 실행하기 위해 다음과 같은 AWS 서비스를 사용합니다.
- Amazon EC2: 애플리케이션을 배포할 대상 서버
- Amazon S3: 배포 패키지를 저장할 저장소
- AWS CodeDeploy: 배포 자동화 서비스
- IAM 역할 및 정책: CodeDeploy 및 EC2가 상호 작용할 수 있도록 설정
2) IAM 역할 생성
(1) EC2용 IAM 역할 설정
- AWS 콘솔 → IAM → 역할(Role) 생성
- EC2를 선택한 후 "다음" 클릭
- 다음 정책을 추가
- AmazonEC2RoleforAWSCodeDeploy
- AmazonS3ReadOnlyAccess
- 역할 이름: EC2CodeDeployRole 설정 후 생성
- EC2 인스턴스에 IAM 역할 할당
(2) CodeDeploy용 IAM 역할 설정
- AWS 콘솔 → IAM → 역할(Role) 생성
- CodeDeploy를 선택한 후 "다음" 클릭
- 다음 정책을 추가
- AWSCodeDeployRole
- 역할 이름: CodeDeployServiceRole 설정 후 생성
3. EC2 인스턴스 설정
1) EC2 인스턴스 생성 및 환경 설정
- AWS 콘솔 → EC2 → 인스턴스 실행
- ubuntu LINUX 선택
- IAM 역할: EC2CodeDeployRole 할당
- 보안 그룹: SSH(22) 및 HTTP(80) 허용
- 인스턴스 실행 후 SSH로 접속
ssh -i my-key.pem ubuntu@<EC2_PUBLIC_IP>
2) CodeDeploy 에이전트 설치
sudo apt update -y
sudo apt install ruby -y
sudo apt install wget -y
cd /home/ubuntu
wget https://aws-codedeploy-us-east-1.s3.us-east-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent start
sudo systemctl enable codedeploy-agent
설치 확인:
sudo service codedeploy-agent status
4. 배포 패키지 준비
AWS에 CodeDeploy 만 사용하고 개발 및 형상관리를 직접하는 환경으로 배포 패키지 준비는 모두 Local PC환경에서 진행합니다.
아래 과정은 jar 파일과 함께 zip파일 묶어서 배포할 appspec.yml 파일과 배포 스크립트를 작성하는 과정 입니다. 해당 파일들은 CodeDeploy 에이전트가 jar 파일을 EC2 인스턴스에 배포하기위해 필요한 정보와 쉘 스크립트라고 보시면 됩니다.
1) 프로젝트 구조 생성
mkdir package
cd package
mkdir scripts
2) appspec.yml 파일 작성
version: 0.0
os: linux
files:
- source: my-app-latest.jar
destination: /home/ubuntu/app
- source: scripts/
destination: /home/ubuntu/scripts/
hooks:
ApplicationStop:
- location: scripts/stop_server.sh
timeout: 60
runas: root
BeforeInstall:
- location: scripts/before_install.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/after_install.sh
timeout: 300
runas: root
ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
runas: root
ValidateService:
- location: scripts/validate_service.sh
timeout: 120
runas: root
3) 배포 스크립트 작성
■ scripts/stop_server.sh
#!/usr/bin/bash
echo "Stopping application..."
sudo pkill -f 'java -jar'
■ scripts/before_install.sh
#!/usr/bin/bash
echo "Installing dependencies..."
java --version
if [ $? -eq 127 ]; then
echo "Java를 설치 합니다...."
sudo apt update
sudo apt install openjdk-21-jdk
else
echo "Java가 설치되어 있습니다."
fi
■ scripts/after_install.sh
#!/usr/bin/bash
echo "Deploying new application..."
sudo cp /home/ubuntu/app/my-app-v1.2.jar /home/ubuntu/app/my-app-latest.jar
(참고) 배포된 v1.2.jar파일을 latest.jar로 복사하여 최신 배포 버전을 명확하게 유지 합니다.
- 배포가 완료되면 최신 버전의 .jar 파일을 항상 my-app-latest.jar로 유지하면, 실행 스크립트에서 특정 버전명이 아니라 고정된 파일명(latest.jar)을 사용할 수 있습니다.
- 즉, 애플리케이션 실행 스크립트에서 특정 버전의 .jar를 찾을 필요 없이 항상 최신 버전(my-app-latest.jar)만 실행하도록 설정할 수 있습니다.
■ scripts/start_server.sh
#!/usr/bin/bash
echo "Starting application..."
sudo nohup java -jar /home/ubuntu/app/my-app-latest.jar \
--spring.config.location=/home/ubuntu/app/app.properties \
> /home/ubuntu/app/springboot.log 2>&1 &
(참고) "2>&1"은 stderr 파일 디스크립트로 출력되는 내용을 stdout 파일 디스크립트로 출력 함께 출력하게 합니다. 즉, 오류 발생시 출력되는 log 내용도 stdout으로 출력되게 함으로써 springboot.log 파일에 모든 로그가 출력되도록해줍니다.
■ scripts/validate_service.sh
#!/usr/bin/bash
echo "Checking application status..."
sleep 10 # Application이 정상 기동된 후 Health check하기 위해 대기
curl -f http://localhost/api/data/0 || exit 1
■ 쉘 스크립트를 모두 작성했으면 실행 권한을 부여 합니다.
chmod +x scripts/*.sh
4) 배포 패키지 압축 및 S3 업로드
지금까지 작성한 appspec.yml과 쉘 스크립트 파일, jar 파일을 하나의 배포 패키지 zip 파일로 묶어 S3에 업로드 합니다.
zip -r my-app.zip appspec.yml scripts/ my-app-v1.2.jar
aws s3 cp my-app.zip s3://my-deploy-bucket/
(참고) AWS CLI를 사용하여 특정 리전에 S3 버킷을 만드는 방법
aws s3api create-bucket --bucket <버킷이름> --region <리전> --create-bucket-configuration LocationConstraint=<리전>
📌 예제: 서울 리전(ap-northeast-2)에 버킷 생성 (버킷이름: my-deploy-bucket, 리전: ap-northeast-2)
aws s3api create-bucket --bucket my-deploy-bucket --region ap-northeast-2 --create-bucket-configuration LocationConstraint=ap-northeast-2
5. AWS CodeDeploy 설정 및 배포 실행
1) CodeDeploy 애플리케이션 및 배포 그룹 생성
aws deploy create-application --application-name MySpringBootApp
aws deploy create-deployment-group \
--application-name MySpringBootApp \
--deployment-group-name MyDeploymentGroup \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--ec2-tag-filters Key=Name,Value=MyEC2Instance,Type=KEY_AND_VALUE \
--service-role-arn arn:aws:iam::123456789012:role/CodeDeployServiceRole
2) CodeDeploy 배포 실행
aws deploy create-deployment \
--application-name MySpringBootApp \
--deployment-group-name MyDeploymentGroup \
--s3-location bucket=my-deploy-bucket,key=my-app.zip,bundleType=zip
3) 배포 상태 확인
aws deploy get-deployment --deployment-id d-ABCDEFGHIJ1234567
(Hint) 쉘 명령 1개로 CodeDeploy 배포를 실행하고 배포상태를 확인하는 쉘 스크립트 만들기. 아래 쉘 스크립트 내용을 복사해 나에게 필요한 부분을 변경하여 쉘 명령 파일이를 만들어 사용해보세요.
#!/usr/bin/bash
echo ">>> (my-app.zip) CodeDeploy start...."
DEP_ID=$(aws deploy create-deployment \
--application-name MySpringBootApp \
--deployment-group-name MyDeploymentGroup \
--s3-location bucket=copycat-deploy-bucket,key=my-app.zip,bundleType=zip \
--file-exists-behavior OVERWRITE --output text)
watch -n1 aws deploy get-deployment --deployment-id $DEP_ID --output table
6. 배포 완료 후 확인
- EC2 인스턴스에 SSH로 접속
- 애플리케이션 실행 여부 확인:
ps aux | grep java
- 애플리케이션 로그 확인:
tail -f /home/ubuntu/app/springboot.log
7. 마무리
이제 AWS CodeDeploy를 활용하여 EC2 인스턴스에 애플리케이션을 자동 배포하는 환경을 성공적으로 구성했습니다. 이 과정에서는 IAM 역할 설정, EC2 인스턴스 구성, CodeDeploy 에이전트 설치, 배포 패키지 생성 및 업로드, CodeDeploy 배포 실행을 다루었습니다.
이제 CI/CD 파이프라인을 확장하여 CodePipeline과 연동하거나, Auto Scaling 그룹을 활용한 배포 자동화도 고려해볼 수 있습니다.