美文网首页Ansible
Ansible之when条件语句

Ansible之when条件语句

作者: GoGooGooo | 来源:发表于2018-05-18 17:18 被阅读6次
    1. When语句
      有时候用户有可能需要某一个主机越过某一个特定的步骤.这个过程就可以简单的像在某一个特定版本的系统上少装了一个包一样或者像在一个满了的文件系统上执行清理操作一样.
      这些操作在Ansible上,若使用when语句都异常简单.When语句也含Jinja2表达式,
      第一个例子:

      tasks:
        - name: "shutdown Debian flavored systems"
          command: /sbin/shutdown -t now
          when: ansible_os_family == "Debian"
      

      如果你在RedHat系列linux系统执行,就不会被执行

      第二个例子:

      #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模块后续会介绍。

      第三个例子:

      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的这台服务器才执行

      - name: Copy file to client
            copy: src=/etc/ansible/test.txt dest=/usr/local/src
            when: "host=='server'"
      

      带管道的when语句

      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
      
    2. 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了。

    3. 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
      

    相关文章

      网友评论

        本文标题:Ansible之when条件语句

        本文链接:https://www.haomeiwen.com/subject/dfagdftx.html