일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 알고리즘
- 프로토콜
- express
- 환경변수
- 프로젝트
- Amazon
- 보안
- amazonqcli
- Amazon Web Services
- 스프링부트
- ACC
- TCP
- ERD
- 아마존큐
- 백엔드프로젝트
- 아마존티셔츠
- mysql
- wecode
- 네트워크
- github
- CS
- node
- AWS
- 아마존큐이벤트
- javascript
- 클라우드
- 위코드
- 정보처리기사
- IP
- TCP/IP
- Today
- Total
아무튼!
[AWS/CICD] 깃허브 액션과 AWS를 이용한 CI/CD 구축 본문
깃헙 액션과 AWS 서비스를 이용한 CI/CD 환경 구축(v2024.03 - mac m1)
⚙️ CI/CD 실습
👉 해당 실습은 맨 아래에 링크해 놓은 영상을 참고하여 진행하였습니다.
초기 세팅
1. 간단한 스프링 프로젝트 작성 (해당 레포를(init 브랜치) 포크 혹은 클론하여 진행하시면 됩니다)
package com.cicdproject.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController{
@GetMapping("/hello")
public String helloWorld(){
return "Hello World";
}
}
- gradle 파일 (24.04.01 00:55수정) - 버전 수정되었음
- 간혹 오류가 발생하시는 경우 `JAVA_HOME` 환경변수를 확인해 주시길 바랍니다. 해당 실습은 자바 11버전을 기준으로 합니다
plugins {
id 'org.springframework.boot' version '2.6.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'accc'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
2. Github Repository에 push
- 자신의 github에 업로드하고 난 뒤 actions 탭으로 이동해 yml 작성을 시작합니다.
3. Workflow에 새 yml 설정
# This is a basic workflow to help you get started with Actions
name: Build and Deploy Spring Boot to AWS EC2
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-20.04
env:
working-directory: ../
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Java JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Grant execute permission for gradlew
run: cd cicd && chmod +x ./gradlew
shell: bash
- name: Build with Gradle
run: cd cicd && ./gradlew build
shell: bash
4. 커밋한 후 workflow 동작 확인
- jdk 설치, 빌드까지 잘 되는지 actions 실행 동작 확인
맨 위가 정상 작동하는 것! 아래는 실패하였을 때임😂
클라우드 세팅
1. S3 생성
- code를 클라우드 환경으로 옮기기 위한 S3 저장소 생성
- 추후에 iam을 이용하여 권한을 부여하기 때문에 모든 퍼블릭 액세스 차단을 유지하여 생성
✅ 코드를 S3 저장소에 업로드 하였을 때의 장점
1. 네트워크 대역폭 관리: 깃허브는 원격 저장소이며, 사용자들이 공유하는 네트워크 대역폭을 고려해야 합니다. 따라서 대용량 파일이 많은 경우 깃허브에서 다운로드하는 데 시간이 오래 걸릴 수 있지만 S3와 같은 객체 스토리지 서비스를 사용하면 다운로드 속도를 개선할 수 있습니다.
2. AWS의 전용 네트워크: AWS는 매우 빠르고 안정적인 네트워크 인프라를 가지고 있습니다. 따라서 AWS 내부에서 작업을 수행할 때는 일반 인터넷보다 빠를 수 있습니다. 이는 S3와 다른 AWS 서비스 간의 데이터 전송에도 적용됩니다.
3. AWS 서비스 간의 통합 및 최적화: 깃허브 액션을 사용하여 코드를 S3에 업로드하는 경우, AWS의 다른 서비스들과 통합하여 작업을 자동화하고 최적화할 수 있습니다. 예를 들어, 코드가 S3에 업로드되면 AWS Lambda를 사용하여 자동화된 작업을 실행하거나, AWS CloudFront를 통해 캐싱 및 배포를 최적화할 수 있습니다.
2. S3 IAM 사용자 생성
- 생성한 사용자의 액세스 키 id와 비밀 액세스 키 저장해 두기!
- aws [iam] -> [사용자 추가]에서 AmazonS3FullAccess와 AWSCodeDeployFullAccess 권한을 부여한 사용자를 생성
각자의 IAM 관리 정책에 따라 화면은 좀 다르게 표시될 수 있습니다.
그다음엔 방금 생성한 사용자의 [보안 자격 설정]에서 액세스 키를 발급받아야 합니다.
용도는 서드파티 선택
이후에 나오는 화면에서 액세스 ID, 키를 복사해 두거나 csv 파일을 다운로드하여서 저장해 둡니다.
이렇게 액세스 키가 활성화되어야 합니다
다만 IAM USER의 키를 다운로드하여야 하며, AmazonS3FullAccess, AWSCodeDeployFullAccess 권한을 부여해주셔야 합니다!
3. Github Repository Secrets에 액세스 키 저장
- 발급받은 IAM User의 비밀정보는 자신이 생성한 레포지토리의 [Settings] - [Secrets and variables] - [Actions] 에서 Repository secrets에 아래와 같은 이름으로 저장합니다.
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
4. EC2 생성 및 보안그룹 설정
- 이제 실제 서버를 구동시킬 EC2 인스턴스를 생성합니다.
- 80, 8080 포트를 열어줍니다.
- ssh 사용을 위해 22번 포트도 열어줍니다.
본 글은 Amazon Linux 2023 AMI, t2.micro를 기준으로 작성하였습니다.
EC2 생성 시 인바운드 규칙을 아래와 같이 수정
5. EC2 IAM 역할 생성
- 해당 EC2에 S3, CodeDeploy에 접근할 권한을 부여해 줄 IAM 역할을 생성
6. EC2 IAM 역할 연결
- EC2에 생성했던 IAM 역할을 부여합니다.
7. EC2 내에 프로그램 설치
EC2 접속은 EC2 선택 후 [작업] - [연결]을 누른 후 ssh를 통해 접속합니다.
접속은 이전에 받은 pem 키가 있는 디렉터리에서만 가능합니다.
권한이 너무 오픈되어 있다는 Permission 0644 오류가 발생할 경우 아래의 커멘드를 입력하여 해결합니다.
chmod 400 <pem키 이름>.pem
그다음 아래의 명령어를 차례로 입력하여 jdk 11을 설치하고 CodeDeploy agent도 설치합니다.
# aws corretto 다운로드
sudo curl -L https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.rpm -o jdk11.rpm
# jdk 11 설치
sudo yum localinstall jdk11.rpm
# java version 확인
java --version
# ruby 설치
sudo yum install ruby
# 서울 리전의 CodeDeploy 리소스 키트 파일 다운로드
cd /home/ec2-user
sudo wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
# 실행 권한 부여
chmod +x ./install
# 에이전트 설치
sudo ./install auto
# 에이전트 상태 확인
sudo service codedeploy-agent status
install 부분에서 오류가 발생할 때에는 `sudo su - root`로 root로 접속하여 `cd/home/ec2-user`로 이동한 후 chmod부터 다시 시도합니다.
amazon linux2등 다른 버전에 대한 설명은 아래에서 추가로 확인 가능합니다.
아마존 리눅스 또는 RHEL용 CodeDeploy 에이전트 설치 - AWS CodeDeploy
앞의 명령에서 /home/ec2-user는 Amazon Linux 또는 RHEL Amazon EC2 인스턴스의 기본 사용자 이름을 나타냅니다. 사용자 지정 AMI를 사용하여 인스턴스를 만든 경우 AMI 소유자가 다른 기본 사용자 이름을 지
docs.aws.amazon.com
8. CodeDeploy IAM 생성
- CodeDeploy를 위한 역할을 생성합니다.
9. CodeDeploy 애플리케이션 생성
- [CodeDeploy] - [애플리케이션] - [애플리케이션 생성] 으로 이동하여 애플리케이션을 생성합니다.
10. CodeDeploy 배포그룹 생성
- 생성한 애플리케이션 내에 배포 그룹을 생성합니다.
- 역할은 이전에 CodeDeploy를 위해 생성한 역할을 선택
- 배포는 현재 위치에
- 환경 구성은 amazonEC2 인스턴스 선택
- name은 생성한 EC2 선택
- 배포 구성은 AllAtOnce 선택
- 로드밸런서는 비활성화
설정 코드 작성
1. 처음 만들었던 deploy.yml 파일을 다음과 같이 수정
- env 수정
- PROJECT_NAME: 버킷에 저장할 프로젝트 폴더 이름
- BUCKET_NAME: S3 생성 시 지정했던 이름
- CODE_DEPLOY_APP_NAME: CodeDeploy의 앱 이름
- DEPLOYMENT_GROUP_NAME: CodeDeploy의 배포그룹 이름
# This is a basic workflow to help you get started with Actions
name: Build and Deploy Spring Boot to AWS EC2
on:
push:
branches: [ main ]
env:
PROJECT_NAME: cicd_project
BUCKET_NAME: yucori-cicd-bucket
CODE_DEPLOY_APP_NAME: cicdapp
DEPLOYMENT_GROUP_NAME: cicdapp_deploy
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Java JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Grant execute permission for gradlew
run: cd cicd && chmod +x ./gradlew
shell: bash
- name: Build with Gradle
run: cd cicd && ./gradlew build
shell: bash
- name: Make Zip File
run: zip -qq -r ./$GITHUB_SHA.zip .
shell: bash
- 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: ap-northeast-2
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
- name: Code Deploy
run: aws deploy create-deployment --application-name $CODE_DEPLOY_APP_NAME --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name $DEPLOYMENT_GROUP_NAME --s3-location bucket=$BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip
2. 커밋 후 Actions 동작 확인
3. appspec.yml 작성
- CodeDeploy의 동작을 설정하기 위해 appspec.yml을 작성합니다. 해당 파일은 소스 파일의 루트 경로에 위치시키면 됩니다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ec2-user/cicdproject
permissions:
- object: /home/ec2-user/cicdproject/
owner: ec2-user
group: ec2-user
hooks:
AfterInstall:
- location: cicd/scripts/deploy.sh
timeout: 60
runas: ec2-user
- files.source: CodeDeploy agent가 다운로드한 코드에서 어느 경로를 다운로드할지 결정함( / -> 전체 파일을 받음)
- file.destination: EC2 서버에서 어느 경로에 해당 코드를 저장할지 결정
- hooks.AfterInstall: CodeDeploy 수명주기 중 하나인 AfterInstall 발생 시 코드에서 scripts 폴더 안에 있는 deploy.sh를 실행하라는 이벤트
4. 배포용 쉘 스크립트 작성
- 코드의 scripts 디렉터리 안에 deploy.sh를 생성하고 아래와 같은 내용을 작성합니다.
- 해당 파일은 빌드된 jar 파일을 실행하는데, 만약 실행이 이미 되어있다면 해당 이름의 process를 kill 하고 새 버전의 서버 프로세스를 실행시켜 줍니다.
#!/usr/bin/env bash
REPOSITORY=/home/ec2-user/cicdproject/cicd
cd $REPOSITORY
APP_NAME=cicdproject
JAR_NAME=$(ls $REPOSITORY/build/libs/ | grep 'SNAPSHOT.jar' | tail -n 1)
JAR_PATH=$REPOSITORY/build/libs/$JAR_NAME
CURRENT_PID=$(pgrep -f $APP_NAME)
if [ -z $CURRENT_PID ]
then
echo "> 종료할것 없음."
else
echo "> kill -9 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi
echo "> $JAR_PATH 배포"
nohup java -jar $JAR_PATH > /dev/null 2> /dev/null < /dev/null &
5. 작성한 내용 반영 후 api 확인
- 포스트맨을 통해 서버가 정상적으로 실행됨을 확인할 수 있습니다.
6. CI/CD 동작 확인
- API 코드의 내용을 변경하고 깃허브에 push 한다.
- ex) 이전에 작성한 controller 파일의 return 부분의 문구를 수정하여 확인
실습 완료!🍀
<참조>
영상이 간결하면서도 설명이 잘 되어있어서 꼭 영상을 보며 따라 해보시기를 추천드립니다~
https://www.youtube.com/watch?v=UF2Giz9PE-E
GitHub - kbsat/cicdproject: CICD project
CICD project. Contribute to kbsat/cicdproject development by creating an account on GitHub.
github.com