Ansible之playbook拓展

  1、handlers和notify結合使用觸發條件html

  handlers同tasks是屬同級,至關於一個特殊任務列表,這些任務同前文說的tasks裏的任務沒有本質的不一樣,用於當關注的資源發生變化時,纔會採起必定的操做。notify此action可用於在每個play的最後被觸發,這樣可避免屢次有改變發生時都執行指定的操做,僅在全部的變化發生完成後一次性地執行指定操做,在notify中列出的操做稱爲handler,換句話說當所關注的資源發生變化時notify將調用handlers中定義的操做。其中notify所在任務就是被監控的任務資源變化的任務,notify能夠調用多個handlers定義的操做,一個handlers裏能夠定義不少任務。node

---
- hosts: websers
  remote_user: root

  tasks:
    - name: create apache group
      group: name=apache gid=80 system=yes
    - name: create apache user
      user: name=apache uid=80 group=apache system=yes shell=/sbin/nologin home=/var/www/html 
    - name: install httpd
      yum: name=httpd
    - name: copy config file
      copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd service

    - name: start httpd service
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd service
      service: name=httpd state=restarted

  說明:notify後指定的名稱必需要和handlers裏的任務名稱相同,如不一樣handlers所定義的任務將不會執行,至關於沒有notify調用handlers裏的任務。python

  在某些狀況下,咱們可能同時須要調用多個handlers,或者須要使用handlers其餘handlers,ansible能夠很簡單的實現這些功能,以下所示nginx

  1)調用多個handlersweb

---
- hosts: websers
  remote_user: root

  tasks:
    - name: create apache group
      group: name=apache gid=80 system=yes
    - name: create apache user
      user: name=apache uid=80 group=apache system=yes shell=/sbin/nologin home=/var/www/html 
    - name: install httpd
      yum: name=httpd
    - name: copy config file
      copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
      notify: 
        - restart httpd service
        - check httpd process

    - name: start httpd service
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd service
      service: name=httpd state=restarted
    - name: check httpd process                                                                                      
      shell: /usr/bin/killall -0 httpd &> /tmp/httpd.log

  說明:調用多個handlers咱們須要在notify中寫成列表的形式,一樣咱們被觸發的任務名稱須要同handlers裏的被調用的任務名稱徹底相同shell

  2)handlers調用handlersapache

---
- hosts: websers
  remote_user: root

  tasks:
    - name: create apache group
      group: name=apache gid=80 system=yes
    - name: create apache user
      user: name=apache uid=80 group=apache system=yes shell=/sbin/nologin home=/var/www/html 
    - name: install httpd
      yum: name=httpd
    - name: copy config file
      copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd service

    - name: start httpd service
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd service
      service: name=httpd state=restarted
      notify: check httpd process                                                                                    
    - name: check httpd process
      shell: /usr/bin/killall -0 httpd &> /tmp/httpd.log

  說明:handlers調用handlers,則直接在handlers中使用notify選項就能夠。數組

在使用handlers咱們須要注意一下幾點:bash

  1)handlers只有在其所在任務被執行時纔會被運行,handlers定義的任務它不會像task任務那樣,自動會從上至下依次執行,它只會被notify所在的任務發生狀態改變時纔會觸發handlers 的任務執行,若是一個任務中定義了notify調用handlers,但因爲條件的判斷等緣由,該任務還沒有執行,那麼notify調用的handlers一樣也不會執行。app

  2)handlers只會在play的末尾運行一次;若是想要在一個playbook的中間運行handlers,則須要使用meta模塊來實現,如:-mate: flush_handlers

  2、playbook中變量的使用

ansible中變量的命名規範同其餘語言或系統中變量命名規則很是相似。變量名以英文大小寫字母開頭,中間能夠包含下劃線和數字,ansible變量的來源有不少,具體有如下幾點:

  1)ansible setup模塊,這個模塊能夠從遠程主機上獲取不少遠程主機的基本信息,它所返回的全部變量均可以直接調用,有關setup說明請參考本人博客http://www.javashuo.com/article/p-ppxguweq-gt.html

  2)在/etc/ansible/hosts中定義,此文件是ansible執行名時默認加載的主機清單文件,在裏面除了可定義咱們要管理的主機外,咱們還能夠定義針對單個主機定義單獨的變量,咱們把針對單獨某一臺主機定義的變量叫作普通變量(也可叫作主機變量);還有一種變量它不是針對單獨一個主機,它針對某一個組裏的全部主機,咱們把這種變量叫作公共組變量。主機清單中定義的變量優先級是普通變量高於公共變量。

    2.1)主機變量,能夠在主機清單中定義主機時爲其添加主機變量以便於在playbook中使用,以下所示

[websers]
192.168.0.128 http_port=80 maxRequestsPerChild=808
192.168.0.218 http_port=81 maxRequestsPerChild=909

    2.2)主機組變量,組變量是指定賦予給指定組內全部主機上的在playbook中可以使用的變量,以下所示

[websers]
192.168.0.128 http_port=80 
192.168.0.218 http_port=81 
[websers:vars]
maxRequestsPerChild=909

  3)經過命令行指定變量(-e指定變量賦值,能夠說多個但須要用引號引發或者一個變量用一個-e指定賦值),這種在命令行指定的優先級最高。以下所示

ansible-playbook -e 'package_name1=httpd package_name2=nginx' test_vars.yml

  4)在playbook中定義變量,最多見的定義變量的方法是使用vars代碼塊,以下所示

---
- hosts: websers
  remote_user: root
  vars:
    - abc: xxx 
    - bcd: aaa

  5)在獨立的變量yml文件中定義,在playbook中使用vars_files代碼塊引用其變量文件,以下所示

[root@test ~]#cat vars.yml 
---
package_name1: vsftpd
package_name2: nginx
[root@test ~]#cat test_vars.yml 
---
- hosts: websers
  remote_user: root
  vars_files:
    - vars.yml
  tasks:
    - name: install package1
      yum: name={{ package_name1 }}
    - name: install package2
      yum: name={{ package_name2 }}
[root@test ~]#

  6)在role中定義,這個後續說到角色在作解釋

  變量的調用方式:第一種在playbook中使用變量須要用「{{}}」將變量括起來,表示括號裏的內容是一個變量,有時用「{{  variable_name }}"才生效;第二種是ansible-playbook -e 選項指定其變量,ansible-playbook -e "hosts=www user=xxxx" test.yml

  在主機清單中定義變量的方法雖然簡單直觀,可是當所須要定義的變量有不少時,而且被多臺主機使用時,這種方法顯得很是麻煩,事實上ansible的官方手冊中也不建議咱們把變量直接定義到hosts文件中;在執行ansible命令時,ansible會默認會從/etc/ansible/host_vars/和/etc/ansible/group_vars/兩個目錄下讀取變量定義文件,若是/etc/ansible/下沒有以上這兩個目錄,咱們能夠手動建立,而且能夠在這兩個目錄下建立與hosts文件中的主機名或主機組同名的文件來定義變量。好比咱們要給192.168.0.218 這個主機定義個變量文件,咱們能夠在/etc/ansible/host_vars/目錄下建立一個192.168.0.218的空白文件,而後在文件中以ymal語法來定義所需變量便可。以下所示

[root@test ~]#tail -6 /etc/ansible/hosts 
## db-[99:101]-node.example.com
[websers]
192.168.0.128 
192.168.0.218 
[appsers]
192.168.0.217
[root@test ~]#cat /etc/ansible/host_vars/192.168.0.218 
---
file1: abc
file2: bcd
[root@test ~]#cat test.yml 
---
- hosts: 192.168.0.218
  remote_user: root
  
  tasks:
    - name: touch file1
      file: name={{ file1 }} state=touch
    - name: toch file2
      file: name={{ file2 }} state=touch
[root@test ~]#ansible-playbook test.yml 

PLAY [192.168.0.218] ************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.218]

TASK [touch file1] **************************************************************************************************
changed: [192.168.0.218]

TASK [toch file2] ***************************************************************************************************
changed: [192.168.0.218]

PLAY RECAP **********************************************************************************************************
192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   

[root@test ~]#ansible 192.168.0.218 -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
總用量 12
-rw-r--r--. 1 root   root    0 11月 17 16:49 abc
-rw-r--r--. 1 root   root    0 11月 17 16:49 bcd
drwxr-xr-x. 2 qiuhom root 4096 11月 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 11月 11 19:28 test
-rw-r--r--. 1 root   root   57 11月 13 19:15 test_cron_file

[root@test ~]#

  說明:可看到咱們定義在/etc/ansible/host_vars/下的主機變量文件中的變量生效了。

同理,咱們要想針對某個組的主機定義一些變量,咱們只須要在/etc/ansible/group_vars/目錄下建立與主機清單中的主機組同名的文件便可。

  3、使用高階變量

  對於普通變量,例如由ansible命令行設定的,hosts文件中定義的以及playbook中定義的和變量文件中定義的,這些變量都被稱爲普通變量或者叫簡單變量,咱們能夠在playbook中直接用雙大括號加變量名來讀取變量內容;除此之外ansible還有數組變量或者叫作列表變量,以下所示:

[root@test ~]#cat vars.yml 
---
packages_list:
  - vsftpd
  - nginx
[root@test ~]#

  列表定義完成後咱們要使用其中的變量能夠列表名加下標的方式去訪問,有點相似shell腳本里的數組的使用,以下所示

[root@test ~]#cat test.yml 
---
- hosts: 192.168.0.218
  remote_user: root
  
  vars_files:
    - vars.yml
  tasks:
    - name: touch file
      file: name={{ packages_list[0] }} state=touch
    - name: mkdir dir
      file: name={{ packages_list[1] }} state=directory
[root@test ~]#

  說明:咱們要使用列表中的第一個元素變量,咱們能夠寫成vars_list[0],使用第二個變量則下標就是1,依此類推

[root@test ~]#ansible *218 -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
總用量 12
-rw-r--r--. 1 root   root    0 11月 17 16:49 abc
-rw-r--r--. 1 root   root    0 11月 17 16:49 bcd
drwxr-xr-x. 2 qiuhom root 4096 11月 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 11月 11 19:28 test
-rw-r--r--. 1 root   root   57 11月 13 19:15 test_cron_file

[root@test ~]#ansible-playbook test.yml 

PLAY [192.168.0.218] ************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.218]

TASK [touch file] ***************************************************************************************************
changed: [192.168.0.218]

TASK [mkdir dir] ****************************************************************************************************
changed: [192.168.0.218]

PLAY RECAP **********************************************************************************************************
192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   

[root@test ~]#ansible *218 -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
總用量 16
-rw-r--r--. 1 root   root    0 11月 17 16:49 abc
-rw-r--r--. 1 root   root    0 11月 17 16:49 bcd
drwxr-xr-x. 2 root   root 4096 11月 17 17:23 nginx
drwxr-xr-x. 2 qiuhom root 4096 11月 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 11月 11 19:28 test
-rw-r--r--. 1 root   root   57 11月 13 19:15 test_cron_file
-rw-r--r--. 1 root   root    0 11月 17 17:23 vsftpd

[root@test ~]#

  說明:可看到咱們建立的文件和目錄在目標主機已經生成

上面的用法是典型的python列表的用法,在python中讀取列表中的元素就是用下標的表示來讀取相應的元素的值。接下咱們將介紹另一種更爲複雜的變量,它相似python中的字典概念,但比字典的維度要高,更像是二維字典。ansible內置變量ansible_eth0就是這樣一種,它用來保存遠端主機上面eth0接口的信息,包括ip地址和子網掩碼等。以下所示

[root@test ~]#cat test.yml     
---
- hosts: 192.168.0.218
  remote_user: root
  
  tasks:
    - debug: var=ansible_eth0 
[root@test ~]#ansible-playbook test.yml 

PLAY [192.168.0.218] ************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.218]

TASK [debug] ********************************************************************************************************
ok: [192.168.0.218] => {
    "ansible_eth0": {
        "active": true, 
        "device": "eth0", 
        "features": {
            "fcoe_mtu": "off [fixed]", 
            "generic_receive_offload": "on", 
            "generic_segmentation_offload": "on", 
            "highdma": "off [fixed]", 
            "large_receive_offload": "off [fixed]", 
            "loopback": "off [fixed]", 
            "netns_local": "off [fixed]", 
            "ntuple_filters": "off [fixed]", 
            "receive_hashing": "off [fixed]", 
            "rx_checksumming": "on", 
            "rx_vlan_filter": "on [fixed]", 
            "rx_vlan_offload": "on [fixed]", 
            "scatter_gather": "on", 
            "tcp_segmentation_offload": "on", 
            "tx_checksum_fcoe_crc": "off [fixed]", 
            "tx_checksum_ip_generic": "on", 
            "tx_checksum_ipv4": "off", 
            "tx_checksum_ipv6": "off", 
            "tx_checksum_sctp": "off [fixed]", 
            "tx_checksum_unneeded": "off", 
            "tx_checksumming": "on", 
            "tx_fcoe_segmentation": "off [fixed]", 
            "tx_gre_segmentation": "off [fixed]", 
            "tx_gso_robust": "off [fixed]", 
            "tx_lockless": "off [fixed]", 
            "tx_scatter_gather": "on", 
            "tx_scatter_gather_fraglist": "off [fixed]", 
            "tx_tcp6_segmentation": "off", 
            "tx_tcp_ecn_segmentation": "off", 
            "tx_tcp_segmentation": "on", 
            "tx_udp_tnl_segmentation": "off [fixed]", 
            "tx_vlan_offload": "on [fixed]", 
            "udp_fragmentation_offload": "off [fixed]", 
            "vlan_challenged": "off [fixed]"
        }, 
        "hw_timestamp_filters": [], 
        "ipv4": {
            "address": "192.168.0.218", 
            "broadcast": "192.168.0.255", 
            "netmask": "255.255.255.0", 
            "network": "192.168.0.0"
        }, 
        "ipv6": [
            {
                "address": "fe80::20c:29ff:fee8:f67b", 
                "prefix": "64", 
                "scope": "link"
            }
        ], 
        "macaddress": "00:0c:29:e8:f6:7b", 
        "module": "e1000", 
        "mtu": 1500, 
        "pciid": "0000:02:01.0", 
        "promisc": false, 
        "speed": 1000, 
        "timestamping": [
            "rx_software", 
            "software"
        ], 
        "type": "ether"
    }
}

PLAY RECAP **********************************************************************************************************
192.168.0.218              : ok=2    changed=0    unreachable=0    failed=0   

[root@test ~]#

  說明:以上playbook就實現了對ansible_eth0這個變量進行調試並打印,能夠看到ansible_eth0是一個相對比較複雜的變量,裏面包含了字典,列表混合一塊兒的一個大字典。

咱們能夠看到ansible_eht0裏面包含了不少內容,咱們要想讀取其中的IPV4地址,咱們能夠採用「.」或者下標的方式去訪問,以下所示

[root@test ~]#cat test.yml 
---
- hosts: 192.168.0.218
  remote_user: root
  
  tasks:
    - name: print ipv4  
      shell: echo {{ ansible_eth0["ipv4"]["address"] }} 
    - name: print mac
      shell: echo  {{ ansible_eth0.macaddress }}
[root@test ~]#ansible-playbook test.yml -v
Using /etc/ansible/ansible.cfg as config file

PLAY [192.168.0.218] ************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.218]

TASK [print ipv4] ***************************************************************************************************
changed: [192.168.0.218] => {"changed": true, "cmd": "echo 192.168.0.218", "delta": "0:00:00.001680", "end": "2019-11-17 18:30:21.926368", "rc": 0, "start": "2019-11-17 18:30:21.924688", "stderr": "", "stderr_lines": [], "stdout": "192.168.0.218", "stdout_lines": ["192.168.0.218"]}

TASK [print mac] ****************************************************************************************************
changed: [192.168.0.218] => {"changed": true, "cmd": "echo 00:0c:29:e8:f6:7b", "delta": "0:00:00.001746", "end": "2019-11-17 18:30:22.650541", "rc": 0, "start": "2019-11-17 18:30:22.648795", "stderr": "", "stderr_lines": [], "stdout": "00:0c:29:e8:f6:7b", "stdout_lines": ["00:0c:29:e8:f6:7b"]}

PLAY RECAP **********************************************************************************************************
192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   

[root@test ~]#

  說明:由此能夠看出ansible多級變量的調用,使用中括號和點號都是能夠的

原文出處:https://www.cnblogs.com/qiuhom-1874/p/11877353.html

相關文章
相關標籤/搜索