배포 자동화
- 한번의 클릭 혹은 명령어 입력을 통해 전체 배포 과정을 자동으로 진행하는 것
- 시간절약
- 휴먼 에러(Human Error)를 방지
소스 코드의 관리부터 실제 서비스로의 배포 과정을 연결하는 구조
- 파이프라인의 단계는 상황과 필요에 따라 더 세분화되거나 간소화될 수 있다.
Source 단계
Build 단계
Deploy 단계
$ sudo apt update
$ sudo apt install openjdk-11-jre-headless
//설치 확인
$ java -version
명령줄 셸의 명령을 사용하여 AWS 서비스와 상호 작용할 수 있는 오픈 소스 도구
$ cd ~
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ sudo apt install unzip
$ unzip awscliv2.zip
$ sudo ./aws/install
//설치 확인
$ aws --version
CodeDeploy의 명령을 받는 프로그램
- CodeDeploy로 배포를 진행하려면 EC2에 반드시 CodeDeploy Agent가 설치되어 있어야 한다.
$ cd ~
$ sudo apt update
$ sudo apt install ruby-full # [Y / n] 선택 시 Y 입력
$ sudo apt install wget
$ cd /home/ubuntu
$ sudo wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
$ sudo chmod +x ./install
$ sudo ./install auto > /tmp/logfile
// 서비스 실행 확인
$ sudo service codedeploy-agent status
ec2 인스턴스 접속하면 습관적으로 cd ~
를 입력해 홈 경로에서 시작하자.
ec2 인스턴스에 프로젝트 파일 자체가 자동으로 전달되는 것이 아니다.
Parameter Store에서 변수를 변경하게 된다면 파이프라인 릴리스 해줘야한다.
ec2 인스턴스 재부팅시 주소값 변하는거 확인
.env
파일 수정 후 리빌드해서 S3 다시 올려야 함.위와 같은 변경 후에 문제 해결 전 캐쉬기록이 남아 오류발생할 수 있음.
프로세스 종료방법
// 탐색
$ ps -ef | grep jar
// 삭제
sudo kill [PID]
- Github이 공식적으로 제공하는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼
- 레포지토리에서 Pull Request 나 push 같은 이벤트를 트리거로 GitHub 작업 워크플로(Workflow)를 구성할 수 있다.
설정 파일(.yml
)에 따라 Github Repository의 특정 변동사항을 트리거로 작동된다.
(실습에서는 main 브랜치에 push 하는 경우 작동되도록 했다.)
위와 같이 gradle.yml
파일 자동 생성하니 '~/gradlew' is not executable
오류 발생
아래와 같이 Build with Gradle 이전에 ./gradlew
에 권한을 부여해서 해결했다.
name: Java CI with Gradle
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
permissions:
contents: read
env:
S3_BUCKET_NAME: be-58-wish9
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: Add permission # '~/gradlew' is not executable. 에러 때문에 추가
run: chmod +x gradlew # '~/gradlew' is not executable. 에러 때문에 추가
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: build
aws access 설정 추가 + 빌드파일 S3에 전달
name: Java CI with Gradle
on:
push:
branches: [ "master" ]
pull_request: # 없어도 됨 (누군가가 해당 레파지토리에서 pull하면 자동배포 되는거임)
branches: [ "master" ]
permissions:
contents: read
env:
S3_BUCKET_NAME: be-58-wish9
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: Add permission # '~/gradlew' is not executable. 에러 때문에 추가
run: chmod +x gradlew # '~/gradlew' is not executable. 에러 때문에 추가
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: build
# build한 후 프로젝트를 압축
- name: Make zip file
run: zip -r ./practice-deploy.zip .
shell: bash
# Access Key와 Secret Access Key를 통해 권한을 확인
# Access Key와 Secret Key는 직접 작성 X (깃 설정에서 추가)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
aws-region: ap-northeast-2
# 압축한 프로젝트를 S3로 전송
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./practice-deploy.zip s3://$S3_BUCKET_NAME/practice-deploy.zip
프로젝트 설정에서 access key 등록
인텔리제이에서 수정했던 gradle.yml
파일 push
(자동생성 된 gradle.yml
파일을 pull해서 수정했음)
자동배포 정상작동!
S3 버킷에 압축파일이 전송된 것도 확인
애플리케이션 + 그룹 생성
IAM 권한에 AWSCodeDeployRole
추가되어 있어야 생성 가능
AWSCodeDeployRole
- AWS CodeDeploy 애플리케이션 및 배포 그룹 생성 및 수정 권한
- AWS CodeDeploy 배포 작업을 위한 EC2 인스턴스 및 온프레미스 서버에 대한 액세스 권한
- AWS CodeDeploy 배포 작업에서 Amazon S3 버킷에 대한 읽기 권한
- AWS CodeDeploy 배포 작업에서 Amazon EC2 Systems Manager에 대한 권한
EC2 배포 진행 상황 별 로그를 기록하고 새로 배포된 빌드 파일을 실행하는 shell script 파일(deploy.sh
) 생성
#!/bin/bash
BUILD_JAR=$(ls /home/ubuntu/action/build/libs/practice-githubAction-0.0.1-SNAPSHOT.jar)
JAR_NAME=$(basename $BUILD_JAR)
echo "> 현재 시간: $(date)" >> /home/ubuntu/action/deploy.log
echo "> build 파일명: $JAR_NAME" >> /home/ubuntu/action/deploy.log
echo "> build 파일 복사" >> /home/ubuntu/action/deploy.log
DEPLOY_PATH=/home/ubuntu/action/
cp $BUILD_JAR $DEPLOY_PATH
echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ubuntu/action/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)
if [ -z $CURRENT_PID ]
then
echo "> 현재 구동중인 애플리케이션이 없습니다." >> /home/ubuntu/action/deploy.log
else
echo "> kill -9 $CURRENT_PID" >> /home/ubuntu/action/deploy.log
sudo kill -9 $CURRENT_PID
sleep 5
fi
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> DEPLOY_JAR 배포" >> /home/ubuntu/action/deploy.log
sudo nohup java -jar $DEPLOY_JAR >> /home/ubuntu/deploy.log 2>/home/ubuntu/action/deploy_err.log &
Code Deploy의 작동을 모아놓은 appspec.yml
파일 설정
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/action # 배포 진행되는 디렉토리 주소
overwrite: yes
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: scripts/deploy.sh # 최상위 디렉토리에서 해당 경로에 있는 deploy라는 이름의 쉘 스크립트 실행
timeout: 60
runas: ubuntu
gradle.yml
파일에 Code Deploy 배포 명령 추가
name: Java CI with Gradle
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
permissions:
contents: read
env:
S3_BUCKET_NAME: be-58-wish9
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: Add permission # '~/gradlew' is not executable. 에러 때문에 추가
run: chmod +x gradlew # '~/gradlew' is not executable. 에러 때문에 추가
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: build
# build한 후 프로젝트를 압축
- name: Make zip file
run: zip -r ./practice-deploy.zip .
shell: bash
# Access Key와 Secret Access Key를 통해 권한을 확인
# Access Key와 Secret Key는 직접 작성 X (깃 설정에서 추가)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
aws-region: ap-northeast-2
# 압축한 프로젝트를 S3로 전송
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./practice-deploy.zip s3://$S3_BUCKET_NAME/practice-deploy.zip
-------------------------------------추가된 부분-------------------------------------
# CodeDeploy에게 배포 명령을 내립니다.
- name: Code Deploy
run: >
aws deploy create-deployment --application-name be-58-wish9
--deployment-config-name CodeDeployDefault.AllAtOnce
--deployment-group-name be-58-wish9-group
--s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=practice-deploy.zip
-------------------------------------추가된 부분-------------------------------------
수정, 추가한 파일 깃허브로 push하면 아래와 같이 배포 성공 확인가능
자동 배포 설정해둔 경로
ssm-user@ip-172-31-34-158:/var/snap/amazon-ssm-agent/6312$ cd ~
ssm-user@ip-172-31-34-158:~$ cd /home
ssm-user@ip-172-31-34-158:/home$ ls
ssm-user ubuntu
ssm-user@ip-172-31-34-158:/home$ cd ubuntu/
ssm-user@ip-172-31-34-158:/home/ubuntu$ ls
action build deploy.log install
ssm-user@ip-172-31-34-158:/home/ubuntu$ cd action
ssm-user@ip-172-31-34-158:/home/ubuntu/action$ ls
appspec.yml build build.gradle deploy.log deploy_err.log gradle gradlew gradlew.bat practice-githubAction-0.0.1-SNAPSHOT.jar scripts settings.gradle src
예전에 파이썬으로 만들었던 프로젝트를 활용해서 간단한 방명록 애플리케이션을 만들어서 배포해봤다.