본문 바로가기

DevOps/Ansible

[A101] 2. Ansible 기본사용(1)

cloudNet@ 팀의 가시다 님이 진행하는 앤서블 스터디 1주차 정리입니다.
# 이번 포스팅에서는 간단한 기능을 확인하기 위해 bash 명령을 입력해보고 앤서블의 기본 동작을 테스트 해보겠습니다.

 

지난번 포스팅 까지 앤서블 설치를 완료했습니다.

이번 게시물에서는 앤서블의 인벤토리,플레이북을 실습을 통해서  알아봅시다! 

 

 

  모듈

 

앤서블을 사용하는데 있어서 숙련자와 초보자의 차이는 얼마나 많은 모듈을 익숙하게 다루는지이다.

앤서블에는 수많은 모듈들이 존재하며, 해당 모듈을 사용하는 법들이 예제와 함께 잘 나와있지만

기본적으로 동작하는데 여러번 사용해보지 않으면 예상한대로 동작하지 않기도 한다.

따라서 모듈에 대한 익숙함이 굉장히 중요하다고 생각한다.


  • 앤서블의 모듈은  함수/클래스 와 같은 개념
  • 하나의 동작 단위
  • bash와의 차이점? 
그런데 bash 기반으로 작업을 할수 있는데 왜 모듈을 쓸까요?

  • 멱등성을 보장해 줍니다.
    1. 엔서블의 모든 작업을 실행하기전에 그 시점의 상태를 확인하고 변경이 있을때에만 실제의 작업을 수행하도록 설계 되어 있습니다.
    2. 중복 실행될 여지가 사전 차단됩니다.
    3. 쉘로 구현하기에는 너무 많은 조건문과, 부담이 있습니다.
  • 가독성이 좋습니다.
    1. 명확한 파라미터가 있어 쉘 명령어를 외울 필요가 없습니다
  • deploy 전에 테스트가 가능합니다
    1. 이 명령어가 수행되었을때 미리 상태를 짐작 가능합니다.
  • 리눅스 OS 간 호환성 보장이 됩니다.

  모듈 Example

ansible [all] -m (모듈)  

# -m 옵션은 실행할 모듈을 불러오는 옵션입니다.
# 모듈마다 필요한 인자값들이 다르기 때문에 그때 그때 확인하셔야 합니다.

 ping 모듈 

ansible all -m ping -k --user kpkim

 

copy 모듈

ansible [all] -m [copy] -a "src=~/test.txt dest-~/test.txt"

# host: all
# module: copy

src : 발원지
dest : 목적지

 

 

text 관련 모듈

 

기본적으로 linux OS에서는 echo 명령어와 sed 명령어 등을 이용해서 text 파일을 수정하고 관리하였는데,

앤서블에서는 이러한 기능들을 모듈로 제공하고 있습니다.

  • blockinfile   텍스트 블록 삽입/업데이트/제거
  • lineinfile  텍스트 파일의 행을 수정
  • replace  정규식을 사용하여 파일의 특정 문자열 인스턴스를 모두 바꿈
  1. blockinfile은 echo랑 비슷하지만 text 내용을 추가하는것입니다. 
  2. lineinfile은 한줄의 텍스트를 고치고 싶을때 사용하며 정규식등을 이용하여 고칠수 있습니다.
  3. replace는 여러줄의 텍스트를 고치고 싶을때 사용 합니다..
    1. 이때  (lineinfile) 모듈과 같은 방식으로  정규식을 사용해서 text를 분별합니다.

각각의 예제를 하나씩 사용해보겠습니다.

 

blockinfile 모듈

 

vi /my-ansible/blockinfile.yaml

- hosts: all
  tasks:
  - name: What is blockinfile
    blockinfile:
      path: /etc/hosts
      block: |
        172.10.0.115 kpkim.local
        172.10.0.166 hspark.local
      marker: "## {mark} ANSIBLE MANAGED BLOCK ##"
  • path: 수정할 파일의 경로
  • block:  
    • | 아래에 입력하는 내용을 block text를 insert하게 됩니다
  • marker: 위에 내용을 입력한 후에 그 아래줄에 주석으로 더 내용을 남기고 싶을때 사용합니다.

 

# ansible-playbook blockinfile.yaml
root@server:~/my-ansible# for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 3 /etc/hosts; echo; done
>> tnode1 <<
172.10.0.115 kpkim.local
172.10.0.166 hspark.local
## END ANSIBLE MANAGED BLOCK ##

>> tnode2 <<
172.10.0.115 kpkim.local
172.10.0.166 hspark.local
## END ANSIBLE MANAGED BLOCK ##

>> tnode3 <<
172.10.0.115 kpkim.local
172.10.0.166 hspark.local
## END ANSIBLE MANAGED BLOCK ##

 

 

lineinfile 모듈

vi /my-ansible/lineinfile.yaml

---

- hosts: all
  tasks:
  - name: Insert configuration block
    lineinfile:
      path: /etc/hosts
      line: "172.10.10.110 kpkim.vmc.local"
  • 위와 같이 같은 변경할 라인을 지정해주지 않으면 마지막줄에 라인을 입력합니다.
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i tail -n 3 /etc/hosts; echo; done
>> tnode1 <<
172.10.0.166 hspark.local
## END ANSIBLE MANAGED BLOCK ##
172.10.10.110 kpkim.vmc.local

>> tnode2 <<
172.10.0.166 hspark.local
## END ANSIBLE MANAGED BLOCK ##
172.10.10.110 kpkim.vmc.local

>> tnode3 <<
172.10.0.166 hspark.local
## END ANSIBLE MANAGED BLOCK ##
172.10.10.110 kpkim.vmc.local
  • 정규식을 통해 변경할 라인을 정해주는 식으로 해봅시다.
- name: Ensure SELinux is set to enforcing mode
  ansible.builtin.lineinfile:
    path: /etc/hosts
    regexp: '^172'
    line: kpkim.kuber.local
    
    

>> tnode3 <<
172.10.0.166 hspark.local
## END ANSIBLE MANAGED BLOCK ##
kpkim.kuber.local

 

replace 모듈

 

우선 기본적으로 replace 모듈은 정규식을 이용하여 구분하기 때문에 사용하기 쉽지 않습니다.

한가지만 예제를 통해서 알아보도록 하겠습니다.

 

- name: Replace between the expressions (requires Ansible >= 2.4)
  ansible.builtin.replace:
    path: /etc/hosts
    regexp: '(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}'
    replace: '172.10.10.10'

 

  • path: 어떤 text 파일을 고칠지 경로를 지정하는것이구요,
  • regexp: 이건 대체하고 싶은 text들을 특정할때 사용하는 정규표현식인데, 위 예제는 제가 ipv4 어드레스에 대한 정규표현식을 찾아논것이고, 모든 ipv4형태의 text들을 대상으로 작업하겠다는 내용입니다.
  • replace: 172.10.0.10 으로 대체 하겠다는 내용입니다.

 

 

✅  inventory란? 

$ ansible all -m ping -k --user root

 

앤서블 명령어는 동작을 실행할 user 를 항상 명시해야 하는 불편함이 있습니다.

이러한 유저를 관리하는 방법이 없다면 아래와 같이 올바르지 못한 방법으로 사용될수 있습니다.

  • 문서화를 하거나
  • history 명령어로 이력을 뒤져보거나
  • 기억에 의존하거나

그래서 몇가지 설정을 파일로 관리하고자 하는 요구사항이 있을수 있습니다.
이렇게 설정들을 관리하는 파일들을 인벤토리 (Inventory) 라고 합니다.
플레이북이 어떤 일의 설계서라면, 인벤토리는 그 일을 어디에 수행할지 라고 보시면 됩니다.

  인벤토리와 ansible.cfg


  • 먼저 실습을 위한 호스트를 등록 하는 인벤토리를 만들겠다.
  • inventory에는 타겟 대상들의 정보를 입력
  • ansible.cfg에는 default user와 인벤토리 위치등을 입력
  • ask_pass는 패스워드 입력을 받을것인가 항목
# inventory 그룹 구성
cat <<EOT > inventory
[web]
tnode1
tnode2

[db]
tnode3

[all:children]
web
db
EOT

# inventory 검증
ansible-inventory -i ./inventory --list | jq
ansible-inventory -i ./inventory --graph
cat ~/my-ansible/Easy-Ansible/chapter_05.1/ansible.cfg

[defaults]
inventory = ./inventory
remote_user = root
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

 

  인벤토리와 ansible.cfg가 적용된 module실행


위에서 인벤토리 없이 사용하던 코드를 아래와 같이 바꿀수 있다.

-u 는 ansible.cfg의 default user을 root로 설정해두었기 때문에 생략할수 있다.

# 인벤토리가 없을때 
ansible all -m ping -k --user kpkim

# 인벤토리가 있을때
ansible -m ping web

# 인벤토리가 있을때
ansible -m ping db