목차
구축 전 팁 1. 간단한 Application 구축1.1 appspec.yml1.2 Scripts2. Git Repository 생성3. Bucket 생성4. EC2 및 Load Balancer 구축1.1 Jenkins 서버 구축docker 설치jenkins 설치code deploy plugin 설치1.2 App Server 구축조건IAM Role 생성첫번째 App Server 구축두번째 App Server 구축1.3 Load Balancer 구축5. CodeDeploy 구축배포 구성 생성애플리케이션 생성배포그룹 생성6. Jenkins 프로젝트 생성소스코드 관리 탭빌드 유발 탭Build 탭BootJar 테스크 실행하기이전에 존재하는 파일 제거하기Jar 파일 옮기기파일 합축 후, S3에 업로드 한뒤, CodeDeploy에게 알리기7. GitHub WebHook 추가8. Test8.1 Push8.2 Jenkins(CI) 확인8.3 S3 bucket 확인8.4 Codedeploy 확인8.5 브라우저 확인
https://galid1.tistory.com/746
위 포스팅에서 이어지는 글입니다.
이제부터 본격적으로 CICD 환경을 구축해보도록 하겠습니다.
- Application 구축
- Git Repository 생성
- S3 Bucket 생성
- EC2 및 로드밸런서 구축
- CodeDeploy 구축
- Jenkins 프로젝트 설정
- Git Hub WebHook 설정
- SNS, Lambda 구축 (Slack에 알림)
구축 순서는 위와 같습니다.
구축 전 팁
xxxxxxxxxx
/opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log
xxxxxxxxxx
less /var/log/aws/codedeploy-agent/codedeploy-agent.log
위의 log를 확인하며 구축합니다.
1. 간단한 Application 구축
Spring Boot 프로젝트를 만들고,
Spring Boot 프로젝트를 만들고, "/"
에 해당하는 Handler를 만듭니다.
LoadBalancer를 이용해 CodeDeploy로 부터 배포요청을 전달 받는경우, Application이 최종적으로 잘 동작하는지를 확인하는 Step이 존재합니다. 따라서, 80port에서 app을 동작시켜야 합니다. resources -> application.properties 에서 server.port=80 을 추가합니다.
보통의 경우, 테스트 코드를 작성하여, jenkins에서 통합시, 테스트 코드를 실행한뒤 빌드가 진행됩니다. 지금은 생략하도록 하겠습니다.
1.1 appspec.yml
codedeploy
에서 배포를 다루기 위해 필요한 appspec.yml
을 생성합니다. 배포 생명주기에 따라, 파일을 특정 디렉토리로 옮기거나, Shell Script를 실행하도록 명령할 수 있습니다.
appspec.yml
xxxxxxxxxx
version 0.0 #version은 필수 값이며 0.0이 고정입니다.
os linux #ec2에 배포하는 경우 필수 값이며, amazon linux를 사용하므로 linux를 입력합니다.
files
source /
destination /home/ec2-user
hooks
ApplicationStop
location Scripts/kill_process.sh #ApplicationStop 생명주기에, kill_process.sh를 실행합니다.
BeforeInstall
location Scripts/remove_before.sh #BeforeInstall 생명주기에, 이전에 생성된 파일들을 제거하는 remove_before.sh를 실행합니다.
ApplicationStart
location Scripts/run_process.sh #ApplicationStart 생명주기에, run_process.sh를 실행합니다.
위와 같이 작성합니다.
! appspec.yml 파일 작성시 주의 할점
- 파일의 이름은 EC2 배포 기준 꼭
appspec.yml
이이어어야 합니다. - appspec.yml은 번들링한 파일안의 최상단(root)에 위치해야 합니다.
- appspec.yml의 이름 및 내부의 작성될 내용은 배포대상 컴퓨팅 플랫폼과 os에 따라 영향을 받으므로 아래의 링크를 통해 확인 후 작성해야합니다.
https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure.html
자세한 작성 방법은 위의 링크를 통해 알 수 있습니다.
1.2 Scripts
이제 배포 과정에서 실행될 Shell Script를 생성합니다.
kill_process.sh
sudo pkill -f 'java -jar'
이 스크립트는, 앱을 배포한뒤 실행전, 이미 실행중이던 프로세스를 종료하는 스크립트입니다.
remove_before.sh
sudo rm -rf /home/ec2-user/*
find /opt/codedeploy-agent/deployment-root/배포디렉토리/* -maxdepth 0 -type 'd' | grep -v $(stat -c '%Y:%n' /opt/codedeploy-agent/deployment-root/배포디렉토리/* | sort -t: -n | tail -1 | cut -d: -f2- | cut -c 3-) | xargs rm -rf
- 가장 최근에 배포되었던 파일을 제외한 나머지 배포 파일들을 제거 합니다. , 배포디렉토리는 우선적으로 codedeploy에 의해 배포가 한번 진행 생성되는 파일이므로, 배포를 한번 진행해야 알 수 있습니다.
sudo rm -rf /home/ec2-user/*
- 이전 배포에서 생성된 파일을 제거합니다.
run_process.sh
x
cd /home/ec2-user
sudo java -jar *.jar > /dev/null 2> /dev/null < /dev/null &
이 스크립트는, 앱을 배포한뒤, 새로운 앱을 실행하기 위한 스크립트입니다.
>> /dev/null 2 > /dev/null < /dev/null &
은 표준 입출력 표준에러를 /dev/null
로 리다이렉트 함으로써, Codedeploy가 Process의 실행이 완료되었음을 알리기 위해 꼭 필요합니다.
2. Git Repository 생성
git repository를 생성한뒤, 위의 App을 Push합니다.
3. Bucket 생성
통합 및 빌드된 App
과 appspec.yml
,shellscript
들이 함께 번들링된 파일이 업로드될 S3버킷
을 생성합니다.
4. EC2 및 Load Balancer 구축
아키텍처에서 알 수 있듯이 총 3대의 EC2와 1개의 Load Balancer가 필요합니다.
1.1 Jenkins 서버 구축
Ec2 서비스에서, jenkins를 설치할 인스턴스를 시작합니다.
docker 설치
xsudo yum update -y
sudo amazon-linux-extras install -y docker
sudo service docker start
도커를 설치합니다.
jenkins 설치
xxxxxxxxxx
sudo su -
docker는 항상 root계정에서 사용합니다.
xxxxxxxxxx
docker run -d --name jenkins -p 32789:8080 jenkins/jenkins:jdk11
docker를 이용해 32789포트를 노출하여 jenkins를 실행합니다,
브라우저에서, 주소창에 "Jenkins가 동작중인 server의 domain":32789
을 입력합니다. administartor password의 경로를 복사합니다.
xxxxxxxxxx
docker exec -it jenkins bash
백그라운드에서 동작중인 jenkins 컨테이너에 bash 셸을 실행하며 attach합니다.
관리자 비밀번호를 복사하여 브라우저에 붙혀넣어 설치를 진행합니다.
Suggested install을 클릭하여, 설치를 진행하면 다음과 같이 Jenkins 설치가 완료됩니다.
code deploy plugin 설치
jenkins에서 codedeploy로 hook을 하기 위해서는 별도의 plugin을 설치해야합니다.
jenkins 관리 -> 플러그인 관리로 이동합니다.
설치 가능 탭에서 codedeploy를 검색하여 AWS CodeDeploy Plugin for Jenkins
를 설치합니다. (저는 사전에 설치하여 설치된 플러그인 목록에 나타납니다.)
1.2 App Server 구축
조건
- java app을 실행하기 위한
jdk
- code deploy 작업을 위한
codedeploy agent
- S3에 접근 가능한 IAM Role
- 로드밸런서 구축을 위한 서로 다른 두 서브넷에 존재하는 EC2 2대
IAM Role 생성
IAM -> 역할 -> 역할만들기를 선택합니다
신뢰할수있는 유형의 개체에서 AWS 서비스
사용 사례에서 EC2
를 선택합니다.
S3와 CodeDeploy에 접근할 수 있는 정책을 연결합니다.
첫번째 App Server 구축
AWS EC2 -> 인스턴스 시작을 클릭합니다.
AMI는 Amazon Linux 2 AMI를 선택하고, 인스턴스 유형은 어플리케이션에서 필요한 사양을 만족하는 유형을 선택합니다.
인스턴스 구성탭에서 2a
서브넷을 선택합니다. 그리고 앞서 생성한 EC2를 위한 역할을 추가합니다.
xxxxxxxxxx
# jdk 11 설치
sudo rpm --import https://yum.corretto.aws/corretto.key
sudo curl -L -o /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo
sudo yum install -y java-11-amazon-corretto-devel
# code deploy agent 설치
sudo yum -y update
sudo yum install -y ruby
cd /home/ec2-user
curl -O https://aws-codedeploy-us-east-2.s3.us-east-2.amazonaws.com/latest/install
sudo chmod +x ./install
sudo ./install auto
하단으로 스크롤을 내리면 사용자데이터
영역이 있습니다. 위의 내용을 복사 붙혀넣기 합니다.
CodeDeploy 구성에서 알아볼 수 있는 적절한 태그를 부여합니다.
보안 그룹에서는 80port 트래픽을 허용합니다.
두번째 App Server 구축
위와 모두 같은 방식으로 인스턴스를 생성하되 인스턴스 구성탭에서 이전 AppServer와는 다른 서브넷을 선택하여 생성합니다.
1.3 Load Balancer 구축
AWS EC2 Service -> 로드 밸런싱 -> 로드밸런서 탭의 로드 밸런서 생성
을 클릭합니다.
Application Load Balancer를 선택합니다.
리스너 탭에서는 HTTP 프로토콜을 선택합니다.
가용영역 탭에서는, 앞서 생성한 두 인스턴스가 위치하는 가용영역 2개를 선택합니다.
보안 그룹 구성에서는, 기존에 생성했던 Http 포트를 허용하는 보안그룹을 선택합니다.
새 대상 그룹을 선택하고 적절한 이름을 부여합니다
대상 유형은 인스턴스로 지정한 뒤, 프로토콜에서는 HTTP를 선택합니다.
앞서 생성한 두개의 AppServer를 선택하고 등록된 항목에 추가합니다.
5. CodeDeploy 구축
자동 배포를 위한 CodeDeploy를 설정하도록 하겠습니다.
배포 구성 생성
AWS CodeDeploy -> 배포 -> 배포구성 -> 배포 구성 만들기를 클릭합니다.
배포구성은 배포과정에서 성공 실패 여부를 결정하는 규칙 셋을 의미합니다. 우리의 규칙은 배포과정에서 최소 1개의 인스턴스가 서비스 가능한 상태를 유지해야 합니다.
따라서, 적절한 이름을 부여하고, EC2/온프레미스, 숫자, 값에는 1을 입력합니다.
애플리케이션 생성
AWS CodeDeploy -> 배포 -> 애플리케이션 -> 애플리케이션 생성
을 클릭합니다.
적절한 이름을 설정하고, EC2/온프레미스
를 선택하고 생성을 완료합니다.
배포그룹 생성
배포그룹을 생성하기전, CodeDeploy에서 배포대상이 되는 EC2 사용하기 위해 IAM Role이 필요합니다.
AWS IAM -> 역할 -> 역할만들기를 클릭합니다.
유형의 개체에서 AWS 서비스를 선택하고,
사용 사례에서 CodeDeploy -> CodeDeploy를 선택합니다.
다시 AWS CodeDeploy 서비스로 돌아와, 배포 -> 애플리케이션 -> 생성한 애플리케이션
을 선택합니다. 뒤이어 나타나는 화면에서, 배포그룹 -> 배포그룹 생성
을 클릭합니다.
적절한 이름을 부여하고, 서비스 역할에서, 앞서 생성한 역할을 선택합니다.
배포 유형에서, 현재위치를 선택합니다
환경 구성에서는 Amazon EC2인스턴스에 체크한뒤, 앞서 생성한 2개의 App Server를 선택합니다.
배포구성에서 앞서 생성한 배포구성을 선택합니다.
로드밸런싱 활성화를 체크하고, Application LoadBalancer를 선택합니다. 대상 그룹은 앞서 생성한 Loadbalancer group을 선택합니다.
6. Jenkins 프로젝트 생성
이제 Code가 푸시되었을때, code를 다운받아, 테스트 및 빌드를 실행한 뒤, CodeDeploy에게 배포 요청을 진행할 Jenkins Project를 생성합니다.
새로운 Item -> FreeStyle Project를 생성합니다.
소스코드 관리 탭
소스코드 관리탭에서 git
을 선택하고, 앞서 생성한 Repository의 주소를 기입합니다. Branches to build에는 jenkins project가 반응할 branch를 지정합니다.
빌드 유발 탭
빌드 유발 탭에서 GitHub hook trigger for GITScm polling을 체크합니다.
Build 탭
BootJar 테스크 실행하기
Build 탭에서, Gradle Wrapper 사용을 체크하고, Make Gradlew executable에 체크합니다.
Wrapper location에는 ${workspace}를 입력하고, Tasks에는 bootJar를 입력합니다.
이전에 존재하는 파일 제거하기
x
rm -f *.jar
add build step
을 누른뒤 execute shell
을 클릭한뒤 위의 내용을 추가합니다. 이 스크립트는 바로 아래에서 추가될 파일이 존재하는 경우 File exist
exception이 발생하는것을 방지하기위해 존재하는 파일을 제거하는 스크립트입니다.
Jar 파일 옮기기
x
cd build/libs/
mv *.jar ~/workspace/cicd-jenkins-project/
마찬가지로 shell을 추가하여, 위의 내용을 추가합니다. 이 스크립트는 bootJar
(빌드) 를 통해 생성된 파일을 옮기는 스크립트입니다.
파일 합축 후, S3에 업로드 한뒤, CodeDeploy에게 알리기
이제 한 곳에 모인 파일을 bundeling하여 S3에 업로드한뒤, CodeDeploy에게 알려야합니다.
우선 CodeDeploy에게 접근하기 위해서, IAM 사용자를 생성해야합니다. IAM Service -> 사용자 -> 사용자 추가를 클릭합니다.
적절한 이름을 입력한 뒤, 프로그래밍 방식 엑세스
에 체크합니다.
CodeDeployFullAccess, AmazonS3FullAccess를 선택합니다.
빌드 후 조치 탭에서 Deploy an application to AWS CodeDeploy를 선택합니다.
위와 같이 Codedeploy, S3 정보를 입력합니다.
Include Files에는 $JENKINS_HOME/workspace
경로에서 번들링할 파일을 선택하는 란입니다.
Exclude Files는 반대로 제외할 파일을 선택하는 란입니다.
AWS Access Key, AWS Secret Key는 앞서 AWS IAM에서 생성한 User의 정보를 입력합니다.
디렉토리 포함시 Scripts/*
를 입력하면, 디렉토리가 같이 포함됩니다.
7. GitHub WebHook 추가
GitHub에 개발자가 code를 push하는 경우, Jenkins에게 hook을 하도록 설정을 하겠습니다.
github reposiory -> Settings -> Webhooks -> Add WebHook을 클릭합니다.
"jenkin가 동작중인 domain:port"/github-webhook/
을 입력하고, ContentType은 application/json으로 변경합니다.
그림과 같이 표시되면 성공입니다.
8. Test
SNS, Lambda, Slack 연동은 다음 포스팅에서 다루기로 하고, 마지막으로 테스팅을 해보도록 하겠습니다.
8.1 Push
보통의 경우 Code Push를 개발자의 로컬에서 진행하지만, 테스트이므로, GitHub에서 바로 진행하도록 하겠습니다.
GitHub의 repo로 이동하여, 아무런 파일을 연뒤, 수정 버튼을 클릭합니다.
그후, 주석으로 내용을 바꾼뒤 커밋 메시지를 입력하고 커밋을 진행합니다.
8.2 Jenkins(CI) 확인
jenkins의 프로젝트로 이동하면, build가 진행중임을 알 수 있습니다.
8.3 S3 bucket 확인
jenkins에서 테스트 및 빌드 후, app과 appspec.yml, Scripts들이 번들링 되어 버킷에, 업로드 되었습니다.
8.4 Codedeploy 확인
AWS Codedeploy -> 배포 -> 배포탭을 확인하면, 배포내역을 확인할 수 있습니다.
8.5 브라우저 확인
로드밸런서의 주소로 요청합니다.
'Software Engineering > CICD (jenkins, etc)' 카테고리의 다른 글
CICD - Jenkins와 CodeDeploy를 이용한 CICD 구축하기 - 3 (Slack 채널에 메시지 보내기) (0) | 2020.06.24 |
---|---|
CICD - Jenkins와 CodeDeploy를 이용한 CICD 구축하기 - 1 (아키텍처, 과정 소개) (0) | 2020.06.23 |
CICD - Codedeploy란? (Codedeploy를 이용한 자동배포(CD) 환경 구축하기) (1) | 2020.06.22 |
CICD - 로컬 PC에 CICD환경 구축하기 (Jenkins, Ngrok, docker) (3) | 2020.06.17 |
Jenkins - AmazonLinux2 에서 Jenkins 구축 및 gitlab 연동 (push 시 자동 빌드) (0) | 2019.07.12 |