Jenkins에서 Ansible Playbook 사용하기

Violet_Evgadn·2023년 4월 25일
0

CI&CD 자동화

목록 보기
19/28

1. Jenkins 관리 > 시스템 설정 > Publish over SSH에 Ansible-Server 추가

이전 Docker Server를 설정한 것과 동일한 방식으로 설정한다.

필자는 이전과 마찬가지로 Windows에 Jenkins를 설치하였기 때문에 Username은 localhost, Port는 20022로 지정하도록 하겠다.

2. Ansible Project(새 Item) 생성

SSH Server에 Build 결과물 넘기기

위 Section에서 만든 My-Docker-Project를 Copy 하여 새로운 Item을 생성하자

빌드 후 조치 Section을 수정하자.

  • docker-server → ansible-server로 변경
  • Exec Command 지우기

이후 Apply & 저장 버튼을 눌러 Item을 생성하자.

3. 빌드 수행 및 배포 여부 확인


Ansible Server에 hello-world.war 파일이 생성되었음을 알 수 있다.

4. Ansible Playbook & Host 파일 만들기

이번엔 Playbook 뿐만이 아닌 Host 파일도 만들어 활용해보자.

이전까지는 Deafult값인 /etc/ansible/hosts 파일에 Ansible Node들의 IP Address를 입력하여 Ansible Node들과 통신하였지만 이번에는 Host 파일을 만들고 직접 Ansible Node들의 IP Address를 입력하여 활용해보자.

당연하겠지만 Playbook 및 Host 파일은 Ansible Server에 존재해야 한다.

(참고로 여기에서 헷갈렸던점이 이미 Build는 완료된 상태라는 것이다. 이미 Build 과정은 모두 수행되었고 hello-world.war 파일은 Ansibe Server 측에 존재한 상태에서 Ansible Playbook을 실행시킨다는 것을 재확인하고 가자)

Playbook 만들기

vi first-devops-playbook.yml

# Playbook 파일
---
- name : Remove Container And Images
  hosts: all  
  tasks:
  - name: stop current running container
    command: docker stop my_cicd_project
    ignore_errors: yes

  - name: remove stopped cotainer
    command: docker rm my_cicd_project
    ignore_errors: yes

  - name: remove current docker image
    command: docker rmi cicd-project-ansible
    ignore_errors: yes

- name : Make Docker Container
  hosts: localhost
  tasks:
  - name: build a docker image with deployed war file
    command: docker build -t cicd-project-ansible .
  - name : Create a container using cicd-project-ansible image
    command: docker run -d --name my_cicd_project -p 8081:8080 cicd-project-ansible

먼저 "ignore_errors" Variables에 대해 알아보고 가자.

ignore_errors: yes는 말 그대로 Task 실행 과정에서 에러가 발생했더라도 무시하고 다음 단계를 진행하라는 의미이다.

그렇다면 왜 이 Variable 설정이 필요할까?

만약 Ansible Node 측에 삭제할 Container가 존재하지 않거나 Image가 존재하지 않을 경우 에러가 발생할 것이다. 그런데 Ansible을 활용해 Server를 확장할 때는 새로운 Server에 배포를 진행하므로 당연히 Container나 Image가 존재하지 않을 것이다. 이 경우 에러가 발생할 테지만 배포 과정은 정상적으로 진행되어야 하므로 ignore_errors 설정을 추가하는 것이다.

이젠 Ansible Playbook 내용을 확인해보자.

이전에 봤던 Ansible Playbook과는 다르게 Play가 2개이다. 꽤 재밌는 이유 때문에 Play를 2개로 나누었다.

첫번째 Play의 1 ~ 3번째 Task에 특별한 부분은 없다. 이전에 중복된 Docker Image 및 Container 때문에 배포가 2번 이상 수행될 수 없다고 말했다. 그렇다면 이미 존재하는 Image와 Container를 삭제하고 다시 배포를 수행하면 중복된 이름으로 인한 오류는 발생하지 않을 것이다. 따라서 기존에 존재하던 Container와 이미지를 삭제하는 과정이 추가된 것이다.

하지만 2번째 Play는 조금 특이하다. 보다시피 2번째 Play의 hosts는 localhost이다.

이렇게 Play를 쪼개 굳이 hosts 값을 다르게 한 이유는 바로 우리가 Docker를 DooD 방식으로 활용했기 때문이다.

현재 필자는 ansible-server와 docker-server를 모두 DooD 방식으로 동작시키고 있다. 즉, 둘 모두 Socket은 Host의 Socket을 활용하고 있는 것이다.

이 과정에서 내가 "docker build ~" 명령어를 모든 Ansible Node에서 수행하면 어떻게 될까?

ansible-server와 docker-server 모두 "cicd-project-ansible"이라는 Docker Image를 생성하며 둘은 같은 Socket(Host의 Socket)을 활용하므로 결국 같은 이름의 Docker Image가 2번 생성되는 것과 같은 일이 벌어진다.

똑같은 이름의 Docker Image를 생성하지 않으려고 Ansible Playbook에 docker rmi 명령을 추가해 기존 Image를 삭제했는데 생성 과정에서 같은 이름의 Docker Image를 2개 생성하는 어처구니없는 상황이 발생하는 것이다.

따라서 중복된 이름의 Docker Image를 생성하지 않게 하기 위해서 localhost, 즉 Ansible-server 측에서만 Docker Container를 생성하도록 한 것이다.

이후 cicd-project-ansible Docker Image를 Localhost에서만 Container로 실행시키는 것도 동일한 이유이다.

Host 파일 만들기

vi hosts

# hosts 파일
[devops]
172.17.0.3
172.17.0.2

/etc/ansible/hosts와 동일한 값을 입력하도록 하자.

5. Jenkins > 구성 > Exec Command 추가 & 지금 빌드

ansible-playbook -i hosts first-devops-playbook.yml

성공했다.

(참고로 15인 것은 2 ~ 14까지 Ansible Playbook 실행 시 Docker Image가 생성되는 이유를 찾기 위해서였다. 너무 힘든 과정이였었다....)

http://localhost:8081/hello-world/에 접속하면 성공적으로 Application이 배포되었음을 알 수 있다.

6. 빌드 유발 > Poll SCM 선택 & Schedule : * * * * *로 지정

이젠 Github의 Commit을 감지하여 자동으로 빌드, 배포, 그리고 Ansible Playbook 실행까지 수행하도록 만들어보자.

사실 방법은 간단한데 이전에 Poll SCM에서 배웠던 것처럼 Item > 구성에 들어가 빌드 유발 Section에서 Poll SCM을 선택하고 Schedule을 "* * * * *"로 지정하기만 하면 된다.

이제 Github에 Commit & Push를 수행하여 Trigger가 발동되도록 하고 Jenkins가 자동으로 빌드 것을 기다려보자.

성공적으로 Jenkins에서 Build 과정이 수행되었다. 마지막으로 localhost:8081/hello-world에 접속하여 우리가 만든 변경사항이 실제로 적용되었는지 확인해보자.

성공!

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!

0개의 댓글