• 013.Ansible Playbook include


    一 include

    当项目越大,tasks越多的时候。如果将多有的task写入一个playbook中,可读性很差,就需要重新组织playbook

    可以把一个playbook分成若干份晓得palybook文件,在主配置文件中,把小文件引入进来,就是include

    include tasks

    [root@node1 ansible]# mkdir tasks

    [root@node1 ansible]# cd tasks

    [root@node1 tasks]# vim host.yml

    [root@node1 tasks]#

    - name: modify hostname
      hostname:
        name: test.example.com

    [root@node1 tasks]# vim dns.yml

    - name: modify resolv.conf
    copy: 
    src: files.resolv.conf
    dest: /etc/resolv.conf
    - name: /etc/resolvconf/base
    copy:
    src: files.resolv.conf
    dest: /etc/resolv.conf
    when: ansible_distribution == "Ubuntu"

    [root@node1 tasks]# mkdir files

    [root@node1 tasks]# vim files/resolv.conf 

    # Generated by NetworkManager
    nameserver 8.8.4.4

    [root@node1 tasks]# cd ../

    [root@node1 ansible]# vim main.yml

    - hosts: demo2.example.com
      tasks:
        - debug:
            msg: "start tasks"
        - include: tasks/host.yml
        - include: tasks/dns.yml
        - debug:
            msg: "执行结束"

    执行

    [root@node1 ansible]# ansible-playbook main.yml 

    TASK [debug] **************************************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "start tasks"
    }
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    TASK [modify resolv.conf] *************************************************************************************************************************
    changed: [demo2.example.com]
    
    TASK [/etc/resolvconf/base] ***********************************************************************************************************************
    skipping: [demo2.example.com]
    
    TASK [debug] **************************************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "执行结束"
    }

    检查:

    也可以引入handlers

    [root@node1 ansible]# vim tasks/nginx.yml

    - name: install nginx
      yum:
        name:  nginx
        state: present
    - name: mpdify nginx.conf
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: 
        - restart nginx
    - name: start nginx
      systemd: 
    name: nginx state: started enabled: yes

    [root@node1 ansible]# vim tasks/handlers.yml

    - name: restart nginx
    systemd:
    name: nginx
    state: restarted

    [root@node1 ansible]# vim main.yml

    - hosts: demo2.example.com
      tasks:
        - debug:
            msg: "start tasks" 
        - include: tasks/host.yml
        - include: tasks/dns.yml
        - include: tasks/nginx.yml
        - debug:
            msg: "执行结束"
      handlers:
        - include: tasks/handlers.yml

    二 include_tasks

    2.1  include_asks基本使用

    在前面尝试使用的是include,但是在后续版本,可能会取消这种方式,使用include_tasks这总方式开始引入

    include可以包含tasks,handlers,playbook,incelude_task专门用来包含tasks

    [root@node1 ansible]# vim main.yml

    - hosts: demo2.example.com
      tasks:
        - debug:
            msg: "start tasks"
        - include_tasks: tasks/host.yml
        - include_tasks: tasks/dns.yml
        - include_tasks: tasks/nginx.yml
        - debug:
            msg: "执行结束"
      handlers:
        - include_tasks: tasks/handlers.yml

    执行

    TASK [debug] **************************************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "start tasks"
    }
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/dns.yml for demo2.example.com
    
    TASK [modify resolv.conf] *************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [/etc/resolvconf/base] ***********************************************************************************************************************
    skipping: [demo2.example.com]
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/nginx.yml for demo2.example.com
    
    TASK [install nginx] ******************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [start nginx] ********************************************************************************************************************************
    changed: [demo2.example.com]
    
    TASK [debug] **************************************************************************************************************************************
    ok: [demo2.example.com] => {
        "msg": "执行结束"
    }

    当我们使用include_tasks,本身会被当做一个tasks,这个task会把文件输入到控制台中,inclue是透明的,include_tasks是可见的。更像是一个任务,这个任我包含了其他的一些任任务,

    在ansible2.7之中,include_task还加入了新的参数

    include_tasks:
      file: in.yml

    2.2 include_tasks使用tags

    如果为include添加tags,那么tags是对include中的所有任务生效的,所以当调用include的tag时,include中的所有任务都会执行

    但是对include_tasks添加tag,只会对include_tasks本身生效,include_tasks中的所有任务都不生效

    - hosts: demo2.example.com
      tasks:
        - debug:
            msg: "start tasks"
        - include_tasks: 
            file:  tasks/host.yml
          tags: host
    
        - include_tasks: 
            file: tasks/dns.yml
          tags: dns
    
        - include_tasks:
            file: tasks/nginx.yml
          tags: nginx
    
        - debug:
            msg: "执行结束"
      handlers:
        - include_tasks: tasks/handlers.yml

    [root@node1 ansible]# ansible-playbook main.yml --tags="host"

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

    只执行自己本身,里面的任务并没有执行

    若要执行include_tasks里面的任务,就需要为执行文件打tags

    - hosts: demo2.example.com
      tasks:
        - debug:
            msg: "start tasks" 
        - include_tasks:
            file:  tasks/host.yml
            apply:
              tags: H1
          tags: always    #这里必须指定always,因为host.yml执行前提是,include_tasks执行
    
        - include_tasks: 
            file: tasks/dns.yml
          tags: dns
    
        - include_tasks: 
            file: tasks/nginx.yml
          tags: nginx 
     
        - debug:
            msg: "执行结束"
      handlers:
        - include_tasks: tasks/handlers.yml

    执行

    root@node1 ansible]# ansible-playbook main.yml --tags="H1"

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    三 import_tasks使用

    import_tasks include_task用法类似,都是包含一个任务列表

    [root@node1 ansible]# vim main.yml 

    - hosts: demo2.example.com
      tasks:
        - debug:
            msg: "start tasks" 
        - include_tasks:
            file:  tasks/host.yml
            apply:
              tags: H1
          tags: always
    
        - import_tasks: tasks/dns.yml
          tags: dns
    
        - include_tasks: 
            file: tasks/nginx.yml
          tags: nginx 
     
        - debug:
            msg: "执行结束"
      handlers:
        - include_tasks: tasks/handlers.yml

    [root@node1 ansible]# ansible-playbook main.yml --tags="dns"

    3.1 include_tasks和import_task区别一

    当执行import_task的tags的时候,对应的文件的任务也会执行,但是自己本身是透明的,和include一样

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    
    TASK [modify resolv.conf] *************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [/etc/resolvconf/base] ***********************************************************************************************************************
    skipping: [demo2.example.com]
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0  

    import_tasks是静态的,被import的文件,在被playbook加载时就预处理了,include_tasks是动态的,被include的文件在playbook运行后,才开始处理

    [root@node1 ansible]# cat import_ex.yml
    - hosts: demo2.example.com
      gather_facts: no
      vars:
        file_name: tasks/host.yml
      tasks:
        - include_tasks: "{{ file_name }}"
        - import_tasks: "{{ file_name }}"

    执行

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    修改配置

    [root@node1 ansible]# cat import_ex.yml
    - hosts: demo2.example.com
      gather_facts: no
      #vars:
      #  file_name: tasks/host.yml
      tasks:
        - set_facts:
            file_name: tasks/host.yml
        - include_tasks: "{{ file_name }}"
        #- import_tasks: "{{ file_name }}"

    [root@node1 ansible]# ansible-playbook import_ex.yml

    [root@node1 ansible]# ansible-playbook  import_ex.yml 
    
    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [set_fact] ***********************************************************************************************************************************
    ok: [demo2.example.com]
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    但是使用import就会报错,原因是include在运行之后加载,但是import在运行之前加载,运行playbook之前,是没有file_name的参数选项,报错  

    [root@node1 ansible]# vim import_ex.yml

    [root@node1 ansible]# cat import_ex.yml
    - hosts: demo2.example.com
      gather_facts: no
      #vars:
      #  file_name: tasks/host.yml
      tasks:
        - set_facts:
            file_name: tasks/host.yml
        #- include_tasks: "{{ file_name }}"
        - import_tasks: "{{ file_name }}"

    [root@node1 ansible]# ansible-playbook import_ex.yml

    ERROR! Error when evaluating variable in import path: {{ file_name }}.
    
    When using static imports, ensure that any variables used in their names are defined in vars/vars_files
    or extra-vars passed in from the command line. Static imports cannot use variables from facts or inventory
    sources like group or host vars.

    3.2 include_tasks和import_task区别二

    如果想对包含的列表进行循环操作,只能使用include_tasks。import_task不支持循环操作,即loop对include内容进行循环操作时,只能使用include_tasks,不能使用import_task

    [root@node1 ansible]# cat import_ex.yml
    - hosts: demo2.example.com
      gather_facts: no
      vars:
        file_name: tasks/host.yml
      tasks:
        #- set_fact:
        #    file_name: tasks/host.yml
        - include_tasks: "{{ file_name }}"
        - import_tasks: "{{ file_name }}"
          loop:
            - 1
            - 2

    执行

    [root@node1 ansible]# ansible-playbook  import_ex.yml 

    ERROR! You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.
    
    The error appears to be in '/etc/ansible/import_ex.yml': line 9, column 7, but may
    be elsewhere in the file depending on the exact syntax problem.
    
    The offending line appears to be:
    
        - include_tasks: "{{ file_name }}"
        - import_tasks: "{{ file_name }}"
          ^ here
    We could be wrong, but this one looks like it might be an issue with
    missing quotes. Always quote template expression brackets when they
    start a value. For instance:
    
        with_items:
          - {{ foo }}
    
    Should be written as:
    
        with_items:
          - "{{ foo }}"

    使用include_tasks

    [root@node1 ansible]# cat import_ex.yml
    - hosts: demo2.example.com
      gather_facts: no
      vars:
        file_name: tasks/host.yml
      tasks:
        #- set_fact:
        #    file_name: tasks/host.yml
        - include_tasks: "{{ file_name }}"
          loop:
            - 1
            - 2
        - import_tasks: "{{ file_name }}"

    执行

    PLAY [demo2.example.com] **************************************************************************************************************************
    
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    included: /etc/ansible/tasks/host.yml for demo2.example.com
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    TASK [modify hostname] ****************************************************************************************************************************
    changed: [demo2.example.com]
    
    PLAY RECAP ****************************************************************************************************************************************
    demo2.example.com          : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

    3.3 include_tasks和import_task区别三

    在使用when的条件判断时,有着本质的区别

    当include_tasks使用when时候,when只针对include_tasks任务本身,当执行被包含的认识时,不会对包含的任务进行条件判断

    当import_tasks使用when时,when对应的条件会被用于import的每一个任务,当执行import的任务时,会对每一个包含的任务进行条件判断

    [root@node1 ansible]# vim import_ex.yml 

    - hosts: demo2.example.com
      gather_facts: no
      vars:
        file_name: tasks/host.yml
        num: 1
      tasks:
        - include_tasks: "{{ file_name }}"
          when: num == 1
    
        - set_fact:
            num: 1
    
        - import_tasks: "{{ file_name }}"
          when: num == 1

    执行

    [root@node1 ansible]# vim tasks/host.yml

    - name: modify num to 0
      set_fact:
        num: 0
    - name: modify hostname
      hostname:
        name: test.example.com

    [root@node1 ansible]# ansible-playbook import_ex.yml

    PLAY [demo2.example.com] **************************************************************************************************************************
    TASK [include_tasks] ******************************************************************************************************************************
    included: /etc/ansible/tasks/host.yml for demo2.example.com    #include满足条件,自己本身任务执行
    TASK [modify num to 0] ****************************************************************************************************************************
    ok: [demo2.example.com]           #包含的第一个任务执行
    TASK [modify hostname] ****************************************************************************************************************************
    ok: [demo2.example.com]            #包含的第二个任务执行
    TASK [set_fact]
    *********************************************************************************************************************************** ok: [demo2.example.com] TASK [modify num to 0] **************************************************************************************************************************** ok: [demo2.example.com] #import第一个满足条件执行,这是num设为0 TASK [modify hostname] **************************************************************************************************************************** skipping: [demo2.example.com] #第二个任务在进行比较,不满足,直接跳过 PLAY RECAP **************************************************************************************************************************************** demo2.example.com : ok=5 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

    在include只要条件满足,就会全部执行包含的内容,import_tasks会对每一个任务做判断,在确定是否执行


    博主声明:本文的内容来源主要来自誉天教育晏威老师,由本人实验完成操作验证,需要的博友请联系誉天教育(http://www.yutianedu.com/),获得官方同意或者晏老师(https://www.cnblogs.com/breezey/)本人同意即可转载,谢谢!

  • 相关阅读:
    Git 简易手册
    【Swift】UILabel 设置内边距
    【iOS】屏幕适配之NSLayoutConstraint
    【Swift】TTTAttributedLabel使用小记
    【iOS】Alamofire库在iOS7下设置Head无效的问题
    【iOS】在Swift中使用JSONModel
    【读书笔记】100个Switf必备tips
    【读书笔记】长尾理论
    【读书笔记】结网
    嗯,农民伯伯的2014就是这些
  • 原文地址:https://www.cnblogs.com/zyxnhr/p/12819241.html
Copyright © 2020-2023  润新知