CentOS 7.6安裝使用Ansible(三):Ansible Playbook和變量類型

四、Ansible Playbooks

1、PlaybookYAMLJinja2簡介:

Playbook:包含Ansible指令的YAML格式的文件,#爲註釋,ansbile-playbook命令根據自上而下的順序依次執行。

YAMLYAML Ain't a Markup LanguageYAML不是一種標記語言)的遞歸縮寫。在開發這種語言時,YAML的意思其實是Yet Another Markup Language(仍是一種標記語言),但爲了強調這種語言以數據爲中心,而不是以標記語言爲中心,採用反向縮略語重命名。YAML的語法和其它高級語言類似,並且可以簡單表達清單、散列表、標量等數據形態。它使用空白符號縮進和大量依賴外觀的特色,特別適合用來表達或編輯數據結構、各種配置文件、傾印除錯內容、文件大綱。對於Ansible,每一個YAML文件都是從一個列表開始,列表中的每一項都是一個鍵值對,通常它們被稱爲一個“哈希”或“字典”。列表中的所有成員都開始於相同的縮進級別,並且使用一個“-”作爲開頭(一個橫槓和一個空格)。一個字典是由一個簡單的“鍵: 值”形式組成(冒號後必須是一個空格)。

Jinja2Python中被廣泛應用的模版引擎,它的設計思想來源於Django的模板引擎,並擴展了其語法和一系列強大的功能,包括:

(1)字面量:

Ø  字符串:使用單引號或雙引號

Ø  數字:整數、浮點數

Ø  列表:[item1, item2, ...]

Ø  元組:(item1, item2, ...)

Ø  字典:{key1:value1, key2:value2, ...}

Ø  布爾型:truefalse

(2)算術運算符:+-*///%**

(3)比較運算符:==!=>>=<<=

(4)邏輯運算符:andornot()

2、Playbook中的元素:

(1)hosts:執行指定任務的、定義在hosts文件中的被管控主機

192.168.1.144

[websrvs]

apache ansible_host=192.168.1.145

nginx ansible_host=192.168.1.220

備註:

Ø  如果定義了主機組名(websrvs)或主機別名(apachenginx),hosts可以使用組名或別名

Ø  如果只定義了IP地址(192.168.1.144),則hosts只能使用IP地址

(2)remote_user:在被管控主機上執行任務的用戶

(3)tasks:定義要在被管控主機上執行的任務列表

(4)handlers:可以把handler理解成另一種形式的taskhandler中的任務會被task中的任務進行調用,但是被調用並不意味着一定會執行,只有當task中的任務真正執行以後(真正的進行實際操作,造成了實際的改變),handler中被調用的任務纔會執行。如果task中的任務並沒有做出任何實際的操作,那麼handler中的任務即使被調用,也不會執行,另外handler執行的順序與handlerplaybook中定義的順序是相同的,與handlernotify的順序無關。默認情況下,所有task執行完畢後,纔會執行各個handler,並不是執行完某個task後,立即執行與其對應的handler

(5)vars:定義playbook運行時需要使用的變量

(6)templates:包含了模板語法的文件

(7)tags:用於讓用戶選擇運行或略過playbook中的部分代碼

3、ansible-playbook的使用格式:# ansible-playbook [options] playbook.yml [playbook2 ...]

[options]

Ø  -C:嘗試預測可能發生的一些變化,並不真正執行

Ø  -e 'EXTRA_VARS':設置key=value的自定義變量

Ø  --syntax-check:對playbook執行語法檢查,並不真正執行

Ø  --list-hosts:列出匹配的遠程主機列表,並不執行任何其它操作

Ø  --list-tags:列出所有可用標籤

Ø  --list-tasks:列出所有要執行的任務

Ø  -t TAGS:僅執行指定標籤標記的任務

Ø  --skip-tags 'SKIP_TAGS':僅執行與指定標籤不匹配的標記的任務

Ø  --start-at-task 'START_AT_TASK':從匹配指定標籤標記的任務開始執行

Ø  -f FORKS:指定一次批量管控多少臺主機,默認一批管控5臺主機

Ø  -u REMOTE_USER:以哪個用戶連接至被管控主機,默認爲None

Ø  -T TIMEOUT:連接至被管控主機的超時時長,默認10

Ø  --version:查看ansible主配置文件、ansible配置的模塊搜索路徑、ansible python模塊位置、可執行程序位置和python版本信息

Ø  -h:顯示幫助信息

4、playbook示例:所有被管控主機安裝memcached軟件包,啓動並實現開機自啓

# mkdir -pv /playbooks

# vim /playbooks/memcached.yml

- hosts: all

remote_user: root

tasks:

- name: install memcached

yum: name=memcached state=latest

- name: start memcached service

service: name=memcached state=started enabled=yes

# ansible-playbook --syntax-check /playbooks/memcached.yml

# ansible-playbook -C /playbooks/memcached.yml

# ansible-playbook /playbooks/memcached.yml


五、Ansible Variables

1、內置變量:

(1)hostvars:獲取被管控主機的主機變量信息

# ansible all -m debug -a 'msg={{hostvars}}'

(2)ansible_version:獲取ansible的版本號

# ansible all -m debug -a 'msg={{ansible_version}}'

# ansible all -m debug -a 'msg={{ansible_version.full}}'

(3)group_names:獲取當前被管控主機所在分組的組名

# ansible all -m debug -a 'msg={{group_names}}'

(4)groups:獲取主機清單中所有主機及主機組的分組信息

# ansible all -m debug -a 'msg={{groups}}'

# ansible all -m debug -a 'msg={{groups.websrvs}}'

備註:所有主機默認被分成了組名爲“all”的組,沒有分組的主機分到了名爲“ungrouped”的組,即組名爲“未分組”的組

(5)inventory_file:獲取主機清單文件存放的路徑和名稱

# ansible all -m debug -a 'msg={{inventory_file}}'

(6)inventory_hostname:獲取被管控主機的主機名,此處的主機名並非系統的主機名,而是對應主機在主機清單中配置的名稱

# ansible all -m debug -a 'msg={{inventory_hostname}}'

備註:如果使用IP配置主機,inventory_hostname返回的值就是IP,如果使用別名配置主機,返回的值就是別名

2、ansible_facts變量:

(1)ansible_distribution:獲取被管控主機的系統類型

(2)ansible_distribution_major_version:獲取被管控主機的系統主版本號

(3)ansible_hostname:獲取被管控主機的主機名

(4)ansible_os_family:獲取被管控主機的系統系列名稱

(5)ansible_pkg_mgr:獲取被管控主機的包管理器名稱

# vim /playbooks/facts.yml

- hosts: all

remote_user: root

tasks:

- name: show distribution

debug: msg={{ansible_distribution}}

- name: show distribution major version

debug: msg={{ansible_distribution_major_version}}

- name: show hostname

debug: msg={{ansible_hostname}}

- name: show os family

debug: msg={{ansible_os_family}}

- name: show package manager

debug: msg={{ansible_pkg_mgr}}

# ansible-playbook --syntax-check /playbooks/facts.yml

# ansible-playbook -C /playbooks/facts.yml

# ansible-playbook /playbooks/facts.yml

備註:

Ø  使用命令# ansible all -m setup | less查看到的所有ansible_facts變量

Ø  所有ansible_facts變量只能在playbook中使用,不能在ad-hoc中直接使用,會提示沒有定義

3、通過主機清單文件定義的主機及主機組變量:

# vim /etc/ansible/hosts

(1)主機變量:

192.168.1.144

[websrvs]

192.168.1.145 ansible_user=keyso ansible_ssh_pass=123456

192.168.1.220 ansible_user=keyso ansible_ssh_pass=123456

[dbsrvs]

146 ansible_host=192.168.1.146

[test:children]

websrvs

dbsrvs

備註:

Ø  定義了3個組,websrvsdbsrvstest組,且test組中包含了2個子組websrvsdbsrvs,當操作test組時就相當於操作了這2個子組中的所有主機

Ø  146 ansible_host=192.168.1.146146爲主機別名,配置了主機別名,IP前需要增加參數ansible_host

Ø  常用主機變量:

  ²  ansible_host:要遠程連接的主機IP

    ²  ansible_portSSH使用的端口號

  ²  ansible_userSSH連接時默認使用的用戶名

  ²  ansible_ssh_passSSH連接時的密碼

  ²  ansbile_sudo_pass:使用sudo連接用戶時的密碼

(2)主機組變量:

192.168.1.144

[websrvs]

192.168.1.145

192.168.1.220

[dbsrvs]

146 ansible_host=192.168.1.146

[test:children]

websrvs

dbsrvs

[websrvs:vars]

ansible_user=keyso

ansible_ssh_pass=123456

備註:在配置密鑰認證的情況下,無需配置ansible_useransible_ssh_pass兩個參數

4、通過ansible-playbook命令傳入變量:

# vim /playbooks/test.yml

- hosts: all

remote_user: root

tasks:

- name: command line variable

debug: msg={{cmdvar}}

# ansible-playbook --syntax-check -e cmdvar=hello /playbooks/test.yml

# ansible-playbook -C -e cmdvar=hello /playbooks/test.yml

# ansible-playbook -e cmdvar=hello /playbooks/test.yml

備註:命令行傳入的變量優先級最高

5、循環中的固定變量item

(1)示例:如果被管控主機是RedHat系列的系統,則安裝tomcatmemcachedvarnish三個軟件包:

# vim /playbooks/pkgs.yml

- hosts: all

remote_user: root

tasks:

- name: install packages

yum: name={{item}} state=latest

loop:

- tomcat

- memcached

- varnish

when: ansible_os_family=="RedHat"

# ansible-playbook --syntax-check /playbooks/pkgs.yml

# ansible-playbook -C /playbooks/pkgs.yml

# ansible-playbook /playbooks/pkgs.yml

備註:

Ø  循環:迭代,需要重複執行的任務。對迭代項的引用,固定變量名爲item,並在tasks中使用loop給定要迭代的元素列表。列表表示方式:字符串和字典。

Ø  when語句:在tasks中使用,表示條件判斷,如果符合條件,則執行,jinja2的語法格式

(2)示例:所有被管控主機按如下要求創建用戶組和用戶,並設置用戶系統登錄密碼

用戶user1,基本組group1,密碼111111

用戶user2,基本組group2,密碼222222

用戶user3,基本組group3,密碼333333

# vim /playbooks/addusers.yml

- hosts: all

remote_user: root

tasks:

- name: add groups

group: name={{item}} state=present

loop:

- group1

- group2

- group3

- name: add users

user: name={{item.user}} group={{item.group}} state=present

loop:

- {user: user1, group: group1}

- {user: user2, group: group2}

- {user: user3, group: group3}

- name: set password

shell: echo {{item.passwd}} | passwd --stdin {{item.user}}

loop:

- {passwd: 111111, user: user1}

- {passwd: 222222, user: user2}

- {passwd: 333333, user: user3}

# ansible-playbook --syntax-check /playbooks/addusers.yml

# ansible-playbook -C /playbooks/addusers.yml

# ansible-playbook /playbooks/addusers.yml

6、自定義變量:

(1)playbook中使用vars關鍵字定義變量

(2)playbook中使用set_fact模塊定義變量

(3)vars_files:將文件中的變量引入playbook,以便在task中使用

(4)include_vars:將文件中的變量動態引入playbook,以便在task中使用

# vim /playbooks/uservar.yml

- hosts: all

remote_user: root

vars:

- var1: test1

vars_files:

- /tmp/uservar.txt

tasks:

- name: show var1

debug: msg={{var1}}

- name: show var2

debug: msg={{var2}}

- name: set var3

set_fact: var3=test3

- name: show var3

debug: msg={{var3}}

- name: modify uservar file

shell: sed -i 's/var2/var4/g' /tmp/uservar.txt

- name: set var4

include_vars: /tmp/uservar.txt

- name: show var4

debug: msg={{var4}}

# cat /tmp/uservar.txt

var2: test2

# ansible-playbook --syntax-check /playbooks/uservar.yml

# ansible-playbook -C /playbooks/uservar.yml

# ansible-playbook /playbooks/uservar.yml

備註:

Ø  set_fact模塊定義的變量在其它playbook中也能被正常引用,但vars關鍵字定義的變量不行

Ø  在變量文件/tmp/uservar.txt中通過sed命令將var2替換成了變量var4include_vars模塊能夠重新加載變量文件,並動態的以任務的方式引用變量var4

Ø  變量文件/tmp/uservar.txt位於Ansible主機,與被管控主機無關

7、 綜合示例:

(1)如果被管控主機是CentOS 7.x系列的系統,則根據提供的模板文件redis.conf.j2安裝、配置並啓動redis

# vim /playbooks/redis.yml

- hosts: all

remote_user: root

tasks:

- name: install redis

yum: name=redis state=latest

- name: install configuration file

template: src=/playbooks/redis.conf.j2 dest=/etc/redis.conf owner=redis group=root mode=0640 backup=yes

when: ansible_distribution=="CentOS" and ansible_distribution_major_version=="7"

notify: restart redis service

tags: redis configuration file

- name: start redis service

service: name=redis state=started enabled=yes

handlers:

- name: restart redis service

service: name=redis state=restarted

# cat /playbooks/redis.conf.j2

bind {{ansible_host}}

requirepass keyso0728

# ansible-playbook --syntax-check /playbooks/redis.yml

# ansible-playbook -C /playbooks/redis.yml

# ansible-playbook /playbooks/redis.yml

備註:

Ø  Ansible節點中先安裝redis,提取redis.conf,並修改爲模板文件

Ø  CentOS 7.6CentOS 6.10redis.conf原始配置文件內容一致

Ø  redis啓動後監聽的端口爲6379

Ø  修改模板文件redis.conf.j2中的內容,然後將模板文件複製至被管控節點,重啓redis生效,可以執行命令:# ansible-playbook -t 'redis configuration file' /playbooks/redis.yml

(2)安全加固後的被管控主機不允許直接以root用戶身份登錄,需要通過普通用戶testuser連接至被管控主機,然後suroot用戶,執行那些需要root用戶權限才能執行的命令

# vim /etc/ansible/hosts

192.168.1.144

[websrvs]

192.168.1.145

192.168.1.220

[dbsrvs]

146 ansible_host=192.168.1.146

[test:children]

websrvs

dbsrvs

# ansible all -a 'whoami' --> root用戶

# ansible all -m user -a 'name=testuser state=present'

# ansible all -m shell -a 'echo 123456 | passwd --stdin testuser'

禁止root用戶直接登錄遠程被管控主機:

# ansible all -m lineinfile -a 'path=/etc/ssh/sshd_config regexp="^#PermitRootLogin yes" line="PermitRootLogin no" state=present backup=yes'

# ansible all -m service -a 'name=sshd state=restarted'

再使用root用戶連接至被管控節點會報錯

# vim /etc/ansible/hosts

192.168.1.144

[websrvs]

192.168.1.145

192.168.1.220

[dbsrvs]

146 ansible_host=192.168.1.146

[test:children]

websrvs

dbsrvs

[websrvs:vars]

ansible_user=testuser

ansible_ssh_pass=123456

ansible_become_pass=hellolinux

備註:

Ø  ansible_user:定義普通用戶名稱

Ø  ansible_ssh_pass:定義普通用戶密碼

Ø  ansible_become_pass:定義切換root用戶時需要的登錄密碼

# ansible all -a 'whoami' --> testuser用戶

嘗試以testuser用戶身份在每臺被管控主機的/root目錄下創建a.txt文件,結果Permission denied

# ansible all -m file -a 'content= path=/root/a.txt state=touch'

# ansible all --become-method su -b -a 'whoami' --> root用戶

備註:

Ø  --become-method:將權限提升的方式設置爲su,默認爲sudo

Ø  -b:使用become執行操作(不提示密碼輸入)

# ansible all --become-method su -b -m file -a 'content= path=/root/a.txt state=touch'


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章