공식문서:https://docs.ansible.com/ansible/latest
멱등성이란?
멱등성이란 여러번 수행해도 같은 결과를 뱉는 성질을 말합니다.
앤서블은 YAML로 관리되는 명령집을 여러번 수행하더라도 언제나 같은 결과가 나올 수 있도록 여러가지 관리를 합니다.
인벤토리(Inventory)
test.inv 따로 확장자 명이 없기때문에 편한 네임 사용
[test]
192.168.1.1
192.168.1.2
[alias]
test1 ansible_host=192.168.1.1
test2 ansible_host=192.168.1.2
[vars]
test1 ansible_host=192.168.1.1 ansible_user=centos
test2 ansible_host=192.168.1.2 ansible_user=centos
애드혹 명령어(Ad-hoc Command)
#순서는 지킬필요는 없다.
ansible [그룹명] -m[모듈] [-a 모듈 옵션] -i[인벤토리 지정]
ansible -i test.ivh -m ping test
ansible -i test.ivh -m command -a "uptime" test #해당 커맨드 명령어 실행
ansible localhost -m setup #리무트 호스트 정보수집
ansible -i test.ivh -m yum -a "name=git state=latest update_cache=yes" test --become #git 설치 및 --become 옵션을 사용하요 root 계정 변환 후 설치 진행
ansible -i test.ivh -m yum -a "name=git state=absent update_cache=yes" test --become #git 삭제
플레이북(Playbook)
yaml 문법으로 스크립트 처럼 작성하여 팀원 간 공유 및 코드 재사용
---
# This is Ansible Playbook
#
# 플레이북 (Playbook): YAML로 정의. 순서대로 정렬된 플레이(작업 목록) 절차.
# 플레이 (Play): 작업 목록(Tasks). 특정 호스트 목록에 대하여 수행
# 작업 (Task): 앤서블의 수행 단위. 애드혹 명령어는 한 번에 단일 작업 수행.
# 모듈 (Module): 앤서블이 실행하는 코드 단위. 작업에서 모듈을 호출함.
# 콜렉션 (Collection): 모듈의 집합.
- name: Play 1
hosts: centos
become: true #루트 권한으로 실행
tasks:
- name: "Task 1: Execute command"
command: uptime
- name: "Task 2: Execute script"
script: task2.sh
- name: "Task 3: Install package"
yum:
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
ansible-playbook -i[인벤토리 지정] [playbook-yaml 파일지정]
ansible-playbook -i test.ivn test.yaml
모듈(Module)
---
- name: Example
hosts: centos
become: true
tasks:
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html
- name: "Create a user"
user: "name=test shell=/bin/bash" #사용자관리 모듈
- name: "Hello World"
command: "echo 'Hello World!'"
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html
- name: "Add DNS server to resolv.conf"
lineinfile: #설정 파일 확인해서 해당라인이 있는지 확인 후 없으면 추가
path: /etc/resolv.conf
line: 'nameserver 8.8.8.8'
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html
- name: "Install Nginx"
yum:
name: nginx
state: present
update_cache: true
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/posix/synchronize_module.html
- name: "Upload web directory"
synchronize: #싱크 동기화 모듈 rsync 랑 유사하다
src: files/html/
dest: /var/www/html
archive: true
checksum: true
recursive: true
delete: true
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html
- name: "Copy nginx configuration file"
copy:
src: files/default
dest: /etc/nginx/sites-enabled/default
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/service_module.html
- name: "Ensure nginx service started"
service:
name: nginx
state: started
핸들러
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html
- name: "Copy nginx configuration file"
copy:
src: files/default
dest: /etc/nginx/sites-enabled/default
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
notify:
- Restart Nginx
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/service_module.html
- name: "Ensure nginx service started"
service:
name: nginx
state: started
handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted
변수(Variables)
---
#vars1
- name: Example
hosts: centos
become: true
vars:
user_name: "test"
user_comment: "from playbook vars"
user_shell: /bin/bash
user_uid: "7777"
tasks:
- name: "Create a user"
user:
name: "{{ user_name }}"
comment: "{{ user_comment }}"
shell: "{{ user_shell }}"
uid: "{{ user_uid }}"
#vars2
# vars.yaml 파일을 vars1 변수처럼 지정하여 파일로 관리한다
---
- name: Example
hosts: centos
become: true
vars_files:
- vars.yaml
tasks:
- name: "Create a user"
user:
name: "{{ user_name }}"
comment: "{{ user_comment }}"
shell: "{{ user_shell }}"
uid: "{{ user_uid }}"
반복문(loops)
tasks: #with_items 방식
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/group_module.html
- name: "Create groups"
group:
name: "{{ item }}"
state: "present"
with_items:
- backend
- frontend
- devops
---------------------------------------------------------------
tasks: #loop 방식
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html
- name: "Create a user"
user:
name: "{{ item }}"
comment: "test"
state: "test"
loop:
- john
- alice
- claud
---------------------------------------------------------------
반복하기 위해 변수 users 추가한다
- name: Example
hosts: centos
become: true
vars:
tags:
Name: "Debug"
Environment: "Test"
Owner: "test"
users:
- john
- alice
- claud
- name: "Create a user"
user:
name: "{{ item }}"
comment: "test"
state: "present"
loop: "{{ users }}"
---------------------------------------------------------------
---
- name: Example
hosts: centos
become: true
vars:
tags:
Name: "Debug"
Environment: "Test"
Owner: "test"
users:
- name: john
shell: /bin/bash
- name: alice
shell: /bin/sh
- name: claud
shell: /bin/bash
- name: henry
shell: /bin/sh
- name: jeremy
shell: /bin/bash
- name: may
shell: /bin/sh
tasks:
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html
- name: "Create a user"
user:
name: "{{ item.name }}"
shell: "{{ item.shell }}"
comment: "test"
state: "present"
loop: "{{ users }}"
- name: "Debug data"
debug:
msg: "{{ item.key }}: {{ item.value }}"
loop: "{{ tags | dict2items }}"
조건문(Conditionals)
---
- name: Example
hosts: all
become: true
vars:
users:
- name: john
shell: /bin/bash
enabled: true
- name: alice
shell: /bin/sh
enabled: false
- name: claud
shell: /bin/bash
enabled: true
- name: henry
shell: /bin/sh
enabled: false
- name: jeremy
shell: /bin/bash
enabled: true
- name: may
shell: /bin/sh
enabled: false
tasks:
# Docs: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html
- name: "Create a user if enabled in Amazon Linux"
user:
name: "{{ item.name }}"
shell: "{{ item.shell }}"
comment: "test"
state: "present"
loop: "{{ users }}"
when: item.enabled and (ansible_facts["distribution"] == "Amazon")
- name: "Show items between 10 and 100"
debug:
var: item
loop: [ 0, 192, 154, 456, 7, 2, -1, 55, 234]
when:
- item >= 10
- item <= 100
---------------------------------------------------------------
- name: "Show items not between 10 and 100"
debug:
var: item
loop: [ 0, 192, 154, 456, 7, 2, -1, 55, 234]
when:
- (item < 10) or (item > 100)
- name: "Install Packages on Ubuntu"
apt:
name: "{{ item }}"
update_cache: true
state: "present"
loop:
- git
- curl
- htop
when:
- ansible_facts['distribution'] == 'Ubuntu'
---------------------------------------------------------------
- name: "Install Packages on Amazon Linux"
yum:
name: "{{ item }}"
state: "present"
loop:
- git
- curl
- htop
when:
- ansible_facts['distribution'] == 'Amazon'
---------------------------------------------------------------
- name: "Print users"
#앞에있는 컬럼내용(유저정보) 만 가져온다
command: "cut -d: -f1 /etc/passwd"
register: users # 가져온 정보를 users 변수에 등록
- name: "Is there claud"
debug:
msg: "There is no claud"
#유저정보에서 (claud) 찾는다 없어면 -1 리턴하여 msg 메세지 출력
when: users.stdout.find('claud') == -1
ansible facts(상세)
#facts 란?
원격서버 등에 대해서 운영체제 정보, IP정보, 파일시스템를 가져온다
기본적으로 정보를 가져오나 대규모 시스템 관리시 성능향상을 위해 끄기도 한다.
gather_facts: false
기타
ansible ssh 장애
"Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)
ansible 서버의 ~/.ssh/id_rsa.pub 값을 에러가난 원격지 서버의 ~/.ssh/authorized_keys 파일에 저장한다
ansible -i <inv> -m ping all -vvv 통해 애러부분확인
ex:) STABLISH SSH CONNECTION FOR USER: None
user 가 지정되지 않았음으로 인벤토리에 "ansible_host=centos" 등록이 필요하다
~/.ssh/authorized_keys 파일 권한이 600, 소유권확인
명령어 실행자 확인(root, user)
ansible ssh 장애2
playbook error : SSH password instand of ... 해결방법
ansible을 인벤토리 설정 후 playbook실행 시 ssh host key에러가 발생되는 경우가 있다.
이 부분은 처음 접속하기 때문에 fingerprint접속오류라고 할수 있다.
이때는 아래와 같이 해결하길 바란다.
*환경변수 지정
export ANSIBLE_HOST_KEY_CHECKING=False
* ansible.cfg 설정
~/.ansible.cfg
[defaults]
host_key_checking = False
*ansible.cfg 생성
ansible-config init --disabled > ansible.cfg
장애3
become 모듈과 connection: local 같이 사용시 "sudo: a password is required\n", "module_stdout" 에러가난다
처음엔 폴더를 만들어야된다는 생각에 become 모듈을 추가하였는데 생각해보니 폴더가 root 로 만들어져서 어차피 사용자 계정에서
파일 복사나 다른것들이 안됐다. 결론은 become 을 빼고 진행하니 정상 작동한다.