IaC(Infrastructure as Code)

Ansible Part. 3 (Playbook)

cwchoiit 2024. 3. 18. 09:14
728x90
반응형
SMALL
728x90
SMALL

Playbook

Ansible로 무언가를 실행하고 작업할 때 여러 방법이 있다고 했는데 그 중 Adhoc 방법을 다뤄봤고 이번에 다룰 내용이 Playbook이다.

Playbook은 YAML 파일로 되어있는데 하나씩 뜯어보자.

 

우선 디렉토리 구조는 다음과 같다.

 

Inventory

이 파일은 저번 포스팅에서 다룬 인벤토리 관련 파일이다. 이번에는 딱 하나의 파일만 존재한다.

[amazon]
amazon1 ansible_host=54.180.201.128 ansible_user=ec2-user 
amazon2 ansible_host=13.124.98.155 ansible_user=ec2-user

[ubuntu]
ubuntu1 ansible_host=ec2-43-203-218-29.ap-northeast-2.compute.amazonaws.com ansible_user=ubuntu
ubuntu2 ansible_host=ec2-3-38-149-203.ap-northeast-2.compute.amazonaws.com ansible_user=ubuntu

[linux:children]
amazon
ubuntu

 

syntax.yaml

이 파일을 통해 Playbook이 어떻게 생겼는지 알아보자.

---
# This is Ansible Playbook

# Playbook: YAML로 정의. 순서대로 정렬된 플레이(작업 목록: Play) 절차.
# Play: 작업 목록(Tasks). 특정 호스트 목록에 대하여 수행
# Task: Ansible의 수행 단위. 애드혹 명령어는 한번에 단일 작업 수행.
# Module: Ansible이 실행하는 코드 단위. 작업에서 모듈을 호출함.
# Collection: 모듈의 집합.

- name: Play 1
  hosts: ubuntu
  tasks:
    - name: "Task 1: Execute command"
      command: uptime

    - name: "Task 2: Execute script"
      script: task2.sh
    
    - name: "Task 3: Install package"
      apt:
        name: nginx
        state: present
        update_cache: true

    - name: "Task 4: Start nginx service"
      service:
        name: nginx
        state: started

- name: Play 2
  hosts: localhost
  tasks:
    - name: "Task 1: Execute command"
      command: whoami

    - name: "Task 2: Execute script"
      script: task2.sh

우선, Playbook은 YAML 파일 자체라고 보면 된다. 그래서 순서대로 정의한 Play 절차를 의미하고 이 Play는 코드에서 Tasks라고 생각하면 된다. Play는 특정 호스트 목록(그룹)에 대하여 Tasks를 수행한다. Task 하나 하나는 Ansible의 수행 단위이다. Adhoc을 사용했을 땐 한번에 하나씩 수행했지만 여기선, 여러개를 tasks라는 키에 정의하여 사용가능하다. Module은 Ansible이 실행하는 코드 단위이다. 저번 포스팅에서 배운 command, ping 이런것들도 다 모듈이다.

 

install-nginx.yaml

이 파일이 실제로 Playbook을 사용해보는 첫 YAML 파일이 될 것이다. 각 호스트 그룹 Ubuntu와 Amazon에 대해서 Nginx를 설치하는 작업을 한다. 그래서 글로벌로 패키지를 설치하려면 루트 권한이 필요하기 때문에 become: true 값이 있음을 알 수 있고, Ubuntu에 대해서는 Nginx를 설치하는 Task 하나와 설치한 Nginx를 서비스로 실행하는 Task 하나가 있다. Amazon도 같은 Task가 있지만 그 전에 패키지 매니저인 amazon-linux-extras를 먼저 Enable하는 Task가 추가로 있음을 확인할 수 있다. 

---

- name: Install Nginx on Ubuntu
  hosts: ubuntu
  become: true
  tasks:
  - name: "Install Nginx"
    apt:
      name: nginx
      state: present
      update_cache: true

  - name: "Ensure nginx service started"
    service:
      name: nginx
      state: started

- name: Install Nginx on Amazon Linux
  hosts: amazon
  become: true
  tasks:
  - name: "Enable Nginx repository provided by Amazon"
    command: "amazon-linux-extras enable nginx1"

  - name: "Install Nginx"
    yum:
      name: nginx
      state: present

  - name: "Ensure nginx service started"
    service:
      name: nginx
      state: started

 

uninstall-nginx.yaml

이번엔 Uninstall이다. 그러다보니 먼저 서비스를 중지하는 Task가 먼저 나온다. 그리고 absent라는 state를 주어 해당 패키지를 삭제한다. Amazon은 거기에 더불어 Repository를 Disable하는 작업도 있다. 

---

- name: Uninstall Nginx on Ubuntu
  hosts: ubuntu
  become: true
  tasks:
  - name: "Ensure nginx service stopped"
    service:
      name: nginx
      state: stopped

  - name: "Uninstall Nginx"
    apt:
      name: nginx
      state: absent

- name: Uninstall Nginx on Amazon Linux
  hosts: amazon
  become: true
  tasks:
  - name: "Ensure nginx service stopped"
    service:
      name: nginx
      state: stopped

  - name: "Uninstall Nginx"
    yum:
      name: nginx
      state: absent

  - name: "Disable Nginx repository provided by Amazon"
    command: "amazon-linux-extras disable nginx1"

Playbook 실행 (Install Nginx)

이제 다음 명령어를 수행해보자.

ansible-playbook -i inventory install-nginx.yaml

 

이번엔 ansible-playbook이라는 명령어를 사용한다. 그래서 인벤토리를 지정하고 Playbook을 지정하면 인벤토리에 존재하는 호스트들에 대해 install-nginx.yaml 파일을 수행하라는 의미가 된다.

 

결과는 다음과 같다. (아래 사진과 백퍼센트 동일하지 않을 수 있다. ok, changed에 대해서)

 

위에서 부터 하나씩 살펴보자. 우선 순서대로 실행된다고 했기 때문에 먼저 작성한 Ubuntu에 대해서 실행을 먼저 한 모습이다.

Gathering Facts는 기본으로 실행되는 작업이다. Facts는 상세라고 표현하는데 리모트 호스트에 대한 정보를 수집하는 과정이라고 생각하면 된다.

 

그리고 Install Nginx를 실행한다. 여기서 어떤것은 ok고 어떤것은 changed라고 되어 있다. 이게 어떤 차이냐면, ok는 설치가 되어 있는 경우에 다시 설치할 필요가 없고 그 말은 변경 사항이 없다는 것을 의미하므로 OK로 표현한다. 그러나 Changed는 없던 패키지가 설치가 됐기 때문에 변경사항이 이 리모트 호스트에 있다라고 말해주기 위해 Changed로 표현한다. 그래서 같은 Playbook을 연속해서 실행하더라도 불필요하게 패키지를 계속 설치하지 않게 Ansible이 이미 이 Task를 충족하는지 확인한다. 이를 '멱등성'이라고 표현하는데 Ansible은 멱등성을 보장한다. 그리고 Service 모듈을 통해 Nginx가 실행됐는지 확인 후 실행하지 않았다면 실행하는데, Ubuntu에서는 Nginx를 설치하면 기본으로 실행을 한다. 그래서 OK로 표현한다. Amazon 부분도 같은 맥락으로 보면 될 것 같다. 

 

이제 요약부분이 마지막에 나온다. 전부 문제 없이 원하는 작업을 수행했고, 그렇지 않았다면 unreachable, failed, skipped, ignored 중 하나가 표시된다. 여기서 amazon1에 대해서만 살펴보면 OK가 총 4개고 그 중 Changed가 1개가 있다라고 생각하면 된다. OK 4개에 Changed 1개가 아니라. 

 

그리고 위에서 멱등성을 보장한다고 했다. 진짜 그런지 확인해보려면 다시 한번 실행해보면 된다. 다시 실행해보면 전부 다 OK로 나올것이다. 

전부 다 OK로 나올것을 예상했지만 딱 한군데, Amazon에서 Enable Repository 작업이 Changed가 됐다. 이는 왜 그러냐면 기본적으로 Command라는 모듈은 멱등성을 보장하지 않는다. 그도 그럴것이 커맨드를 실행하지 않은 상태에서 실행을 하는데 멱등성이란 게 있을 수가 없다. 그래서 저 부분만 Changed고 설치나 설치 후 실행 작업은 모두 이미 충족된 상태임을 알려주는 OK가 표시됐다.

 

Adhoc으로 Playbook 정상 수행 확인

Nginx를 설치했으면 잘 설치가 됐는지 확인해보자. 다음 명령어로 간단하게 확인이 가능하다.

ansible -i inventory amazon -m command -a "curl localhost"

 

인벤토리 파일에 작성된 호스트들 중 Amazon이라는 그룹에 대해서 Command 모듈을 수행하는데 localhost:80에 요청을 날리는 작업을 수행하는 것이다. Nginx가 설치됐다면 기본으로 80 포트에 Nginx 서버가 호스팅된다. 실행해보면 Nginx 기본 페이지가 보여짐을 알 수 있다.

 

 

Playbook 실행 (Uninstall Nginx)

이제 Nginx를 Uninstall 해보자. 미리 만들어둔 uninstall-nginx.yaml 파일로 Playbook을 실행하면 된다. 잘 수행됐다. 예상대로 OK와 Changed가 나올곳에 딱딱 나왔다.

 

이제 실제로 잘 삭제됐는지 확인하기 위해 같은 CURL을 수행해보자.

ansible -i inventory [amazon|ubuntu] -m command -a "curl localhost"

 

정상 응답을 받지 못하는 것을 확인할 수 있다.

 

728x90
반응형
LIST

'IaC(Infrastructure as Code)' 카테고리의 다른 글

Ansible Part. 5 (Variables)  (0) 2024.03.18
Ansible Part. 4 (Handler)  (0) 2024.03.18
Ansible Part. 2 (Adhoc)  (3) 2024.03.17
Ansible Part. 1 (Inventory)  (3) 2024.03.17
Packer Part. 5 (Post Processor)  (2) 2024.03.15