一、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