一 Ansible Playbook簡介
ansbile-playbook是一系列ansible命令的集合,利用yaml 語言編寫。playbook命令根據自上而下的順序依次執行。同時,playbook開創了很多特性,它可以允許你傳輸某個命令的狀態到后面的指令,如你可以從一台機器的文件中抓取內容並附為變量,然后在另一台機器中使用,這使得你可以實現一些復雜的部署機制,這是ansible命令無法實現的。
playbook通過ansible-playbook命令使用,它的參數和ansible命令類似,如參數-k(–ask-pass) 和 -K (–ask-sudo) 來詢問ssh密碼和sudo密碼,-u指定用戶,這些指令也可以通過規定的單元寫在playbook 。
ansible-playbook的簡單使用方法: ansible-playbook example-play.yml 。
二 Playbook基本語法
下面是一個簡單的ansible-playbook示例,可以了解其構成:
# cat user.yml - name: create user hosts: all remote_user: root gather_facts: false vars: user:"test" tasks: - name: create user user: name="{{ user }}"
配置項說明:
- name:對該playbook實現的功能做一個概述,后面執行過程中,會打印 name變量的值
- hosts:指定對哪些被管理機進行操作;
- remote_user:指定在遠程被管理機上執行操作時使用什么用戶,如不指定,則使用ansible.cfg中配置的remote_user
- gather_facts:指定在執行任務之前,是否先執行setup模塊獲取主機相關信息,如未用到,可不指定
- vars:定義后續任務中會使用到的變量,如未用到,可不指定
- tasks:定義具體需要執行的任務name:對任務的描述,在執行過程中會打印出來。
- user:指定調用user模塊;
- name:user模塊里的一個參數,用於指定創建的用戶名稱
同樣,如果想實現把這個新增的用戶刪除,只需將該playbook文件的最后一行替換為如下行再執行相應的playbook即可:
user: name="{{ user }}" state=absent remove=yes
三 playbook組成
3.1 palybook簡單演示
- name: configure nginx hosts: 192.168.132.133 tasks: - name: install epel-release package: name: epel-release state: present - name: install nginx package: name: nginx state: present - name: create directory file: path: ./file state: directory owner: nginx group: nginx - name: copy file from remote serevr fetch: src: /usr/share/nginx/html/index.html dest: file/ - name: delete file of remote server file: path: /usr/share/nginx/html/index.html state: absent - name: create a remote server file file: path: /usr/share/nginx/html/index.html state: touch owner: nginx group: nginx - name: content copy: content: "<h3>welcome ansible</h3>" dest: /usr/share/nginx/html/index.html - name: start service systemd: name: nginx state: started enabled: yes daemon_reload: yes
[root@node1 ansible]# ansible-playbook nginx_config.yml
PLAY [configure nginx] ************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************ ok: [192.168.132.133] TASK [install epel-release] ******************************************************************************************************************* changed: [192.168.132.133] TASK [install nginx] ************************************************************************************************************************** changed: [192.168.132.133] TASK [create directory] *********************************************************************************************************************** ok: [192.168.132.133] TASK [copy file from remote serevr] *********************************************************************************************************** changed: [192.168.132.133] TASK [delete file of remote server] *********************************************************************************************************** changed: [192.168.132.133] TASK [create a remote server file] ************************************************************************************************************ changed: [192.168.132.133] TASK [content] ******************************************************************************************************************************** changed: [192.168.132.133] TASK [start service] ************************************************************************************************************************** changed: [192.168.132.133] PLAY RECAP ************************************************************************************************************************************ 192.168.132.133 : ok=9 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看192.168.132.133
[root@node3 ~]# rpm -qa |grep epel-release epel-release-7-11.noarch [root@node3 ~]# rpm -qa |grep nginx nginx-mod-http-xslt-filter-1.16.1-1.el7.x86_64 nginx-all-modules-1.16.1-1.el7.noarch nginx-mod-mail-1.16.1-1.el7.x86_64 nginx-mod-http-image-filter-1.16.1-1.el7.x86_64 nginx-mod-stream-1.16.1-1.el7.x86_64 nginx-filesystem-1.16.1-1.el7.noarch nginx-mod-http-perl-1.16.1-1.el7.x86_64 nginx-1.16.1-1.el7.x86_64 [root@node3 ~]# systemctl status nginx ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2020-04-29 14:06:10 CST; 2min 25s ago [root@node3 ~]# systemctl is-enabled nginx
enabled
訪問
3.2 yml規則
yml文件它的基本語法規則如下。
- 大小寫敏感
- 使用縮進表示層級關系
- 縮進時不允許使用Tab鍵,只允許使用空格。
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
#
表示注釋,從這個字符一直到行尾,都會被解析器忽略。
YAML 支持的數據結構有三種。
- 對象:鍵值對的集合,又稱為映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 數組:一組按次序排列的值,又稱為序列(sequence) / 列表(list)
- 純量(scalars):單個的、不可再分的值
ansible-playbook常用選項
3.3 ansible其他用法
1 打印詳細信息
- -v:打印任務運行結果
- -vv:打印任務運行結果以及任務的配置信息
- -vvv:包含了遠程連接的一些信息
- -vvvv:Adds extra verbosity options to the connection plug-ins,including the users being used in the managed hosts to execute scripts, and what scripts have been executed
[root@node1 ansible]# ansible-playbook nginx_config.yml -v
2. 校驗playbook語法
[root@node1 ansible]# ansible-playbook nginx_config.yml --syntax-check
playbook: nginx_config.yml
3. 測試運行playbook
通過-C選項可以測試playbook的執行情況,但不會真的執行:
[root@node1 ansible]# ansible-playbook -C nginx_config.yml
4 Multiple Plays
# This is a simple playbook with two plays - name: first play hosts: web.example.com tasks: - name: first task yum: name: httpd status: present - name: second task service: name: httpd state: started - name: second play hosts: db.example.com tasks: - name: first task yum: name: mariadb-server status: present - name: second task service: name: mariadb state: started
四 playbook的結構說明
playbook是由一個或多個"play"組成的列表。play的主要功能就是對一組主機應用play中定義好的task。從根本上來講一個task就是對ansible一個module的調用。而將多個play按照一定的順序組織到一個playbook中,我們稱之為編排。
playbook主要有以下四部分構成:
- Target section: 用於定義將要執行playbook的遠程主機組及遠程主機組上的用戶,還包括定義通過什么樣的方式連接遠程主機(默認ssh)
- Variable section: 定義playbook運行時需要使用的變量
- Task section: 定義將要在遠程主機上執行的任務列表
- Handler section: 定義task執行完成以后需要調用的任務
4.1 Target section
playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的用戶身份執行任務。
Playbook中的遠程用戶
playbook中的遠程用戶和ad-hoc中的使用沒有區別,默認不定義,則直接使用ansible.cfg配置中的用戶相關的配置。也可在playbook中定義如下:
- name: /etc/hosts is up to date hosts: datacenter remote_user: automation become: yes become_mothod: sudo become_user: root tasks: - name: server.example.com in /etc/hosts lineinfile: path: /etc/hosts line: '192.168.0.200 server.exmaple.com server' state: present
Playbook中的hosts
playbook中的hosts即inentory中的定義主機與主機組,在《Ansible Inventory》中我們講到了如何選擇主機與主機組,在這里也完全適用。
4.2 Variable section
定義playbook運行時需要使用的變量
- name : test vars hosts: node2 remote_user: ansible become_user: root become_method: sudo vars: user: name: "user1" address: "IPaddr" tasks: - name: "print" debug: msg: "{{ user }}"
執行
PLAY [test vars] ****************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************ ok: [node2] TASK [print] ********************************************************************************************************************************** ok: [node2] => { "msg": { "address": "IPaddr", "name": "user1" } } PLAY RECAP ************************************************************************************************************************************ node2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.3 Task section
play的主體部分是任務列表。
任務列表中的各任務按次序逐個在hosts中指定的所有主機上執行,在所有主機上完成第一個任務后再開始第二個。在自上而下運行某playbook時,如果中途發生錯誤,則整個playbook會停止執行,由於playbook的冪等性,playbook可以被反復執行,所以即使發生了錯誤,在修復錯誤后,再執行一次即可。
定義task可以使用action: module options
或module: options
的格式,推薦使用后者以實現向后兼容。
tasks: - name: make sure apache is running service: name: httpd state: started - name: disable selinux command: /sbin/setenforce 0
如果命令或腳本的退出碼不為零可以使用如下方式替代:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true
可以使用ignore_errors來忽略錯誤信息:
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
4.4 Handler section
-
在Ansible Playbook中,handler事實上也是個task,只不過這個task默認並不執行,只有在被觸發時才執行。
-
handler通過notify來監視某個或者某幾個task,一旦task執行結果發生變化,則觸發handler,執行相應操作。
-
handler會在所有的play都執行完畢之后才會執行,這樣可以避免當handler監視的多個task執行結果都發生了變化之后而導致handler的重復執行(handler只需要在最后執行一次即可)。
在notify中定義內容一定要和tasks中定義的 - name 內容一樣,這樣才能達到觸發的效果,否則會不生效。
- name: configure nginx hosts: 192.168.132.133 tasks: - name: install epel-release package: name: epel-release state: present - name: install nginx package: name: nginx state: present notify: restart nginx - name: create directory file: path: ./file state: directory owner: nginx group: nginx - name: copy file from remote serevr fetch: src: /usr/share/nginx/html/index.html dest: file/ - name: delete file of remote server file: path: /usr/share/nginx/html/index.html state: absent - name: create a remote server file file: path: /usr/share/nginx/html/index.html state: touch owner: nginx group: nginx - name: content copy: content: "<h3>welcome ansible</h3>" dest: /usr/share/nginx/html/index.html - name: start service systemd: name: nginx state: started enabled: yes daemon_reload: yes handlers: - name: restart nginx systemd: name: nginx daemon_reload: yes state: restarted
執行
PLAY [configure nginx] ************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************ ok: [192.168.132.133] TASK [install epel-release] ******************************************************************************************************************* ok: [192.168.132.133] TASK [install nginx] ************************************************************************************************************************** ok: [192.168.132.133] TASK [create directory] *********************************************************************************************************************** ok: [192.168.132.133] TASK [copy file from remote serevr] *********************************************************************************************************** ok: [192.168.132.133] TASK [delete file of remote server] *********************************************************************************************************** changed: [192.168.132.133] TASK [create a remote server file] ************************************************************************************************************ changed: [192.168.132.133] TASK [content] ******************************************************************************************************************************** changed: [192.168.132.133] TASK [start service] ************************************************************************************************************************** ok: [192.168.132.133] PLAY RECAP ************************************************************************************************************************************ 192.168.132.133 : ok=9 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
沒有觸發,試音並沒有change
- name: configure nginx hosts: 192.168.132.133 tasks: - name: install epel-release package: name: epel-release state: present - name: install nginx package: name: nginx state: present - name: create directory file: path: ./file state: directory owner: nginx group: nginx - name: copy file from remote serevr fetch: src: /usr/share/nginx/html/index.html dest: file/ - name: delete file of remote server file: path: /usr/share/nginx/html/index.html state: absent notify: restart nginx - name: create a remote server file file: path: /usr/share/nginx/html/index.html state: touch owner: nginx group: nginx - name: content copy: content: "<h3>welcome ansible</h3>" dest: /usr/share/nginx/html/index.html - name: start service systemd: name: nginx state: started enabled: yes daemon_reload: yes handlers: - name: restart nginx systemd: name: nginx daemon_reload: yes state: restarted
執行
[root@node1 ansible]# ansible-playbook nginx_config.yml
PLAY [configure nginx] ************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************ ok: [192.168.132.133] TASK [install epel-release] ******************************************************************************************************************* ok: [192.168.132.133] TASK [install nginx] ************************************************************************************************************************** ok: [192.168.132.133] TASK [create directory] *********************************************************************************************************************** ok: [192.168.132.133] TASK [copy file from remote serevr] *********************************************************************************************************** ok: [192.168.132.133] TASK [delete file of remote server] *********************************************************************************************************** changed: [192.168.132.133] TASK [create a remote server file] ************************************************************************************************************ changed: [192.168.132.133] TASK [content] ******************************************************************************************************************************** changed: [192.168.132.133] TASK [start service] ************************************************************************************************************************** ok: [192.168.132.133] RUNNING HANDLER [restart nginx] *************************************************************************************************************** changed: [192.168.132.133] PLAY RECAP ************************************************************************************************************************************ 192.168.132.133 : ok=10 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
觸發執行
一個任務可以觸發多個handlers
notify: - restart nginx - restart redis
默認情況下,在一個play中,只要有task執行失敗,則play終止,即使是與handler關聯的task在失敗的task之前運行成功了,handler也不會被執行。如果希望在這種情況下handler仍然能夠執行,則需要使用如下配置:
- hosts: all force_handlers: yes tasks: - name: a task which always notifies its handler command: /bin/true notify: restart the database - name: a task which fails because the package doesn't exist yum: name: notapkg state: latest handlers: - name: restart the database service: name: mariadb
如果與handler關聯的task還未執行,在其前的task已經失敗,整個play終止,則handler未被觸發,也不會執行
博主聲明:本文的內容來源主要來自譽天教育晏威老師,由本人實驗完成操作驗證,需要的博友請聯系譽天教育(http://www.yutianedu.com/),獲得官方同意或者晏老師(https://www.cnblogs.com/breezey/)本人同意即可轉載,謝謝!