글 작성자: beaniejoy

 

https://codingtricks.io/how-to-run-ansible-playbook-from-jenkins

 

지난 게시글 중에 Jenkins 서버를 설치하고 Spring boot project 대상으로 간단하게 테스트, 빌드까지 해보는 Jenkins pipeline을 적용해보는 글이 있었습니다. 이번 게시글을 읽기 전에 먼저 읽어보시는 것을 추천드립니다.
(https://beaniejoy.tistory.com/95)

 

[Jenkins] Lightsail에 Jenkins server 구축해보고 Spring project 빌드해보기

목적 - AWS Lightsail을 통해 생성한 instance에 jenkins server 구축한 내용 기록용 목표 - AWS Lightsail에 띄운 instance에 jenkins server 띄우기 - jenkins server 기본적인 설정 - jenkins item 생성 후 spring project build 해

beaniejoy.tistory.com

이번 게시글에는 설치된 Jenkins에 Ansible plugin을 적용해보는 내용을 정리해보고자 합니다.

 

📌 1. Ansible을 왜 적용하려고 하나요? (장점이 무엇인가요?)

Ansible에 대한 원론적인 개념을 언급하지는 않으려고 합니다. 구글에 ansible만 쳐도 개념은 아주 자세하게 잘 나와있기 때문에 혹시 ansible를 완전히 처음인 분들은 개념 한 번 보시고 아주 기본적인 내용을 가지고 테스트로 ansible 실행해보시는 것을 추천드립니다.

저는 ansible을 사용하게 된 직접적인 계기는 실무에서 사용하고 있기 때문입니다. 그래서 로컬에서 여러 vm을 설치해 ansible을 테스트로 돌려보면서 이번 개인프로젝트 CI/CD 프로세스에 적용해보기로 했습니다.

 

1-1.  개인적으로 느낀 ansible의 장점

ansible을 아주 기본적인 형태로밖에 사용하지 못했지만 개인 프로젝트에 적용해보면서 느낀 장점은 제가 관리하고 있는 개발 프로젝트 내부에서 ansible script 파일을 컨트롤할 수 있다는 점입니다.

개인적으로 인프라적인 요소들을 접목하는데 있어 중요하게 생각하는 것 중 하나는 설정 관련된 내용들이 뿔뿔이 흩어져있지 않고 되도록 한 곳에서 관리될 수 있게 하는 것입니다. 물론 모든 것을 한 곳에 관리하는 것은 불가능하긴 합니다. 개발은 개발 따로, CI 툴 따로, 배포 관련 서버 따로, 모든 설정들이 흩어져 관리된다면 수정하는 것도 힘들어지고 오류 발생시 확인하는 과정도 더 번잡해질 가능성이 커집니다.

ansible은 이러한 저의 니즈를 아주 적절하게 충족해주는 도구라 할 수 있습니다.
ansible은 playbook이라는 script를 통해 대상이 되는 서버에 여러 설정을 지시할 수 있습니다. 디렉토리, 파일 생성과 같은 아주 기본적인 것들부터 필요한 패키지 설치, shell script 실행 등 파일 실행도 할 수 있고 심지어 직접 작성한 파일을 대상이 되는 서버로 전송할 수도 있습니다. 이렇게 되면 애플리케이션 실행을 하기 위한 shell script와 같은 실행파일도 하나의 개발프로젝트에서 관리가 가능해집니다.

개발프로젝트에서 ansible 관련 스크립트 파일도 관리가 가능

개발 프로젝트에다 관리하는 것이 오히려 번잡하다 생각하시면 ansible 관련 설정내용만 따로 git repository로 관리하셔도 되고 편한 방식으로 하셔도 됩니다. 정답은 없지만 개발하는 입장에서 인프라적인 요소도 같이 관리를 해야 한다면 최대한 보기 쉽고 오류에 대응하기에도 편리한 방식을 고민하는 것이 중요한 것 같습니다.

 

📌 2. Jenkins 서버에 Ansible 패키지 설치하기

저는 Jenkins를 AWS에 설치를 했는데요. 리소스 비용 문제로 Jenkins가 설치된 동일 서버에 ansible도 같이 설치하였습니다.

AWS OS는 최근에 나온 Amazon Linux 2023을 사용하고 있는데요. 해당 OS에서 ansible 설치하는 방법을 자세하게 소개하는 블로그이 있어 첨부해드리겠습니다. https://cloudkatha.com/how-to-install-ansible-on-amazon-linux-2023/

 

How to Install Ansible on Amazon Linux 2023 - CloudKatha

discussed How to Install Ansible on Amazon Linux 2023 Instance. We learnt that Amazon Linux Extras and EPEL are not available on Amazon Linux

cloudkatha.com

(블로그 내용만 잘 따라서 입력하시기만 하셔도 설치하실 수 있습니다.)

$ pip install ansible

$ ansible --version
ansible [core 2.15.2]
  config file = None
  configured module search path = ['/home/ec2-user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ec2-user/.local/lib/python3.9/site-packages/ansible
  ansible collection location = /home/ec2-user/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/ec2-user/.local/bin/ansible
  python version = 3.9.16 (main, Feb 23 2023, 00:00:00) [GCC 11.3.1 20221121 (Red Hat 11.3.1-4)] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True

ansible 버전을 확인했을 때 위와 같이 콘솔창에 메시지가 나오면 설치 완료된 것입니다. 위 내용 중에 중요하게 기억해두고 있어야할 내용은 executable location입니다. pip로 설치했을 때 /usr/bin 에 설치가 되는 것이 아닌 /home/ec2-user/.local/bin 에 설치가 된다는 것입니다. 조금 있다가 Jenkins에 ansible plugin을 적용할 때 고려해야하는 부분이니 그 때 다시 한 번 언급하도록 하겠습니다.

 

📌 3. Jenkins에 Ansible plugin 적용해보자

Jenkins에 접속하고 Jenkins 관리 > Plugins > 왼쪽 탭 Available plugins 이동합니다. 거기에 ansible이라고만 검색해도 Ansible plugin이라고 나옵니다. 바로 설치 진행해줍니다.

저는 이미 ansible plugin 설치된 상태이기 때문에 Installed에 해당 플러그인이 나오고 있습니다.

Ansible plugin을 설치하고 나서 확인해봐야하는 중요한 내용이 있습니다. Jenkins 관리 > System Information에서 환경 변수를 확인해줍니다.

jenkins에 등록된 PATH 환경변수 확인

거기에 PATH 환경변수가 어떻게 등록이 되어있는지 확인을 해야합니다. 만약 /home/ec2-user/.local/bin이 등록안되어 있다면 Jenkins에 PATH를 다시 등록하거나 ansible plugin installation 관련 설정을 해야 jenkins에서 ansible을 사용할 수 있습니다.

Jenkins는 PATH에 등록된 경로를 기준으로 설치된 플러그인들에 대한 실행을 프로그램을 찾게 됩니다. 위에서 pip를 통해 ansible 설치했을 때 /home/ec2-user/.local/bin 경로에 설치된 것을 확인했는데요. Jenkins에서는 해당 경로를 인식 못하기 때문에 Jenkins 상에서 ansible을 실행하려고 한다면 에러가 발생하게 됩니다.

jenkins에 등록된 PATH에 ansible 실행파일 없을시 위와 같이 에러가 발생

또 하나 주의해야할 점이 AWS에 명령프롬프트로 PATH를 출력했을 때하고 Jenkins에 등록된 PATH 내용이 다를 수 있기 때문에 되도록 위에서 보여드렸던 것처럼 jenkins에 설정된 PATH 내용을 확인하셔야 합니다.

 

위의 jenkins PATH 확인했을 때 ansible 실행파일이 있는 경로가 설정이 안되어있을 때 Jenkins에 ansible 관련 설정을 해야 합니다.
Jenkins 관리 > Tools에 들어갑니다. Ansible plugin을 설치하면 Ansible 항목이 보일텐데요. 거기에 pip를 통해 설치된 ansible 실행프로그램이 있는 경로를 지정해주면 됩니다.

여기까지 하면 Jenkins에 기본적인 Ansible 설정이 완료된 것이고 Jenkins를 통해 ansible을 실행할 수 있게 됩니다.

 

📌 4. Jenkins pipeline에 ansible-playbook 테스트해보자

 

4-1. ansiblePlaybook에 대한 pipeline script 작성하기

jenkins pipeline을 통해 ansible playbook을 한 번 실행해보겠습니다.

우선 젠킨스에 새로운 item 하나를 pipeline으로 생성하고 기본 설정을 해줍니다.
(맨 위에 링크드린 제 게시글에서 젠킨스 item 설정하는 방법있으니 참고바랍니다!)

주의할 점은 item 설정할 때 대상이 되는 Jenkinsfile 스크립트 파일 path(파일이름까지)를 잘 설정하셔야 합니다.

jenkins의 pipeline item 생성하면 설정 맨 아래에 Pipeline Syntax가 있습니다.

그 다음 item 설정 맨아래에 보시면 Pipeline Syntax가 있습니다. 해당 링크를 클릭하면 pipeline script를 간편하게 설정할 수 있도록 각종 샘플을 제공하는 페이지가 나올 것입니다.

Ansible plugin을 설치했다면 Sample Step에 ansiblePlaybook이라고 나올 것입니다. 해당 샘플을 클릭하면 아래에 관련 설정들이 나오게 됩니다. 모든 설정을 다 기입할 필요는 없는데요. 테스트를 위해 간단하게 기입해보겠습니다.

  • installation: Jenkins 관리 > Tools에서 Ansible Installation을 설정했으면 해당 내용이 나올 것입니다. 그 설정을 지정해주면 됩니다.
  • playbook file path: ansible-playbook을 실행하기 위한 스크립트 파일인 playbook 파일의 경로를 설정해줍니다.
  • inventory file path: ansible-playbook 실행의 대상이 되는 서버에 대한 내용이 설정된 ansible용도의 hosts 파일의 경로를 설정해줍니다.

설정내용들을 기입하고 맨 아래에 Generate 어쩌구 버튼이 있는데요. 클릭하면 설정 내용들을 토대로 pipeline script 내용을 생성해줍니다. 생성된 script 내용을 빌드할 Jenkinsfile에 기입해주면 됩니다.

pipeline {
    agent any

    stages {
        stage('Init') {
            steps {
                script {
                    // ansible playbook
                    ANSIBLE_INVENTORY = "${HOME}/ansible/inventory"
                    ANSIBLE_PLAYBOOK = "${WORKSPACE}/scripts/deploy/test.yml"
                }
            }
        }

        stage('Run Application with Ansible') {
            steps {
                ansiblePlaybook(
                        installation: 'ansible',
                        playbook: "${ANSIBLE_PLAYBOOK}",
                        inventory: "${ANSIBLE_INVENTORY}",
                        extraVars: [
                                hello: "world",
                                beanie: "joy"
                        ]
                )
            }
        }
    }
}

위의 Jenkinsfile-test 파일을 개발 프로젝트의 root 경로(프로젝트 최상단 위치)에 만들어두고 github repo에 푸시하시면 됩니다.
(참고로 extraVars는 playbook으로 전달할 외부 변수들을 지정한 것입니다. 뒤에 playbook 만들 때 출력용도로 사용될 예정입니다.)

 

4-2. 서버에 ansible 관련 파일 생성하기(hosts, playbook)

이제 ansible에서 사용될 hosts파일과 playbook을 만들어야 합니다.

hosts 파일은 위의 script에서 inventory에 지정한 ${HOME}/ansible/inventory 경로에 만들어야 합니다. ${HOME}은 jenksins 프로그램이 돌아가고 있는 서버의 사용자 디렉토리로 AWS에서 /home/ec2-user를 가리킵니다.
/home/ec2-user/ansible/inventory 경로에 hosts 파일을 생성합니다.

[ec2]
[ssh_server_ip_addr]	ansible_user=ec2-user	ansible_ssh_private_key_file=/home/ec2-user/.ssh/[ssh_server_private_key]

hosts 파일에는 ansible이 프로비저닝할 대상 인프라 정보를 담으면 ansible이 실행할 때 해당 파일을 참조해 관련 프로세스(여기서는 playbook에 지정한 절차)를 진행하게 됩니다.

위의 내용 처럼 [ssh_server_ip_addr]에는 대상 서버의 ip address를 적으면 되고, ansible_user에는 대상 서버의 사용자를, ansible_ssh_private_key는 대상 서버의 private key를 지정하면 되는데 여기서는 AWS ec2 설정시 받았던 pem key file을 지정하면 됩니다. (저같은 경우 jenkins 서버 내의 사용자 디렉토리의 .ssh에다가 저장을 해두었습니다.)

이렇게 되면 ansible 실행시 ec2에 대해서는 해당 설정 내용들을 참조해 ssh 연결을 하게 됩니다.

그 다음 간단하게 대상 서버에 지시할 playbook을 만들어보겠습니다.

---
- name: Test Ansible
  hosts: ec2

  tasks:
    - name: Debug extra vars
      ansible.builtin.debug:
        msg: "{{ hello }}, {{ beanie }}"

엄청 간단하게 pipeline script에서 지정한 extraVars의 내용들을 출력해보는 작업을 만들어보았습니다.
위의 playbook은 yaml 파일 형식으로 만들어야 하고요. 경로는 역시 pipeline script에 지정한 ${WORKSPACE}/scripts/deploytest.yml 이름으로 파일을 만들면 됩니다.
참고로 jenkins에서 ${WORKSPACE}는 해당 jenkins item의 작업이 이루어지는 공간으로 쉽게 말해서 github repository의 root directory라고 생각하시면 됩니다.

위의 pipeline script에서 inventory, playbook 경로로 지정한 내용은 개발하시는 입장에서 관리하기 편한 곳에 임의로 설정하면 됩니다. 위 내용은 예시일 뿐입니다.

 

이렇게 하고 jenkins item을 빌드 실행해볼까요?

pipeline script에 설정한 stage들이 성공적으로 잘 수행된 것을 확인할 수 있습니다.
playbook에 설정한 debug부분에 extraVars로 지정한 변수값들이 잘 출력된 것을 확인할 수 있습니다.

 

📌 5. 정리

ansible을 적용하게된 이유부터 해서 제가 개인적으로 생각하는 장점에 대해서 언급해드렸는데요. 다른 생각을 가지신 분들도 많을 거라 생각합니다. 

그 이후에 Jenkins가 돌아가고 있는 서버에 ansible 패키지를 설치했고, Jenkins에 Ansible plugin 설치하고 관련 설정들을 작업하였습니다.

ansible-playbook에 대한 Jenkins pipeline script를 작성해보았고요. playbook과 ansible hosts 파일을 작성하였고 jenkins item 빌드를 통해 제가 테스트로 설정한 extraVars가 잘 출력된 것을 확인할 수 있었습니다.

ansible playbook에 대해서 정말 방대한 정보들을 담고 있는데요. 만약 playbook을 통해 다양한 방식으로 기능들을 적용해보고 싶으시다면 공식 document를 꼭 읽어보시는 것을 추천드립니다. https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html#playbook-syntax

 

Ansible playbooks — Ansible Documentation

A playbook runs in order from top to bottom. Within each play, tasks also run in order from top to bottom. Playbooks with multiple ‘plays’ can orchestrate multi-machine deployments, running one play on your webservers, then another play on your databas

docs.ansible.com

그리고 ansible + jenkins 적용된 제 개인 프로젝트 github repository 링크입니다.
https://github.com/beaniejoy/dongne-cafe-api

 

GitHub - beaniejoy/dongne-cafe-api: ☕️ kotlin & spring boot application (toy project) / siren order service fro local cafe

☕️ kotlin & spring boot application (toy project) / siren order service fro local cafe - GitHub - beaniejoy/dongne-cafe-api: ☕️ kotlin & spring boot application (toy project) / siren order ...

github.com

 

틀린 내용이 있을 수 있습니다~ 언제나 피드백 환영합니다!