[Ansible] #3.4.2 Ansible 기본 - 모듈 상세
Ansible
의 기본 구성 요소인 모듈
중 ping
, command
1. ping
ansible mgmt -m ping
모듈
을 사용한 명령문의 기본 정보에 대해서 알아보자.
위 명령어는 ping
이라는 모듈
을 mgmt
에 실행한 결과를 반환한다.
즉, 반환된 ansible_facts
, changed
, ping
등은 모두 return value
이다.
ansible mgmt -m ping -a 'data=xyz'
ping
모듈에 대해서 좀 더 보자면, 기본적으로 ping
이라는 프로토콜은 랜덤 문자를 보내고 그게 그대로 돌아오는지를 확인하는 매커니즘을 가지고있다. Ansible
에서의 ping
모듈은 기본적으로 ping
이라는 값을 보내서 pong
이라는 값이 오는지를 확인한다.
위 명령어는 이 pong
대신, xyz
라는 값을 반환하고, 확인하도록 변경하였다.
이러한 기능, 옵션 등을 Specification
이라고 하며, ansible-doc
에서 확인할 수 있다.
2. command
ansible-doc command
위 명령어로 command
에 대한 정보를 쭉 보다보면 다음과 같은 설명이 있다.
OPTIONS
항목에 대한 설명중 free_form
이라는 것이 있다.
자유형식이라는 뜻으로, 설명을 읽어보면 실행시킬 명령을 자유형식의 문자열로 넣으라고 안내되어있다.
또한 이는 실제 파라미터가 아니며, 단지 자유형식이라는 의미이다.
따라서 다음과 같이 자유롭게 명령을 옵션으로 넣을 수 있다.
ansible mgmt -m command -a 'id'
ansible mgmt -m command -a 'ls -l'
ansible mgmt -m command -a 'ps'
하지만 다음 명령문을 보자.
ansible mgmt -m command -a 'ps | grep python3'
실패한다.
일단 기본적으로 부모 프로세스
와 자식 프로세스
에 대한 이해가 필요하다.
부모 프로세스
는 bash
라고 생각하고, 자식 프로세스
는 bash
에서 ls
를 실행한다고 생각하자.
부모 프로세스
인 bash
는 실행중이고, bash
에서 ls
를 실행하려면 자식 프로세스
에게 fork()
를 하게 된다.
즉 메모리를 복사하게 된다.
그리고 부모 프로세스
는 자식 프로세스
가 종료할 때 까지 wait()
, 대기하게 된다.
그 동안 자식 프로세스
는 exec()
, 실행하게 된다.
여기서의 fork()
, wait()
, exec()
는 모두 C
함수들이다.
Linux
는 C
로 만들어져있기 때문이다.
자식 프로세스
에서의 ls
가 끝나게 되면, exit()
, 종료를 하게 되고 이때 return code
를 같이 전송을 시킨다.
기본적으로 return code
는 0
만이 정상 종료이고, 나머지 모든 값은 비정상 종료이다.
ls
echo $?
echo $?
의 결과값 0
이 방금 실행한 프로세스, ls
의 return code
이다.
ls -K
echo $?
이번에는 ls -K
에서 오류가 발생했다.
ls
에 -K
라는 옵션은 존재하지 않는다.
따라서 해당 프로세스는 비정상 종료하며, return code
로 2
를 반환했음을 알 수 있다. 2
가 무엇을 의미하는지는 다음을 통해 알 수 있다.
man ls
쭉 내리면, Exit status
에서 2
가 무엇을 의미하는지가 나온다.
이는 각 명령어마다 다 다르기 때문에 모든 명령어의 status
가 의미하는 자세한 바를 외우기는 힘드지만, 공통적으로 0
이 의미하는 바는 정상 종료이다.
다시 돌아와서, 그럼 다음의 명령어와 결과를 다시 보자.
ansible mgmt -m command -a 'ps | grep python3'
return code
1
, 즉 실패다.
이유는 간단하다.
우리는 앞서 command
가 쉘
을 사용하지 않는 모듈
이라는 것을 배웠다.
하지만 인자로 들어간 |
는 쉘
의 기능이므로, 오류가 발생한것이다.
다음의 명령과 비교해보자.
ansible mgmt -m shell -a 'ps | grep python3'
잘 실행된다.
3. copy
echo "hello" > hello.txt
cat hello.txt
ansible mgmt -m copy -a 'src=hello.txt dest=/tmp/hello.txt'
dest
는 원격지의 절대경로, src
는 로컬 상대경로, 절대경로 로 쓰면 된다.
참고로 ansible-doc
으로 copy
의 spec
을 보면, 다른 옵션은 앞에 -
가 붙어있지만 dest
는 앞에 =
이 붙어있다.
이는 mandatory
, 즉 필수 옵션이라는 뜻이다.
파일이 복사되었기 때문에, 변경 내역이 있으므로 “changed”
는 true
가 되고, 이는 상태가 계속 변하는 가변 인프라
임을 나타낸다.
ansible mgmt -m copy -a 'src=hello.txt dest=/tmp/hello.txt'
한 번 더 실행시, SUCCESS
라고 뜨지만 "changed"
는 false
이다.
즉 실행은 되었지만, 결론적으로 복사는 되지 않은것이다.
동일한 파일이 이미 존재하기 때문이다.
만약에 파일 내용을 바꾸고 명령을 실행하면, 파일이 달라졌기 때문에 복사가 된다 !
즉 파일의 "checksum"
으로 파일명 뿐만 아니라 내용까지도 감안해서 복사를 진행한다.
rm hello.txt
다음 실습을 위해 control1
노드에서 hello.txt
를 지운다.
4. fetch
ansible mgmt -m fetch -a 'src=/tmp/hello.txt dest=./'
ls
ls node1/tmp/hello.txt
fetch
는 가져옴을 뜻한다.
이 때 src
는 mgmt
가, dest
는 control1
이 될 것이다.
결과, control1
에 node1
이란 폴더가 생기게 되고, 여기 안에 디렉토리가 생기면서 파일을 가져오게 된다.
왜 이런식으로 fetch
가 이루어질까 ?
만약 우리가 대상 노드를 여러개를 지정한 경우, 즉 그룹을 대상으로 지정한 경우, 겹치게 되므로 노드마다 디렉토리를 만든 다음 그 안에 파일을 가져오게 된다.
rm -rf node1/
다음 실습을 위해 control1
노드에서 node1
을 지운다.
5. file
주로 파일을 생성하고, 속성을 변경할 때 사용한다.
path (필수)
file
모듈의 필수 아규먼트는path
이다.
path
라는 이름 대신에,dest
,name
으로 적어도 된다.stat
또stat
이라는 인자가 있다.
다음의 옵션 중에 하나를 선택해서 사용한다.- absent
- directory
- file (default)
- hard
- link
- touch
node1
에 있는 hello.txt
를 대상으로 file
모듈을 사용해보자.
생성 및 변경
ansible mgmt -m file -a 'path=/tmp/hello.txt'
여기서 state
에 주목해보자.
hello.txt
는 파일이기 때문에, file
이라고 표시된다.
대상이 디렉토리일 경우, directory
가 나온다.
ansible mgmt -m file -a 'path=/tmp state=file'
디렉토리를 대상으로 state
를 file
로 지정했기 때문에, fail이 나게 된다.
ansible mgmt -m file -a 'path=/tmp/hello1.txt state=touch'
state
를 touch
로 지정해주면, 대상 빈 파일을 만든다.
상태가 바뀌었기 때문에, CHANGED
가 나온다.
touch
가 아닌 directory
를 지정하면, 디렉토리를 생성한다.
ansible mgmt -m file -a 'path=/tmp/test state=directory mode=700 owner=root' -b
state
= directory
를 지정했기 때문에 디렉토리가 생성된다.
mode
= 700
으로 권한 변경도 가능하다.
owner
= root
로 소유자도 변경 가능하다. 단, root
로 변경할 때에는 관리자 권한이 필요하므로 -b
를 붙이지 않으면 오류가 발생한다.
삭제
ansible mgmt -m file -a 'path=/tmp/test state=absent' -b
state
를 absent
로 지정하면, 대상이 삭제된다.
absent
는 존재하지 않음을 뜻한다.
동일한 명령문을 다시 실행하면, SUCCESS
가 뜬다.
변경사항이 없고, 대상이 존재하지 않음은 참이기 때문이다.
위에서 생성했던 파일도 삭제해주자.
ansible mgmt -m file -a 'path=/tmp/hello.txt state=absent'
ansible mgmt -m file -a 'path=/tmp/hello1.txt state=absent'
6. apt
패키지를 설치할 때 사용하는 모듈이다.
- state
다음의 옵션에서 한 가지를 지정 가능하다.- absent (삭제)
- build-dep
- latest (설치)
- present (설치, default)
- fixed
apt
모듈을 사용하여 node1
에 apache2
를 설치해보자.
ansible mgmt -m apt -a 'name=apache2 state=present' -b
성공적으로 설치되었다.
한 번 더 실행하면, file
과 마찬가지로 이미 존재하며 변경사항이 없기 때문에 SUCCESS
가 출력된다.
ansible mgmt -m apt -a 'name=apache2 state=absent' -b
absent
를 지정하여 삭제.
7. service
name (필수)
- state
아래 항목 중 하나 선택- reloaded
- restarted
- started
- stopped
- (null) (default)
- enabled
ansible mgmt -m apt -a 'name=apache2 state=present' -b
ansible mgmt -m service -a 'name=apache2 enabled=false' -b
apt
로 apache2
를 다시 설치하고, service
모듈을 사용해보자.
기본적으로 관리자 권한이 필요하다.
enabled
를 false
로 지정하면, apache2
를 사용할 수 없게 된다.
disabled
를 확인할 수 있다.
다시 enabled
를 true
로 바꿔보자.
ansible mgmt -m service -a 'name=apache2 enabled=true state=started' -b
state
는 이미 started
이기 때문에, 이것만 실행하면 SCCUESS
가 출력되었을 것이고, 이번에는 enabled
를 true
바꾸었기 때문에 CHANGED
가 출력되었다.
8. replace
path (필수)
수정할 경로를 나타낸다.regexp (필수)
바꿀 텍스트를 정규화 표현식으로 나타낼 수 있다.replace
어떤 텍스트로 변경할지 지정한다.
echo "hello" > hello.txt
ansible mgmt -m copy -a 'src=hello.txt dest=/tmp/hello.txt'
hello.txt
파일을 만들고, node1
에 복사한다.
ansible mgmt -m replace -a 'path=/tmp/hello.txt regexp="hello" replace="hello world"'
이런식으로 파일의 내용을 수정할 수 있다.