[CI_CD] (Github Actions) 확장성을 고려한 프로젝트에서 많이 쓰는 CI/CD 구축 방법
🪵 AWS CodeDeploy
※ 무중단 배포기능도 내재되어 있어 쉽게 무중단 배포를 구현할 수 있다.
AWS CodeDeploy
가 EC2
에 명령을 해야하는데, EC2
가 해당 명령을 알아들을 수 있는 프로그램을 설치해야 한다 (codedeploy-agent)
🧙♂️ EC2 內 codedeploy-agent 설치
1
2
3
4
5
6
7
8
sudo apt update && \
sudo apt install -y ruby-full 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
systemctl status codedeploy-agent
active (running) 확인 🔅
1
2
3
4
ls
(install, codedeploy-agent 설치파일)
rm -rf install
(없어도 상관x)
👹 확장성을 고려한 CI/CD 구축
Github Actions
에서 빌드 및 테스트를 수행하고, S3
에 빌드파일을 전달한다.
Github Actions
이 CodeDeploy
에 배포를 진행하라고 명령하면,
CodeDeploy
는 EC2
에게 S3
로부터 빌드 파일을 다운받고, 배포를 진행하도록 명령한다.
(정확히는 EC2
에 설치된 codedeploy-agent
에게 명령)
🔌 실습 STEP1: 확장성을 고려한 CI/CD 구축, AWS 설정
📔 외부 리소스가 AWS 리소스를 사용할 때 허용할 정책을 가진 사용자를 생성한다.
📔 정책은 특정 리소스에 대한 권한을 지정한다.
※ 하나의 역할은 여러개의 정책을 가질 수 있다. (역할 생성하면서 정책 연결)
📔 특정 AWS 리소스가 다른 AWS 리소스에 접근할 권한을 얻을 때 역할을 생성한다.
⛓️ Github Actions
(외부리소스)에서 S3
에 접근할 권한 필요 (빌드파일 업로드)
⛓️ Github Actions
(외부리소스)에서 CodeDeploy
에 접근할 권한 필요 (배포 진행 명령)
※ IAM
[IAM > 사용자]
🕹️ '사용자 생성'
사용자 이름: [TEST-SERVER-GITHUB-ACTIONS]
🕹️ '다음'
권한 옵션
✅ 직접 정책 연결
✅ AWSCodeDeployFullAccess
✅ AmazonS3FullAccess
🕹️ '다음'
🕹️ '사용자 생성'
생성된 사용자 🖱️
[보안 자격 증명 Tab]
'액세스 키 만들기'
✅ AWS 외부에서 실행되는 애플리케이션
🕹️ '다음'
🕹️ '액세스 키 만들기'
액세스 키 복사 📑
비밀 액세스 키 복사 📑
※ 따로 메모장에 저장
🕹️ '완료'
🕹️ '계속'
[in Github Repository]
[Settings > Secrets and variables > Actions]
🕹️ 'New repository secret'
AWS_ACCESS_KEY_ID
값 붙여넣기
🕹️ 'Add secret'
🕹️ 'New repository secret'
AWS_SECRET_ACCESS_KEY
값 붙여넣기
🕹️ 'Add secret'
⛓️ CodeDeploy
에서 EC2
에 접근할 권한 필요 (배포 진행 명령)
[IAM > 역할]
🕹️ '역할 생성'
✅ AWS 서비스
서비스 또는 사용 사례: [CodeDeploy 선택]
'다음'
AWSCodeDeployRole
(필요한 권한들이 이미 다 세팅되어 있다.)
'다음'
역할 이름: [CODE-DEPLOY-ROLE]
🕹️ '역할 생성'
⛓️ EC2
에서 S3
에 접근할 권한 필요 (빌드파일 다운로드)
[IAM > 정책]
🕹️ '정책 생성'
JSON 🖱️
아래 json 파일 복붙 📑
🕹️ '다음'
정책 이름: [CODE-DEPLOY-EC2-POLICY]
🕹️ '정책 생성'
1
2
3
4
5
6
7
8
9
10
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:Get*", "s3:List*"],
"Effect": "Allow",
"Resource": "*"
}
]
}
🪄 s3에 접근하고, 조회하는 기능을 허용
[IAM > 역할]
🕹️ '역할 생성'
✅ AWS 서비스
서비스 또는 사용 사례: EC2
🕹️ '다음'
위에서 생성한 정책 검색 🔍 [CODE-DEPLOY-EC2-POLICY] 및 체크
🕹️ '다음'
역할 이름: [CODE-DEPLOY-EC2-ROLE]
🕹️ '역할 생성'
[EC2 > 인스턴스]
✅ [생성했던 인스턴스]
[작업 > 보안 > IAM 역할 수정]
[새로 생성한 역할 선택]
🕹️ 'IAM 역할 업데이트'
[Amazon S3]
🕹️ '버킷 만들기'
버킷 이름: [TEST-SERVER-S3]
🕹️ '버킷 만들기'
[CodeDeploy > 애플리케이션]
🕹️ '애플리케이션 생성'
애플리케이션 이름: [TEST-APPLICATION]
컴퓨팅 플랫폼: ✅ EC2/온프레미스
🕹️ '애플리케이션 생성'
배포그룹: 프로덕션, 스테이징, 디벨롭 환경을 구별하기 위한 단위
🕹️ '배포그룹 생성'
배포 그룹 이름 입력: Production
서비스 역할 입력: [IAM에서 생성한 역할 선택]
[애플리케이션 배포 방법 선택]: ✅ 현재 위치
[환경구성]
✅ Amazon EC2 인스턴스
키: Name
값: [EC2 인스턴스 선택]
[로드밸런서]
로드 밸런싱 활성화 해제
🕹️ '배포 그룹 생성'
🔌 실습 STEP2: CodeDeploy 설정파일 및 쉘스크립트 파일 작성
해당 yml에는 S3로부터 빌드파일을 다운받고 쉘 스크립트 파일을 실행하라는 내용이 담겨있다.
※ EC2 내부에 설치된 codedeploy-agent
가 해당 파일을 읽고 실행한다.
※ 파일명이 꼭 appspec.yml 여야만 AWS CodeDeploy가 해당 파일을 인식한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: 0.0
os: linux
# AWS EC2가 S3로부터 어떤 파일을 어느 위치에 다운받을 것인지
files:
- source: / # S3의 저장한 전체 파일
destination: /home/ubuntu/test-server
# codedeploy-agent가 작업을 수행할 때 어떤 권한을 가지고 수행할 것인지
permissions:
- object: /
owner: ubuntu
group: ubuntu
# 애플리케이션을 시작할 단계에서 어떤 작업을 수행할 것인지
hooks:
ApplicationStart:
- location: scripts/start-server.sh # 쉘스크립트 파일 실행
timeout: 60
runas: ubuntu
- 🪄 소스 제공 위치
deploy.yml
파일에서aws deploy create-deployment
명령에서
--s3-location bucket=test-server-build-s3,bundleType=tgz,key=$GITHUB_SHA.tar.gz
옵션을 설정했기 때문에
files > source
는AWS S3
의 지정한 버킷을 가리킨다.
프로젝트 루트 > 📂scripts > start-server.sh
1
2
3
4
5
6
7
#!/bin/bash
echo "------------------서버 시작------------------"
cd /home/ubuntu/test-server
sudo fuser -k -n tcp 8080 || true
nohup java -jar project.jar > ./output.log 2>&1 &
echo "------------------서버 배포 끝------------------"
🔌 실습 STEP3: deploy.yml 워크플로우 파일 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
name: Deploy TO EC2 With CodeDeploy
on:
push:
branches:
- main
jobs:
Deploy:
runs-on: ubuntu-latest
steps:
- name: Github Repository에 업로드한 파일 불러오기
uses: actions/checkout@v4
- name: test
run: |
ls
pwd
- name: JDK 11 ver. 설치
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 11
- name: Java ver. 확인
run: java -version
- name: application.yml 파일 생성
run: echo "$" > src/main/resources/application.yml
- name: 테스트 및 빌드
run: |
chmod +x gradlew
./gradlew clean build
- name: 빌드된 파일 이름 변경
run: mv ./build/libs/*SNAPSHOT.jar ./project.jar
- name: 압축하기
run: tar -czvf $GITHUB_SHA.tar.gz project.jar appspec.yml scripts
- name: AWS Resource에 접근할 수 있게 AWS Credentials 설정
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-2
aws-access-key-id: $
aws-secret-access-key: $
- name: S3에 프로젝트 폴더 업로드
run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.tar.gz s3://test-server-build-s3/$GITHUB_SHA.tar.gz
- name: CodeDeploy를 활용해 EC2에 프로젝트 코드를 배포하라고 명령
run: aws deploy create-deployment
--application-name test-server-application
--deployment-config-name CodeDeployDefault.AllAtOnce
--deployment-group-name Production
--s3-location bucket=test-server-build-s3,bundleType=tgz,key=$GITHUB_SHA.tar.gz
- 🪄 압축
- tar -czvf [압축후 파일명] [압축할 대상1] [압축할 대상2] [압축할 대상1] …
-
- 🪄
Github Actions
에서 AWS 리소스에 접근할 수 있도록 로그인과 유사한 인증이 필요하다. - 🪄
AWS Credentials
🧩 관련 라이브러리:aws-actions/configure-aws-credentials@v4
-
- 🪄 aws 명령어
aws s3 cp --region ap-northeast-2 p1 s3://~/~.tar.gz
: S3에 있는 파일을 업로드
aws deploy create-deployment
배포생성 (개발자 도구 > CodeDeploy > 애플리케이션 > 배포그룹 > ‘배포 생성’ 하는 것과 같다.)
create-deployment
명령어가 실행되면, 지정한 S3 버킷에서.tar.gz
파일을 다운로드 받는다.
해당 압축파일을 임시 디렉토리에 풀고,appspec.yml
을 찾는다.
해당 파일을 파싱하고, 그 내용에 따라 EC2 인스턴스내에서 작업을 수행한다.
※CodeDeployDefault.AllAtOnce
: 모든 인스턴스를 한번에 배포하는 옵션 (인스턴스가 여러개 있을 때 중요)
[개발자 도구 > CodeDeploy > 배포]
배포 내용이 생겼는 지 확인 🔅
[Amazon S3]
S3에 압축된 파일이 업로드 되었는지 확인 🔅
($GIHUB_SHA.tar.gz)
[EC2 인스턴스 內]
ls
cd test-server
ls
appspec.yml output.log project.jar scripts 확인 🔅
lsof -i:8080
🍝 실행된 쉘스크립트 로그 확인
1
2
3
4
5
6
7
8
cd /opt
cd codedeploy-agent
cd deployment-root
cd [START WITH ALPHABET...]
ls
cd [DISTRIBUTION ID]
cd logs
cat scripts.log
- 🪄 배포 ID
- [개발자 도구 > CodeDeploy > 배포]
해당 배포 id에 해당하는 폴더가 생성되어 있다.