自動化運維工具Ansible實戰(五)playbook使用
(一)playbook簡述
ansbile-playbook是一系統ansible命令的集合,其利用yaml 語言編寫,運行過程,ansbile-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添加用戶實例
1,給遠程主機添加用戶test
[[email protected] ansible]# vim user.yml ########add user.yml - name: create user hosts: all user: root gather_facts: false vars: - user: "test" tasks: - name: create user user: name="{{ user }}"
上面的playbook 實現的功能是新增一個用戶:
name:參數對該playbook實現的功能做一個概述,後面執行過程中,會打印 name變量的值 ;
hosts:參數指定了對哪些主機進行參作;
user:參數指定了使用什麽用戶登錄遠程主機操作;
gather_facts:參數指定了在以下任務部分執行前,是否先執行setup模塊獲取主機相關信息,這在後面的task會使用到setup獲取的信息時用到;
vars:參數,指定了變量,這裏指定了一個user變量,其值為test ,需要註意的是,變量值一定要用引號引住;
task:指定了一個任務,其下面的name參數同樣是對任務的描述,在執行過程中會打印出來。user提定了調用user模塊,name是user模塊裏的一個參數,而增加的用戶名字調用了上面user變量的值。
2,查看具體的執行結果
[[email protected] ansible]# ansible-playbook user.yml PLAY [create user] ************************************************************* TASK [create user] ************************************************************ changed: [Server5] changed: [192.168.180.4] fatal: [192.168.180.23]: FAILED! => {"changed": false, "cmd": "/sbin/useradd -m test", "failed": true, "msg": "[Errno 13] 權限不夠", "rc": 13} ok: [Server6] ok: [192.168.180.6] ok: [192.168.180.5] changed: [192.168.180.10] ok: [192.168.180.2] to retry, use: --limit @/etc/ansible/user.retry PLAY RECAP ********************************************************************* 192.168.180.10 : ok=1 changed=1 unreachable=0 failed=0 192.168.180.2 : ok=1 changed=0 unreachable=0 failed=0 192.168.180.23 : ok=0 changed=0 unreachable=0 failed=1 192.168.180.4 : ok=1 changed=1 unreachable=0 failed=0 192.168.180.5 : ok=1 changed=0 unreachable=0 failed=0 192.168.180.6 : ok=1 changed=0 unreachable=0 failed=0 Server5 : ok=1 changed=1 unreachable=0 failed=0 Server6 : ok=1 changed=0 unreachable=0 failed=0
3,刪除遠程主機的賬號:只需user: name="{{ user }}" state=absent remove=yes 即可
,把剛才添加的test用戶刪除:
[[email protected] ansible]# vim user.yml ########add user.yml - name: create user hosts: all user: root gather_facts: false vars: - user: "test" tasks: - name: create user user: name="{{ user }}" state=absent remove=yes [[email protected] ansible]# ansible-playbook user.yml PLAY [create user] ************************************************************* TASK [create user] ************************************************************ changed: [Server5] changed: [192.168.180.4] ok: [192.168.180.23] changed: [192.168.180.6] ok: [192.168.180.5] ok: [Server6] fatal: [192.168.180.2]: FAILED! => {"changed": false, "failed": true, "msg": "userdel:/ftmp/test 並不屬於 test,所以不會刪除\n", "name": "test", "rc": 12} changed: [192.168.180.10] to retry, use: --limit @/etc/ansible/user.retry PLAY RECAP ********************************************************************* 192.168.180.10 : ok=1 changed=1 unreachable=0 failed=0 192.168.180.2 : ok=0 changed=0 unreachable=0 failed=1 192.168.180.23 : ok=1 changed=0 unreachable=0 failed=0 192.168.180.4 : ok=1 changed=1 unreachable=0 failed=0 192.168.180.5 : ok=1 changed=0 unreachable=0 failed=0 192.168.180.6 : ok=1 changed=1 unreachable=0 failed=0 Server5 : ok=1 changed=1 unreachable=0 failed=0 Server6 : ok=1 changed=0 unreachable=0 failed=0
二,通過playbook一鍵升級bash
[[email protected] ansible]# vim update_bash.yml - hosts: all remote_user: root gather_facts: True tasks: - name: update bash in redhat 6 version yum: name=http://mirrors.aliyun.com/centos/6.6/os/x86_64/Packages/bash-4.1.2 -29.el6.x86_64.rpm.rpm state=present when: ansible_os_family == "RedHat" and ansible_distribution_version|int >=6 - name: update bash in redhat 5 version yum: name=http://mirrors.hustunique.com/centos/5/updates/x86_64/RPMS/bash-3. 2-33.el5.1.x86_64.rpm state=present when: ansible_os_family == "RedHat" and ansible_distribution_version|int <=5 [[email protected] ansible]# ansible ansible ansible-doc ansible-playbook ansible-vault ansible-console ansible-galaxy ansible-pull [[email protected] ansible]# ansible-playbook update_bash.yml PLAY [all] ********************************************************************* TASK [setup] ******************************************************************* ok: [Server6] ok: [192.168.180.23] ok: [Server5] ok: [192.168.180.6] ok: [192.168.180.5] ok: [192.168.180.4] ok: [192.168.180.2] ok: [192.168.180.10] TASK [update bash in redhat 6 version] ***************************************** fatal: [192.168.180.4]: FAILED! => {"changed": false, "failed": true, "msg": "Failure downloading http://mirrors.aliyun.com/centos/6.6/os/x86_64/Packages/bash-4.1.2-29.el6.x86_64.rpm.rpm, ‘NoneType‘ object has no attribute ‘read‘"} skipping: [192.168.180.23] TASK [update bash in redhat 5 version] ***************************************** fatal: [192.168.180.23]: FAILED! => {"changed": false, "failed": true, "msg": "Failure downloading http://mirrors.hustunique.com/centos/5/updates/x86_64/RPMS/bash-3.2-33.el5.1.x86_64.rpm, ‘NoneType‘ object has no attribute ‘read‘"} to retry, use: --limit @/etc/ansible/update_bash.retry PLAY RECAP ********************************************************************* 192.168.180.10 : ok=1 changed=0 unreachable=0 failed=1 192.168.180.2 : ok=1 changed=0 unreachable=0 failed=1 192.168.180.23 : ok=1 changed=0 unreachable=0 failed=1 192.168.180.4 : ok=1 changed=0 unreachable=0 failed=1 192.168.180.5 : ok=1 changed=0 unreachable=0 failed=1 192.168.180.6 : ok=1 changed=0 unreachable=0 failed=1 Server5 : ok=1 changed=0 unreachable=0 failed=1 Server6 : ok=1 changed=0 unreachable=0 failed=1
三,通過playbook 安裝apache
[[email protected] ansible]# vim apache.yml - hosts: web1 user: root gather_facts: True tasks: - name: install apache on CentOS yum: name=httpd state=present when: ansible_os_family =="CentOS" [[email protected] ansible]# ansible-playbook apache.yml PLAY [web1] ******************************************************************** TASK [setup] ******************************************************************* ok: [Server6] ok: [Server5] TASK [install apache on CentOS] ************************************************ skipping: [Server6] skipping: [Server5] PLAY RECAP ********************************************************************* Server5 : ok=1 changed=0 unreachable=0 failed=0 Server6 : ok=1 changed=0 unreachable=0 failed=0
(三)playbook構成
playbook是由一個或多個“play”組成的列表。play的主要功能在於將事先歸並為一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來講所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中即可以讓它們聯同起來按事先編排的機制一同工作。其主要有以下四部分構成
playbooks組成: Target section: 定義將要執行 playbook 的遠程主機組 Variable section: 定義 playbook 運行時需要使用的變量 Task section: 定義將要在遠程主機上執行的任務列表 Handler section: 定義 task 執行完成以後需要調用的任務
而其對應的目錄層為五個,如下:
一般所需的目錄層有:(視情況可變化) vars 變量層 tasks 任務層 handlers 觸發條件 files 文件 template 模板
下面介紹下構成playbook 的四層結構。
1、Hosts和Users
#######示例 - hosts: web1 tasks: - name: test ping connection: remote_user: test sudo: yes
playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的用戶身份執行任務。
hosts:用於指定要執行指定任務的主機其可以是一個或多個由冒號分隔主機組。
remote_user :用於指定遠程主機上的執行任務的用戶。不過remote_user也可用於各task中。也可以通過指定其通過sudo的方式在遠程主機上執行任務其可用於play全局或某任務。此外甚至可以在sudo時使用sudo_user指定sudo時切換的用戶。
user:與remote_user相同
sudo:如果設置為yes,執行該任務組的用戶在執行任務的時候,獲取root權限
sudo_user:如果設置user為breeze,sudo為yes,sudo_user為bernie時,則breeze用戶在執行任務時會獲得bernie用戶的權限
connection:通過什麽方式連接到遠程主機,默認為ssh
gather_facts:除非明確說明不需要在遠程主機上執行setup模塊,否則默認自動執行。如果確實不需要setup模塊傳遞過來的變量,則可以將該選項設置為False
2,任務列表和action
play的主體部分就是任務列表。
任務列表中的各任務按次序逐個在hosts中指定的所有主機上執行即在所有主機上完成第一個任務後再開始第二個。在自上而下運行某playbook時如果中途發生錯誤,所有已執行任務都將回滾因此在更正playbook後重新執行一次即可。
task的目的是使用指定的參數執行模塊,而在模塊參數中可以使用變量。模塊執行是冪等的,這意味著多次執行是安全的,因為其結果均一致。每個task都應該有其name用於playbook的執行結果輸出,建議其內容盡可能清晰地描述任務執行步驟。如果未提供name則action的結果將用於輸出。
定義task的可以使用"action: module options"或"module: options"的格式,推薦使用後者以實現向後兼容。如果action一行的內容過多也可使用在行首使用幾個空白字符進行換行。
tasks: - name: make sure apache is running service: name=httpd state=running 在眾多模塊中只有command和shell模塊僅需要給定一個列表而無需使用“key=value”格式例如 tasks: - 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
3,handlers
用於當關註的資源發生變化時采取一定的操作。
"notify"這個action可用於在每個play的最後被觸發,這樣可以避免多次有改變發生時每次都執行指定的操作,取而代之僅在所有的變化發生完成後一次性地執行指定操作。
在notify中列出的操作稱為handler也即notify中調用handler中定義的操作。
註意:在notify中定義內容一定要和tasks中定義的 - name 內容一樣,這樣才能達到觸發的效果,否則會不生效。
- name: template configuration file template: src=template.j2 dest=/etc/foo.conf notify: - restart memcached - restart apache handler是task列表這些task與前述的task並沒有本質上的不同。 handlers: - name: restart memcached service: name=memcached state=restarted - name: restart apache service: name=apache state=restarted
4,tags
tags用於讓用戶選擇運行或略過playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分,即便如此,有些代碼為測試其確實沒有發生變化的時間依然會非常地長。此時如果確信其沒有變化就可以通過tags跳過這些代碼片斷。
5,示例。下面再給出一個安裝httpd web服務的示例:
[[email protected] ansible]# vim playbook/install_web.yml ########httpd - hosts: all user: root gather_fasks: False vars: packages: httpd tasks: - name: Install httpd yum: name={{ packages }} state=present - name: Cofiguration httpd copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf tags: httpd_conf notify: - restart httpd - name: Start httpd service: name=httpd state=started enabled=no tags: start - name: Add centos user user: name={{ item }} state=absent tags: adduser with_items: - centos - admin handlers: - name: restart httpd service: name=httpd state=restart
本文出自 “清風明月” 博客,請務必保留此出處http://liqingbiao.blog.51cto.com/3044896/1963187
自動化運維工具Ansible實戰(五)playbook使用