1. 程式人生 > 其它 >ansible playbook中when的多種用法和playbook handler

ansible playbook中when的多種用法和playbook handler

劇本中可以使用判斷的方式,減少hosts(play)的個數 template jinjia2 劇本中不能使用if判斷,使用when判斷 shutdown -a 取消關機 shutdown -s 關機 shutdown -f 強行關閉應用程式 shutdown -m \\計算機名 控制遠端計算機 shutdown -i 顯示“遠端關機”圖形使用者介面,但必須是Shutdown的第一個引數   shutdown -l 登出當前使用者 shutdown -r 關機並重啟 shutdown -s -t 時間 設定關機倒計時 shutdown -h 休眠 centos6啟動httpd /etc/init.d/httpd start 變數的使用並不能減少程式碼量,使用迴圈就可以減少程式碼量了 還原快照要重新推送m01上的公鑰,才能使用ansible bool值純數字要加引號,字串不用加 yum localinstall 在劇本中不會報錯 檔案型別:str int 字串型別 python中檔案型別的區分是很嚴格的, 劇本中變數加雙引號 迴圈一般在啟動服務或者copy的時候使用 yum支援列表,一般不用迴圈 命令列不支援字典的形式呼叫變數,playbook支援

根據不同的作業系統安裝apache

官方示例:

- hosts: all tasks: - name: "shut down Debian flavored systems" command: /sbin/shutdown -t now when: ansible_facts['os_family'] == "Debian" #不等於表示:!= 0 # 注意,'所有變數'都可以直接在條件語句中使用,而無需使用雙大括號 - hosts: web_group tasks: - name: Install CentOS Httpd yum: name: httpd state: present #官方 when: ansible_['os_family'] == "CentOS" #判斷系統 when: ansible.os_family == "CentOS" #非官方() when: ansible_distribution == "CentOS" - name: Install Ubuntu Httpd yum: name: apache2 state: present when: ansible_facts['os_family'] == "Ubuntu" when後面既可以是變數,又可以是指定值,一般後面跟變數,與hosts一起使用 [root@www ~]# ansible web01 -m setup |grep os_family "ansible_os_family": "RedHat", when的縮排和name註釋一樣 #facts 指的是 ansible_facts 變數,ansible 中使用 setup 模組來獲取,包含系統的大部分基礎硬體資訊

還可以使用括號,and , or對條件進行分組

tasks: - name: "shut down CentOS 6 and Debian 7 systems" command: /sbin/shutdown -t now when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7") #使用ansible_facts['distribution'] 判斷系統 注意大小寫

也可以指定多條件為列表(and 並且)

tasks: - name: "shut down CentOS 6 systems" command: /sbin/shutdown -t now when: - ansible_facts['distribution'] == "CentOS" - ansible_facts['distribution_major_version'] == "6" #列表形式等效於and

條件運算

tasks: - shell: echo "only on Red Hat 6, derivatives, and later" when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6 #

rsync服務端推送配置檔案

[root@m01 ~]# cat rsyncd/rsyncd.yml - hosts: all ###### tasks: - name: Install Rsyncd Server yum: name: rsync state: present #可在這裡使用ls -l 判斷rsync是否安裝 - name: Create www Group group: name: www gid: 666 - name: Create www User user: name: www group: www uid: 666 create_home: false shell: /sbin/nologin - name: Scp Rsync Config copy: src: ./rsyncd.j2 dest: /etc/rsyncd.conf owner: root group: root mode: 0644 when: ansible_hostname == "backup" #判斷主機名 - name: Create Passwd File copy: content: 'rsync_backup:123' dest: /etc/rsync.passwd owner: root group: root mode: 0600 when: ansible_hostname == "backup" - name: Create backup Directory file: path: /backup state: directory mode: 0755 owner: www group: www recurse: yes when: ansible_hostname == "backup" - name: Start Rsyncd Server systemd: name: rsyncd state: started when: ansible_hostname == "backup"

rsync客戶端推送指令碼

[root@m01 ~]# vim rsync.yml - hosts: rsync_server tasks: - name: SCP Backup Shell copy: src: ./backup.sh dest: /root/backup.sh when: ansible_hostname is match "web*" #when支援萬用字元 when: ansible_hostname ~= "web*" #when: ansible_hostname == "backup" or ansible_hostname == "nfs" #這三種方式類似模糊匹配,都可以匹配多臺web #模糊匹配和and or不能一起使用

通過register將命令執行結果儲存至變數,然後通過when語句進行判斷

- hosts: web_group tasks: - name: Check Httpd Server command: systemctl is-active httpd #檢視服務狀態 ignore_errors: yes #忽略報錯,繼續執行 register: check_httpd #將命令的執行結果註冊變數 - name: debug outprint debug: var=check_httpd #偶爾除錯 - name: Httpd Restart service: name: httpd state: restarted when: check_httpd.rc == 0 #通過變數註冊的方式可以進行非系統變數的呼叫,與'register: check_httpd'對應 #htpd [root@lb01 ~]# systemctl is-active httpd active [root@lb01 ~]# systemctl stop httpd [root@lb01 ~]# systemctl is-active httpd unknown #nginx [root@lb01 ~]# systemctl is-active nginx active [root@lb01 ~]# systemctl stop nginx [root@lb01 ~]# systemctl is-active nginx failed

2|0playbook迴圈語句

在之前的學習過程中,我們經常會有傳送檔案,建立目錄之類的操作,建立2個目錄就要寫兩個file模組來建立,如果要建立100個目錄,我們需要寫100個file模組???媽耶~~~~ 當然不是,只要有迴圈即可,減少重複性程式碼。


啟動多個服務

- hosts: web_group tasks: - name: start service systemd: name: "{{ item }}" state: started with_items: - httpd - php-fpm - mariadb

定義變數迴圈

- name: ensure a list of packages installed yum: name: "{{ packages }}" vars: #模組內定義變數 packages: - httpd - httpd-tools - hosts: web_group tasks: - name: ensure a list of packages installed yum: name= "{{ item }}" state=present #可以使用多個'=' with_items: - httpd - httpd-tools #with_items一般放到模組的末尾,與模組同一縮排級別

字典迴圈

1.建立使用者

[root@m01 ~]# cat loop.yml - hosts: web_group tasks: - name: Add Users user: name: "{{ item.name }}" groups: "{{ item.groups }}" state: present with_items: - { name: 'zls', groups: 'linux' } - { name: 'egon', groups: 'python' }

2.拷貝檔案

- hosts: web_group tasks: - name: copy conf and code copy: src: "{{ item.src }}" dest: "{{ item.dest }}" mode: "{{ item.mode }}" with_items: - { src: "./httpd.conf", dest: "/etc/httpd/conf/", mode: "0644" } - { src: "./upload_file.php", dest: "/var/www/html/", mode: "0600" } #同一模組在一個劇本中多次出現,即可考慮使用迴圈 #同一模組在一個劇本中多次出現,對同一主機多次操作,即可考慮字典迴圈

3|0playbook handler

handler用來執行某些條件下的任務,比如當配置檔案發生變化的時候,通過notify觸發handler去重啟服務。

實踐案例

[root@m01 ~]# cat handler.yml - hosts: web_group vars: - http_port: 8080 tasks: - name: Install Http Server yum: name: httpd state: present - name: config httpd server template: src: ./httpd.j2 dest: /etc/httpd/conf notify: # - Restart Httpd Server - Restart PHP Server - name: start httpd server service: name:httpd state: started enabled: yes handlers: # - name: Restart Httpd Server systemd: name: httpd state: restarted - name: Restart PHP Server systemd: name: php-fpm state: restarted

練習:多個nginx配置檔案的推送及觸發器

注意:
1.無論多少個task通知了相同的handlers,handlers僅會在所有tasks結束後執行一次

2.Handlers只有在其所在的任務被執行時,才會被執行;如果一個任務中定義了notify呼叫Handlers,但是由於條件判斷等原因,該任務未被執行,那麼Handlers同樣不會被執行。

3.Handlers只會在每一個play的末尾執行一次;如果想在一個playbook中間執行Handlers,則需要使用meta模組來實現。例如: -meta: flush_handlers。

4.如果一個play在執行到呼叫Handlers的語句之前失敗了,那麼這個Handlers將不會被執行。我們可以使用meta模組的--force-handlers選項來強制執行Handlers,即使Handlers所在的play中途執行失敗也能執行。

5.不能使用handlers替代tasks


4|0playbook任務標籤

預設情況下,Ansible在執行一個playbook時,會執行playbook中定義的所有任務,Ansible的標籤(tag)功能可以給單獨任務甚至整個playbook打上標籤,然後利用這些標籤來指定要執行playbook中的個別任務,或不執行指定的任務。


打標籤的方式

1.對一個task打一個標籤
2.對一個task打多個標籤
3.對多個task打一個標籤


打完標籤如何使用

-t:執行指定的tag標籤任務
--skip-tags:執行--skip-tags之外的標籤任務


使用-t指定tag

[root@m01 m01]# cat tag.yml - hosts: web_group vars: - http_port: 8080 tasks: - name: Install Http Server yum: name: httpd state: present tags: - install_httpd - httpd_server - name: configure httpd server template: src: ./httpd.j2 dest: /etc/httpd/conf/httpd.conf notify: Restart Httpd Server tags: - config_httpd - httpd_server - name: start httpd server service: name: httpd state: started enabled: yes tags: service_httpd handlers: - name: Restart Httpd Server systemd: name: httpd state: restarted [root@m01 m01]# ansible-playbook tag.yml --list-tags [root@m01 m01]# ansible-playbook tag.yml -t httpd_server [root@m01 m01]# ansible-playbook tag.yml -t install_httpd,confiure_httpd [root@m01 m01]# ansible-playbook tag.yml --skip-tags httpd_server

5|0playbook檔案複用

在之前寫playbook的過程中,我們發現,寫多個playbook沒有辦法,一鍵執行,這樣我們還要單個playbook挨個去執行,很雞肋。所以在playbook中有一個功能,叫做include用來動態呼叫task任務列表。

只調用task:include_tasks
呼叫整個task檔案:include(新版本:import_playbook)

在saltstack中,叫做top file入口檔案。

示例一:

[root@m01 m01]# cat task.yml - hosts: web_group vars: - http_port: 8080 tasks: - include_tasks: task_install.yml - include_tasks: task_configure.yml - include_tasks: task_start.yml handlers: - name: Restart Httpd Server systemd: name: httpd state: restarted [root@m01 m01]# cat task_install.yml - name: Install Http Server yum: name: httpd state: present [root@m01 m01]# cat task_configure.yml - name: configure httpd server template: src: ./httpd.j2 dest: /etc/httpd/conf/httpd.conf notify: Restart Httpd Server [root@m01 m01]# cat task_start.yml - name: start httpd server service: name: httpd state: started enabled: yes

示例二

- include: httpd.yml - include: nfs.yml - include: rsync.yml

示例三

- import_playbook: httpd.yml - import_playbook: nfs.yml - import_playbook: rsync.yml

6|0playbook忽略錯誤

預設playbook會檢測task執行的返回狀態,如果遇到錯誤則會立即終止playbook的後續task執行,然鵝有些時候playbook即使執行錯誤了也要讓其繼續執行。

加入引數:ignore_errors:yes 忽略錯誤

[root@m01 ~]# cat ignore.yml --- - hosts: web_group tasks: - name: Ignore False command: /bin/false ignore_errors: yes - name: touch new file file: path: /tmp/zls.txt state: touch

7|0playbook錯誤處理

如上所述,當task執行失敗時,playbook將不再繼續執行,包括如果在task中設定了handler也不會被執行。

但是我們可以採取強制措施...


強制呼叫handler

[root@m01 ~]# cat handler.yml - hosts: web_group vars: - http_port: 8080 force_handlers: yes tasks: - name: config httpd server template: src: ./httpd.j2 dest: /etc/httpd/conf notify: - Restart Httpd Server - Restart PHP Server - name: Install Http Server yum: name: htttpd state: present - name: start httpd server service: name:httpd state: started enabled: yes handlers: - name: Restart Httpd Server systemd: name: httpd state: restarted - name: Restart PHP Server systemd: name: php-fpm state: restarted

抑制changed

被管理主機沒有發生變化,可以使用引數將change狀態改為ok

[root@m01 ~]# cat handler.yml - hosts: web_group vars: - http_port: 8080 force_handlers: yes tasks: - name: shell shell: netstat -lntup|grep httpd register: check_httpd changed_when: false - name: debug debug: msg={{ check_httpd.stdout.lines }} [root@m01 project2]# cat changed_when.yml - hosts: webservers vars: - http_port: 8080 tasks: - name: configure httpd server template: src: ./httpd.j2 dest: /etc/httpd/conf/httpd.conf notify: Restart Httpd Server - name: Check HTTPD shell: /usr/sbin/httpd -t register: httpd_check changed_when: - httpd_check.stdout.find('OK') - false - name: start httpd server service: name: httpd state: started enabled: yes handlers: - name: Restart Httpd Server systemd: name: httpd state: restarted