CI/CD 이론CI (Continuous Integration)CI란? CI가 필요한 환경 조건CI 핵심 목표CD (Continuous Deployment)CD란?CD 장점CI/CD 툴AWS - EC2, S3, IAM🔖 진행 순서보안 그룹 생성EC2 인스턴스 생성EIP 설정🍯 EC2 설정⁉️ 초기 설치를 위한 툴 설치하기⁉️ EC2에 Java 설치하기…IAM 설정S3 버킷 생성가즈아..CI/CD - GIT Action 편1. 프로젝트 빌드Github Action 설정소소한 팁S3 Upload 설정CodeDeployEC2에 IAM 역할 추가CodeDeploy IAM 역할 생성CodeDeploy 애플리케이션 만들어!CodeDeploy Agent 설치appspec.yml, deploy.sh 생성appspec.yml 파일 작성depoly.sh 파일 작성🐶 되는지 확인해 봅시다.트러블 슈팅🐶 읽어봐야 되는 글🔖 참고 사이트
CI/CD 이론
CI (Continuous Integration)

CI란?
- Continuous Integration, 지속적인 통합
- 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 레파지토리에 통합하는 것
CI가 필요한 환경 조건
- 다수의 개발자가 형상관리 툴을 공유하여 사용하는 환경
- MSA(Micro Service Architecture) 환경
CI 핵심 목표
- 버그를 신속하게 찾아 해결
- 소프트웨어의 품질 개선
- 새로운 업데이트의 검증 및 릴리즈의 시간 단축
CD (Continuous Deployment)

CD란?
- Continuous Delivery는 공유 레파지토리로 자동으로 Release 하는 것
- Continuous Deployment는 프로덕션 레벨까지 자동으로 deploy 하는 것
- 개발자의 변경 사항이 레파지토리를 넘어, 고객의 프로덕션 환경까지 릴리즈 되는 것
CD 장점
- Agile 방법론의 경우… 서비스의 사용자는 최대한 빠른 시간 내에 최신 버전의 Production을 제공받을 필요가 있는데, 이 때, 소프트웨어가 언제든지 신뢰 가능한 수준의 버전을 유지할 수 있도록 support 하는 목표!
- 서비스의 개발팀과 비지니스팀(영업, CS팀 등) 간의 커뮤니케이션 부족 문제를 해결, 배포에 이르기까지의 노력을 최소한으로 단축시켜 준다는 Benefit을 제공
CI/CD 툴
- Jenkins
- Travis CI
- Bamboo
AWS - EC2, S3, IAM
🔖 진행 순서
- 보안 그룹 생성
- EC2 인스턴스 생성
- IAM 생성
- S3 Bucket 생성
보안 그룹 생성
먼저 EC2 인스턴스에서 사용할 보안 그룹부터 만듭니다.
default-ec2-server
라는 이름으로 보안 그룹 이름을 설정함

- 인바운드 규칙에 추가를 한다.
- ✨ SSH
- 전체 오픈을 하거나 pem 키가 노출 되는 경우, 어느 순간부터 서버로 코인이 채굴되고 있을듯…
- 보안을 위해 내 IP로 설정했습니다.
- 8080, HTTPS

이를 위해서 보안이 필요하고 pem 키 관리와 지정된 IP에서 SSH 접속이 되도록 구성하는 걸 추천
테스트를 위해 위의 2개는 전체 오픈을 합니다.
- 나머지는 기본 값으로 저장하면 끗.

EC2 인스턴스 생성
- 이름 : 웹 서버 이름을 설정해주세요.

- 앱 및 OS 이미지 선택

- 인스턴스 유형 설정

- 키 페어(로그인) 설정 → 만들어놓은 키가 없다면 키 페어 생성하기!

- 스토리지 구성 → 프리티어 최대치인 30GB 설정하기

- 보안 그룹 적용!!!
기존 보안 그룹 선택으로 위에서 만든 보안 그룹으로 설정합니다

- 나머지는 기본 설정으로 저장하면 끗.

EIP 설정
기본적으로 인스턴스가 중지되고 다시 시작할때마다 IP가 변경 되므로, 매번 설정을 바꿔줘야 할 것입니다.
이를 위해 Elastic IP(탄력적 IP)를 설정해서 매번 변경되지 않고 고정 IP를 가지도록 합니다.
- 탄력적 IP 선택 후 탄력적 IP 주소 할당을 클릭합니다.

- 네트워크 경계 그룹만 EC2에 맞춰서 설정을 해주고 할당을 클릭해서 생성합니다.

- 생성된 EIP 선택 후에 작업 탭에서 탄력적 IP 주소 연결 클릭

- 이제 생성된 EC2 인스턴스로 연결시켜줍니다.

- 끗.

인스턴스 PUBLIC IP 주소가 EIP로 설정된 것을 확인 할 수 있습니다.
🍯 EC2 설정
# 키를 .ssh 폴더로 복사해줍니다. cp hello-cicd-server_key.pem ~/.ssh/ # 이제 설정을 해줍니다. vim ~/.ssh/config ### 편집창 ### Host hello-cicd-server HostName [AWS PUBLIC IP] User ec2-user IdentityFile ~/.ssh/hello-cicd-server_key.pem ### 작성이 끝났다면? → 종료 ### :wq # 생성된 config 파일은 실행 권한이 필요 → 권한 부여 GoGo chmod 700 ~/.ssh/config
- hello-cicd-server : 서비스명
🫥 [before] EC2 접속
ssh -i hello-cicd-server_key.pem ec2-user@[AWS PUBLIC IP]
😎 [after] EC2 접속
ssh hello-cicd-server
⁉️ 초기 설치를 위한 툴 설치하기
sudo yum update sudo yum install ruby sudo yum install wget
⁉️ EC2에 Java 설치하기…
요거 해야지 jar 파일 실행 가능 하니께.. 설치해주쇼
- JDK 17 설치
wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.rpm sudo rpm -ivh jdk-17_linux-x64_bin.rpm sudo alternatives --config java java -version
- 나머지 버전은 알아서 추가해주세요… 🫠
IAM 설정
이제 S3와 CodeDeploy 권한을 가진 사용자를 추가해줍니다.
- IAM으로 와서 사용자 추가를 클릭합니다.
- 사용자 이름 등록 하고, 액세스 유형은 프로그래밍 방식 액세스를 선택합니다.

- 기존 정책 직접 연결을 선택

- S3와 CodeDeploy 권한을 추가


- 태그에 이름만 추가를 해주고…

- 마지막으로 확인하고 사용자를 추가합니다.

- ✨ 해당 사용자의 정보는 어딘가에 안전하게 보관해주세요. → Github Action 에서 액세스 키와 비밀키를 등록해줘야 합니다.

S3 버킷 생성
- AWS의 S3 서비스는 파일 서버
- Build 파일을 저장하는 용도로 사용
- CodeDeploy에서 배포할 파일로 가져가도록 구성
가즈아..
- 버킷명 설정

- IAM 키로 접속할 예정이기 때문에 모든 퍼블릭 액세스를 차단시켜 줍니다.

- 저장하면 끗.

CI/CD - GIT Action 편
1. 프로젝트 빌드
Github Action 설정
- 가는 길…


- 여기서 이제 파일명 설정을 하고 내용을 작성하면 됩니다.

- 🐶 작성을 해보면..?
작성 전 주의점
yaml 파일 작성 때, 들여쓰기 안맞거나 오타나는 부분을 조심해주세요!
name: hello-cicd # workflow 언제 실행 될것인지 트리거 지정 on: # develop 브랜치에 대한 push request를 이벤트 트리거로 지정 push: branches: - develop # 수동으로 해당 workflow 실행 지정 workflow_dispatch: # workflow는 한개 이상의 job을 가지며, 각 job은 여러 step에 따라 단계를 나눌 수 있다. jobs: build: # 어떤 환경에서 실행할 것인지 지정 runs-on: ubuntu-latest # 작업의 실행 단계 steps: - name: Checkout uses: actions/checkout@v3 # Java 세팅 # https://github.com/actions/setup-java - name: Set up JDK 17 uses: actions/setup-java@v1 with: java-version: 17 # IF (Maven의 경우...) - name: Build with Maven run: mvn -B package --file pom.xml # Else IF (Gradle의 경우...) - name: Grant execute permission for gradlew run: chmod +x ./gradlew shell: bash - name: Build with Gradle run: ./gradlew clean build shell: bash # End IF
- 작성을 하고 Commit을 하면 workflows 폴더가 생성되고, 안에 작성된 파일이 생성됩니다.

- 지금까지 작성된 부분까지 잘 작동하는지 먼저 확인해주세요. (이제부터 Action 들은 여기서 확인 가능 합니다.)

빌드까지 성공된 것을 확인할 수 있습니다.

소소한 팁
- 실패한 Action도 재 실행 가능합니다. (요인이 외부 요인(AWS 설정 등) 이라면 재실행 해볼만 하겠죠?)

- 그리고 위 사진의 deploy.yml 안에 있는 build를 클릭하면…?

(어느 Step 에서 실패 했는지 오류 내역까지 확인 가능합니다.)
S3 Upload 설정
deploy.yml
→ 설정 추가
# 현재 스크립트에서 사용할 환경 변수 정의 env: PROJECT_NAME: hello-cicd DEPLOY_GROUP: hello-cicd-group S3_BUCKET_NAME: hello-cicd-bucket AWS_REGION: ap-northeast-2 # workflow는 한개 이상의 job을 가지며, 각 job은 여러 step에 따라 단계를 나눌 수 있다. jobs: build: ... ### S3 uload 설정 ### # $GITHUB_SHA : Github Actions에서 제공하는 기본 환경변수 # 현재 workflow 실행시키는 커밋의 Hash 값 - name: Make zip file run: zip -r ./$GITHUB_SHA.zip . shell: bash # ${{ secrets.~~~ }} : 보안 설정 값 - name: Configure AWS credentials uses: aws-action/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 S3 run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
Upload to S3 마지막 부분 s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
- S3 - Upload 구현을 위해 Github Action 키 값 지정
- AWS_ACCESS_KEY_ID : IAM 사용자 액세스 키 ID
- AWS_SECRET_ACCESS_KEY : IAM 사용자 Secret 액세스 키

위에서 생성한 IAM 키값들을 여기에 등록해줍니다.

- 그라믄.. 이제 이것도 되는지 확인해 봐야겠쥬?

현재 시각.. 7월 14일(목) 오후 3시 48분..

zip 파일로 등록된 것을 확인할 수 있습니다.
쒜엩… 이제 끝이 보인다.. 🫠
CodeDeploy
S3에 등록된 배포파일로 이제 배포하고 실행까지 시켜봅시다.
Code Commit, Code Build도 있다곤 하는데 CodeDeploy가 짱짱맨이라고 합니다. (넘나 많은 기능 지원)
EC2에 IAM 역할 추가
EC2가 CodeDeploy를 연동 받을 수 있도록 IAM 추가
- IAM에서 역할 탭에서 역할 만들기 클릭

- AWS 서비스 선택 후 EC2를 선택해줍니다.

- AmazoneEC2RoleforAWSCodeDeploy를 추가합니다.

- 역할 이름 등록 후 저장!

- EC2에 역할을 수정해줍니다.

만들어 놓은 역할을 설정해주세요.

CodeDeploy IAM 역할 생성
CodeDeploy에서 EC2로 접근할 수 있도록 IAM 역할을 생성해 줍니다.
- 위와 역할 만들기, AWS 서비스 & EC2 선택 동일
- AWSCodeDeployRole 권한 추가

- 역할 이름 등록 후 저장!

- 🫥… 신뢰관계도 추가해봅시다. [추가사항] → 이거 추가 안하면 CodeDeploy 등록할 때 검색 안됨…
- 신뢰 정책 편집을 클릭해주세요.
- Service 부분에 CodeDeploy도 추가해줍니다.
- 끗.


CodeDeploy 애플리케이션 만들어!
- CodeDeploy의 시작하기 탭에서 애플리케이션 생성 버튼 클릭

- 애플리케이션 이름을 등록하고 생성해줍니다.

- 그리고 바로 배포 그룹을 생성해줍니다.

- 배포 그룹 이름 지정

- 서비스 역할 추가

- 환경 구성 등록 : Amazon EC2 인스턴스 선택 및 Name 태그 등록

- 배포 설정 확인해 주시구요.

- 서버 1대이니까.. 로드 밸런서는 OFF 시켜줍니다.

- 이제 저장하면 끗.
CodeDeploy Agent 설치
- EC2에 접속해서 CodeDeploy를 설치해줍니다.
# CodeDeploy Agent 설치 sudo yum update sudo yum install ruby sudo yum install wget wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/latest/install chmod +x ./install sudo ./install auto # CodeDeploy Agent가 실행되고 있는지 확인 sudo service codedeploy-agent status
- deploy.yml - CodeDeploy 설정 정보 추가
deploy.yml
→ 설정 추가# 현재 스크립트에서 사용할 환경 변수 정의 env: PROJECT_NAME: hello-cicd DEPLOY_GROUP: hello-cicd-group S3_BUCKET_NAME: hello-cicd-bucket AWS_REGION: ap-northeast-2 # workflow는 한개 이상의 job을 가지며, 각 job은 여러 step에 따라 단계를 나눌 수 있다. jobs: build: ... - name: Code Deploy run: | aws deploy create-deployment \ --application-name $PROJECT_NAME \ --deployment-group-name $DEPLOY_GROUP \ --file-exists-behavior OVERWRITE \ --deployment-config-name CodeDeployDefault.AllAtOnce \ --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip \ --region ap-northeast-2
- bucket : 버킷 이름
- bundleType : 확장자…?
- key : 폴더 경로가 포함되어 있다면 폴더 경로까지 합쳐서 작성해주세요.
appspec.yml, deploy.sh 생성

- deploy.sh 의 경우에는 scripts 안에 생성 (선택 사항: 루트에 만드셔도 됩니다.)
- appspec.yml 파일도 생성해줍니다.
appspec.yml 파일 작성
배포를 위한 스크립트를 작성해줍니다.
프로젝트 루트 경로에 appspec.yml 파일을 작성해줍니다.
# CodeDeploy 버전 # 프로젝트 버전이 아니므로 0.0 외에 다른 버전을 사용하면 오류 발생 version: 0.0 os: linux files: # source # CodeDeploy에서 전달해 준 파일 중 destination으로 이동시킬 대상을 지정 # 루트 경로(/)를 지정하면 전체 파일을 이야기한다. - source: / # source에서 지정된 파일을 받을 위치 # 이후 jar를 실행하는 등은 destination에서 옮긴 파일로 진행 destination: /home/ec2-user/app/hellocicd/zip/ # overwrite # 기존에 파일들이 있으면 덮어쓸지 결정 # 현재 yes라고 했으니 파일 덮어씀 overwrite: yes # CodeDeploy에서 EC2 서버로 넘겨준 파일들을 모두 ec2-user 권한을 갖도록 한다. permissions: - object: / pattern: "**" owner: ec2-user group: ec2-user # CodeDeploy 배포 단계에서 실행할 명령어 지정 # ApplicationStart라는 단계에서 deploy.sh를 ec2-user 권한으로 실행 # timeout: 60으로 스크립트 60초 이상 수행되면 실패 # (무한정 기다릴 수 없으니 시간 제한을 둬야 한다.) hooks: ApplicationStart: - location: scripts/deploy.sh # 루트 경로로 부터 deploy.sh의 위치를 설정해주세요. timeout: 60 runas: ec2-user
depoly.sh 파일 작성
이 녀석은 ApplicationStart 단계 때, EC2 에서 실행될 Shell 파일 입니다.
#!/bin/bash REPOSITORY=/home/ec2-user/app/hello PROJECT_NAME=hello echo "> Build 파일 복사" # zip 파일의 jar 파일의 경로를 이동시켜 줍니다. # IF MAVEN THEN cp $REPOSITORY/zip/target/*.jar $REPOSITORY/ # ELSE IF cp $REPOSITORY/zip/build/libs/*.jar $REPOSITORY/ # FI echo "> 현재 구동 중인 애플리케이션 pid 확인" CURRENT_PID=$(pgrep -fl $PROJECT_NAME | awk '{print $1}') echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID" if [ -z "$CURRENT_PID" ]; then echo "> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다." else echo "> kill -15 $CURRENT_PID" kill -15 $CURRENT_PID sleep 5 fi echo "> 새 애플리케이션 배포" # 자... jar 파일 실행해 봅시다... JAR_NAME=$(ls -tr $REPOSITORY/*.jar | tail -n 1) echo "> JAR Name: $JAR_NAME" echo "> $JAR_NAME 에 실행 권한 추가" chmod +x $JAR_NAME echo "> $JAR_NAME 실행" # 이 부분이 핵심인데, 필요한 설정 값들을 포함해서 jar 파일을 실행시켜주면 됩니다. nohup java -jar -Dspring.profiles.active=real $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &
- PID 찾는 부분이 안되면… 명령어는 알맞게 변경해주세요. 😓
🐶 되는지 확인해 봅시다.
- Github Action 확인 → 정상적으로 Code Deploy가 작동한 것을 볼 수 있습니다.

- 실제 API로 확인해 봅시다.
- 초기 세팅
- 메서드 변경
- Commit & PR 및 Action 확인
- Code Deploy 배포 확인 → AWS에서 확인 가능
- API 확인
- 끗.




굳… 👍


굳… 👍
트러블 슈팅

🐶 읽어봐야 되는 글
🔖 참고 사이트
기타