一、When語句linux
有時候用戶有可能須要某一個主機越過某一個特定的步驟.這個過程就能夠簡單的像在某一個特定版本的系統上少裝了一個包同樣或者像在一個滿了的文件系統上執行清理操做同樣.nginx
這些操做在Ansible上,若使用`when`語句都異常簡單.When語句也含Jinja2表達式,web
第一個例子:shell
tasks: - name: "shutdown Debian flavored systems" command: /sbin/shutdown -t now when: ansible_os_family == "Debian" 若是你在RedHat系列linux系統執行,就不會被執行
第二個例子:apache
#cat copyfile.yml --- - hosts: "`host`" user: "`user`" gather_facts: True tasks: - name: Copy file to client copy: src=/etc/ansible/test.txt dest=/usr/local/src when: ansible_os_family == "Debian" - include: add_user.yml when: ansible_os_family == "Debian" 執行: #ansible-playbook copyfile.yml -e "host=web user=root" --能夠看到下面都skipping掉了 PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [10.0.90.26] ok: [10.0.90.25] TASK [Copy file to client] ***************************************************** skipping: [10.0.90.25] skipping: [10.0.90.26] TASK [include] ***************************************************************** skipping: [10.0.90.25] skipping: [10.0.90.26] PLAY RECAP ********************************************************************* 10.0.90.25 : ok=1 changed=0 unreachable=0 failed=0 10.0.90.26 : ok=1 changed=0 unreachable=0 failed=0 以上yml中的任務都沒有執行,由於我測試機器是CentOS系統!而條件是隻有當系統是Debian類型的時候執行!
PS:文件中的include模塊後續會介紹。
bash
第三個例子:服務器
tasks: - shell: echo "only on Red Hat 6, derivatives, and later" when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 6 意思是隻有當系統是RedHat而且版本大於等於6的時候執行
第三個例子:只有在server組或者名爲server的這臺服務器才執行ide
- name: Copy file to client copy: src=/etc/ansible/test.txt dest=/usr/local/src when: "host=='server'"
帶管道的when語句oop
tasks: - command: /bin/false register: result ignore_errors: True - command: /bin/something when: result|failed - command: /bin/something_else when: result|success - command: /bin/still/something_else when: result|skipped
判斷變量是否已經定義:測試
若是一個變量不存在,你可使用Jinja2的`defined`命令跳過或略過.例如:
tasks: - shell: echo "I've got '{{ foo }}' and am not afraid to use it!" when: foo is defined - fail: msg="Bailing out. this play requires 'bar'" when: bar is not defined
二、debug模塊
Print statements during execution
打印執行過程當中的語句,一般用來調試編寫好的playbook語句,
Examples # Example that prints the loopback address and gateway for each host - debug: msg="System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}" - debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}" when: ansible_default_ipv4.gateway is defined - shell: /usr/bin/uptime register: result - debug: var=result verbosity=2 - name: Display all variables/facts known for a host debug: var=hostvars[inventory_hostname] verbosity=4
生產環境遇到的一個案例:
有2臺server:
第一臺:10.0.90.25安裝了nginx,
第二臺:10.0.90.26沒有安裝nginx
如今我只想在沒有安裝nginx的server上作操做,須要經過when條件語句實現,以下:
#cat test1.yml --- - hosts: web remote_user: root tasks: - name: ps shell: ps -ef | grep nginx | grep -v grep|wc -l register: nginx_num - debug: var=nginx_num - name: command copy: src=/etc/ansible/server.xml dest=/root when: nginx_num.stdout == "0"
PS:剛開始的時候,沒有添加- debug: var=nginx_num這一項,結果執行的時候,老是skipping跳過,說明條件錯誤後來才使用debug模塊調試
執行結果:
#ansible-playbook test1.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [10.0.90.25] ok: [10.0.90.26] TASK [ps] ********************************************************************** changed: [10.0.90.25] changed: [10.0.90.26] TASK [debug] ******************************************************************* ok: [10.0.90.25] => { "nginx_num": { "changed": true, "cmd": "ps -ef | grep nginx | grep -v grep|wc -l", "delta": "0:00:00.008476", "end": "2016-05-19 20:40:51.742088", "rc": 0, "start": "2016-05-19 20:40:51.733612", "stderr": "", "stdout": "3", "stdout_lines": [ "3" ], "warnings": [] } } ok: [10.0.90.26] => { "nginx_num": { "changed": true, "cmd": "ps -ef | grep nginx | grep -v grep|wc -l", "delta": "0:00:00.009458", "end": "2016-05-19 20:40:51.754993", "rc": 0, "start": "2016-05-19 20:40:51.745535", "stderr": "", "stdout": "0", "stdout_lines": [ "0" ], "warnings": [] } } TASK [command] ***************************************************************** skipping: [10.0.90.25] changed: [10.0.90.26] PLAY RECAP ********************************************************************* 10.0.90.25 : ok=3 changed=1 unreachable=0 failed=0 10.0.90.26 : ok=4 changed=2 unreachable=0 failed=0
能夠看到跳過了10.0.90.25,只在10.0.90.26上執行了命令。
範例1:
#cat test2.yml --- - hosts: 10.0.90.25 user: root gather_facts: True tasks: - name: test debug module debug: msg="System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}" #ansible-playbook test2.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [10.0.90.25] TASK [test debug module] ******************************************************* ok: [10.0.90.25] => { "msg": "System 10.0.90.25 has uuid 564DB430-3121-EEE4-33F1-559FEF576AC9" } PLAY RECAP ********************************************************************* 10.0.90.25 : ok=2 changed=0 unreachable=0 failed=0
範例2:
#cat test3.yml --- - hosts: 10.0.90.25 user: root gather_facts: True tasks: - debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}" when: ansible_default_ipv4.gateway is defined 說明:只有當遠端server的gateway配置的狀況下才執行,執行結果以下: #ansible-playbook test3.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [10.0.90.25] TASK [debug] ******************************************************************* ok: [10.0.90.25] => { "msg": "System 10.0.90.25 has gateway 10.0.90.1" } PLAY RECAP ********************************************************************* 10.0.90.25 : ok=2 changed=0 unreachable=0 failed=0 將10.0.90.25網關配置去掉,再一次執行: #ansible-playbook test3.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [10.0.90.25] TASK [debug] ******************************************************************* skipping: [10.0.90.25] PLAY RECAP ********************************************************************* 10.0.90.25 : ok=1 changed=0 unreachable=0 failed=0 說明:由於將遠端server的網關配置去掉了,when條件不成立,就skipping了。
三、notify和Handlers
handlers 用於在發生改變時執行的操做。notify這個action可用於在每一個play的最後被觸發,這樣能夠避免屢次有改變發生時每次都執行指定的操做,取而代之的是僅在全部的變化發生完成後一次性地執行指定操做。好比多個resources指出由於一個配置文件被改動,因此apache須要從新啓動,可是從新啓動的操做只會被執行一次。在notify中列出的操做稱爲handler也即notify調用handler中定義的操做,Handlers也是一些task的列表,經過名字來引用,他們和通常的task並無什麼區別。Handlers是由通知者進行notify,若是沒有被notify,handlers不會執行,無論有多少個通知者進行了notify,等到play中的全部task執行完成以後,handlers也只會被執行一次。
注意:Handlers 最佳的應用場景是用來重啓服務,或者觸發系統重啓操做.除此之外不多用到了,並且它會按照聲明的順序執行
以下一個例子:
自定義好httpd.conf配置文件(有變量),拷貝到/etc/httpd/conf目錄,而後啓動httpd,並設置開機自啓動!
#cat test3.yml --- - hosts: web remote_user: root gather_facts: True vars: http_port: 80 max_clients: 200 tasks: - name: ensure apache is at the latest version yum: pkg=httpd state=latest - name: copy httpd config file to client copy: src=/etc/ansible/httpd_test.config dest=/etc/httpd/conf/ notify: - restart apache - name: ensure apache is running service: name=httpd state=started handlers: - name: restart apache service: name=httpd state=restarted
執行:
#ansible-playbook test3.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [10.0.90.25] ok: [10.0.90.26] TASK [ensure apache is at the latest version] ********************************** changed: [10.0.90.26] changed: [10.0.90.25] TASK [copy httpd config file to client] **************************************** changed: [10.0.90.26] changed: [10.0.90.25] TASK [ensure apache is running] ************************************************ ok: [10.0.90.26] ok: [10.0.90.25] RUNNING HANDLER [restart apache] *********************************************** changed: [10.0.90.26] changed: [10.0.90.25] PLAY RECAP ********************************************************************* 10.0.90.25 : ok=5 changed=3 unreachable=0 failed=0 10.0.90.26 : ok=5 changed=3 unreachable=0 failed=0
注:此處定義的notify是restart,就是安裝好httpd並拷貝好配置文件以後。
notify也能夠是restarted、stopped、reloaded
enabled=yes是表示設置httpd開機自啓動。
若是再次執行,就不會有任何改變了。由於httpd已經啓動了
#ansible-playbook test3.yml PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [10.0.90.25] ok: [10.0.90.26] TASK [ensure apache is at the latest version] ********************************** ok: [10.0.90.25] ok: [10.0.90.26] TASK [copy httpd config file to client] **************************************** ok: [10.0.90.26] ok: [10.0.90.25] TASK [ensure apache is running] ************************************************ ok: [10.0.90.26] ok: [10.0.90.25] PLAY RECAP ********************************************************************* 10.0.90.25 : ok=4 changed=0 unreachable=0 failed=0 10.0.90.26 : ok=4 changed=0 unreachable=0 failed=0