• ansible playbook中的变量


    一、变量的优先级

    • extra vars变量(在命令行中使用 -e);优先级最高;
    • 在inventory中定义的连接变量(比如ansible_ssh_user);优先级第二;
    • 大多数的其他变量(命令行转换,play中的变量,include的变量,role的变量等);优先级第三;
    • inventory定义的其他变量;优先级第四;
    • 有系统发现的facts;优先级第五;
    • "role默认变量",这个是最默认的值,很容易丧失优先权。优先级最小;

    另外:在inventory清单列表里定义的变量:单个主机定义的变量优先级高于主机组定义的变量
    经过实验,ansible使用inventory定义变量的优先级顺序从高到低为:
    host_vars下定义变量 ---> inventory中单个主机定义变量 ---> group_vars下定义变量 ---> inventory中组定义变量

    1.1 YAML陷阱

    YAML语法要求如果值以{{ foo }}开头的话,那么就需要将整行用双引号包起来,这是为了确认你不是想声明一个YAML字典。
    如下面配置是不行的!!!

    ---
    - hosts: app_servers
      vars:
        app_path: {{ base_path }}/data/web
    

    应该改成下面这样:

    ---
    - hosts: app_servers
      vars:
        app_path: "{{ base_path }}/data/web"
    

    二、 Ansbile-playbook变量配置方法

    2.1 在inventory主机清单文件中定义变量

    可以直接定义在主机清单文件/etc/ansible/hosts中,表明该变量只对对应的主机或者组有效,对其余的主机和组无效。

    示例:

    $ egrep -v "^#|^$" /etc/ansible/hosts 
    10.4.7.101 key=20180101
    10.4.7.102 key="niubility"
    
    $ vim ansi.yml 
    ---
    - hosts: all
      gather_facts: False
      tasks:
        - name: haha
          debug: msg="the {{ inventory_hostname }} value is {{ key }}"
    
    # 执行结果(注意inventory_hostname代表inventory列表列表里被控节点的主机名):
    
    $ ansible-playbook ansi.yml 
    
    PLAY [all] **************************************************************************************************************************************
    
    TASK [haha] *************************************************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "the 10.4.7.101 value is 20180101"
    }
    ok: [10.4.7.102] => {
        "msg": "the 10.4.7.102 value is niubility"
    }
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    10.4.7.102                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    

    2.2 通过host_vars和group_vars目录来定义变量

    /etc/ansible/目录是linux系统上ansible默认的配置文件目录(Mac系统上的话,其默认配置目录是在/usr/local/etc/ansible/),在该目录下创建host_varsgroup_vars两个目录用来存放定义变量的文件。

    针对单个主机的变量

    $ cat /etc/ansible/host_vars/10.4.7.101
    ---
    user: root
    pass: root@123
    

    针对test组的变量

    $ cat /etc/ansible/group_vars/test
    ---
    user: work
    pass: work@123
    

    在inventory清单列表文件里,单个主机定义的变量优先级高于主机组定义的变量

    2.3 通过var_files定义变量

    $ cat vars.yml 
    ---
    key: jiayou
    
    $ cat bo.yml 
    ---
    - hosts: all
      gather_facts: False
      vars_files:
          - vars.yml
      tasks:
        - name: display
          debug: msg="the {{ inventory_hostname }} valus is {{ key }}"
    
    $ ansible-playbook bo.yml
    
    PLAY [all] **************************************************************************************************************************************
    
    TASK [display] **********************************************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "the 10.4.7.101 valus is jiayou"
    }
    ok: [10.4.7.102] => {
        "msg": "the 10.4.7.102 valus is jiayou"
    }
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    10.4.7.102                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    

    2.4 通过vars_prompt交互式传入变量

    在playbook中定义vars_prompt的变量名和交互式提示信息,就可以实现在运行playbook时,通过交互的传入变量值。
    private字段:用来定义交互时是否回显输入的值,默认private为yes;
    default字段:用来定义变量的默认值。

    $ cat prom.yml 
    ---
    - hosts: test
      remote_user: root
      vars_prompt:
          - name: "var1"
            prompt: "please input you name"
            private: no
          - name: "var2"
            prompt: "please input you age"
            private: yes
            default: 18
      tasks:
          - name: display var1
            debug: msg="your name of var1 is {{ var1 }}"
          - name: display var2
            debug: msg="you age of var2 is {{ var2 }}"
    
    $ ansible-playbook prom.yml 
    please input you name: lvzhenjiang    # 把输入的内容传递给变量var1。输入的值显示出来!
    please input you age [18]:           # playbook中定义默认值是18,如果不输入便是18,但是输入的值不显示出来!比如这里输入的23
    
    PLAY [test] *************************************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************************************
    ok: [10.4.7.101]
    
    TASK [display var1] *****************************************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "your name of var1 is lvzhenjiang"
    }
    
    TASK [display var2] *****************************************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "you age of var2 is 23"
    }
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    

    2.5 通过ansible-playbook命令行定义变量!即参数传入变量

    除了vars_promptvars_files,也可以通过Ansible命令行发送变量。如果想要编写一个通用的发布playbook时则特别有用!你可以传递应用的版本以便部署。例如下面命令(注意: --extra-vars 相等于 -e)

    $ cat exap.yml 
    ---
    - hosts: '{{hosts}}'
      remote_user: '{{user}}'
      tasks:
        - name: "一个测试"
          debug: msg="your hosts is {{hosts}}, user is {{user}}"
    
    $  ansible-playbook exap.yml -e "hosts=test user=root" 
    [WARNING]: Found variable using reserved name: hosts
    
    PLAY [test] *************************************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************************************
    ok: [10.4.7.101]
    
    TASK [一个测试] *************************************************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "your hosts is test, user is root"
    }
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
    

    也可以将参数放在文件里面进行传递(注意命令行里要是用"@文件名"):

    # 同样使用上面的例子
    $ cat anhui.yml 
    ---
    hosts: test
    user: root
    
    $ ansible-playbook exap.yml -e "@anhui.yml"
    [WARNING]: Found variable using reserved name: hosts
    
    PLAY [test] *************************************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************************************
    ok: [10.4.7.101]
    
    TASK [一个测试] *************************************************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "your hosts is test, user is root"
    }
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  
    

    2.6 在playbook剧本中定义变量

    在playbook中定义变量需要用到Ansible的vars模块,可以将所有需要用到的变量统一在vars模块下定义,定义格式需要遵循YAML语言格式:

    语法格式:

    vars:
      - var1: value1
      - var2: value2
      - var3: value3
      - ....: .....
    

    示例如下:

    $ cat playbook.yml 
    ---
    - hosts: test
      remote_user: root
      vars:
        - dir1: /root/Ansible
        - dir2: /root/Ansible/test1
        - dir3: /root/Ansible/test2
      tasks:
        - name: Create New Folder
          file: name={{ dir1 }} state=directory
        - name: Create New Folder
          file: name={{ dir2 }} state=directory
        - name: Create New Folder
          file: name={{ dir3 }} state=directory
    
    $ ansible-playbook playbook.yml 
    
    PLAY [test] *************************************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************************************
    ok: [10.4.7.101]
    
    TASK [Create New Folder] ************************************************************************************************************************
    changed: [10.4.7.101]
    
    TASK [Create New Folder] ************************************************************************************************************************
    changed: [10.4.7.101]
    
    TASK [Create New Folder] ************************************************************************************************************************
    changed: [10.4.7.101]
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    

    2.7 通过roles角色定义变量

    在Ansible的roles中定义变量,需要将变量及值的键值对形式写到roles的vars目录下的main.yml文件中,同样适用YAML语言格式,格式如下:

    var1: value1
    var2: value2
    var3: value3
    

    但是请注意:通过Roles定义的变量只适用于当前roles。

    # roles目录结构
    $ tree .
    .
    ├── hosts
    ├── playbook.yml
    └── test
        ├── files
        ├── tasks
        │   └── main.yml
        ├── templates
        └── vars
            └── main.yml
    
    5 directories, 4 files
    
    $ cat test/tasks/main.yml 
    - name: create directory
      file: name={{ dir }} state=directory
    - name: Get IP Address
      shell: echo `{{ cmd }}` >> {{ dir }}/{{ file }}
    
    $ cat test/vars/main.yml 
    cmd: hostname -I
    
    $ cat playbook.yml 
    ---
    - hosts: test
      remote_user: root
      roles:
        - test
        
    $ cat hosts 
    [test]
    10.4.7.101 dir=/root/node2
    10.4.7.102 dir=/root/node1
    
    [node1]
    10.4.7.100
    
    [test:vars]
    file=hostname.txt
    
    $ ansible-playbook -i hosts  playbook.yml 
    
    PLAY [test] *************************************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************************************
    ok: [10.4.7.101]
    ok: [10.4.7.102]
    
    TASK [test : create directory] ******************************************************************************************************************
    ok: [10.4.7.101]
    ok: [10.4.7.102]
    
    TASK [test : Get IP Address] ********************************************************************************************************************
    changed: [10.4.7.102]
    changed: [10.4.7.101]
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    10.4.7.102                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    

    2.8 使用Facts获取的信息

    还有其它地方可以获取变量, 这些变量是自动发现的,而不是用户自己设置的。Facts通过访问远程系统获取相应的信息,一个很好的例子就是远程主机的IP地址或者操作系统是什么。

    $ ansible test -m setup
    # 使用以下命令可以查看哪些信息是可用的(test是上面在/etc/ansible/hosts列表文件中配置的主机群组)
    
    $ ansible test -m setup|grep "ansible_python_version"
            "ansible_python_version": "2.7.5", 
    # 在playbook中这样引用上面被控制主机的python版本: {{ ansible_python_version }}
    
    $ ansible test -m setup|grep "ansible_nodename"
            "ansible_nodename": "template", 
    # 可以在playbook中这样引用上面被控制主机的主机名: {{ ansible_nodename }}
    
    $ ansible test -m setup | grep "ansible_hostname"
            "ansible_hostname": "template",
    # 被控制主机的主机名变量还可以是: {{ ansible_hostname }}
    

    如果关闭Facts,可以大大提高ansible的执行速度 ,关闭方法如下:

    $ cat anhui.yml
    ---
    - hosts: test
      gather_facts: no
    

    2.9 register注册变量

    变量的另一个主要用途是在运行命令时,把命令结果存储到一个变量中,不同模块的执行结果是不同的。运行playbook时使用-v选项可以看到可能的结果值,ansible执行任务的结果值可以保存在变量中,以便稍后使用它。register方式主要用于在task之间传递变量。

    $ cat /etc/ansible/hosts
    [test]
    10.4.7.101
    10.4.7.102
    
    $ cat register.yml
    ---
    - hosts: test
      remote_user: root
      tasks:
          - name: register bo_test
            shell: hostname -I
            register: info
          - name: display info
            debug: msg="this host ip is {{ info['stdout'] }}"
    
    $ ansible-playbook register.yml
    
    PLAY [test] *************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************
    ok: [10.4.7.102]
    ok: [10.4.7.101]
    
    TASK [register bo_test] *************************************************************************************************
    changed: [10.4.7.102]
    changed: [10.4.7.101]
    
    TASK [display info] *****************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "this host ip is 10.4.7.101 "
    }
    ok: [10.4.7.102] => {
        "msg": "this host ip is 10.4.7.102 "
    }
    
    PLAY RECAP **************************************************************************************************************
    10.4.7.101                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    10.4.7.102                 : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    2.10 hostvars 变量

    该变量用于引用其他主机上收集的facts中的数据,或者引用其他主机的主机变量、主机组变量。即从一台远程主机获取另一台远程主机的变量。

    $ cat /etc/ansible/hosts
    [test]
    10.4.7.101 addr=beijing
    10.4.7.102 user=shibo age=39
    
    $ cat test.yml
    ---
    - hosts: test
      remote_user: root
      gather_facts: False
      tasks:
        - name: this is test1
          debug: msg="She is come from {{ hostvars['10.4.7.101']['addr'] }}"
        - name: this is test2
          debug: msg="I am {{ hostvars['10.4.7.102']['user'] }}, and age is {{ hostvars['10.4.7.102']['age'] }}"
    
    $ ansible-playbook test.yml
    
    PLAY [test] *************************************************************************************************************
    
    TASK [this is test1] ****************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "She is come from beijing"
    }
    ok: [10.4.7.102] => {
        "msg": "She is come from beijing"
    }
    
    TASK [this is test2] ****************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": "I am shibo, and age is 39"
    }
    ok: [10.4.7.102] => {
        "msg": "I am shibo, and age is 39"
    }
    
    PLAY RECAP **************************************************************************************************************
    10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    10.4.7.102                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    2.11 列表变量、循环变量、字典变量

    1)ansible的变量不仅可以是单个的值,也可以为列表,即ansible传列表作为变量

    $ cat test.yml
    ---
    - hosts: test
      remote_user: root
      gather_facts: False
      vars:
        - list: [1,2,3]
      tasks:
        - name: echo
          debug: msg="{{ list }}"
    
    $ ansible-playbook test.yml
    
    PLAY [test] *************************************************************************************************************
    
    TASK [echo] *************************************************************************************************************
    ok: [10.4.7.101] => {
        "msg": [
            1,
            2,
            3
        ]
    }
    ok: [10.4.7.102] => {
        "msg": [
            1,
            2,
            3
        ]
    }
    
    PLAY RECAP **************************************************************************************************************
    10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    10.4.7.102                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=
    

    2)循环列表

    结合循环,这个特性就变得很有用;以参数传递列表给playbook,不用在playbook中固定循环的次数与内容。

    $ cat test.yml
    ---
    - hosts: 10.4.7.101
      remote_user: root
      gather_facts: False
      vars:
        - list: [1,2,3]
      tasks:
        - name: this is loop
          debug: msg="{{ item }}"
          with_items: '{{list}}'
    
    $ ansible-playbook test.yml
    
    PLAY [10.4.7.101] *******************************************************************************************************
    
    TASK [this is loop] *****************************************************************************************************
    ok: [10.4.7.101] => (item=1) => {
        "msg": 1
    }
    ok: [10.4.7.101] => (item=2) => {
        "msg": 2
    }
    ok: [10.4.7.101] => (item=3) => {
        "msg": 3
    }
    
    PLAY RECAP **************************************************************************************************************
    10.4.7.101                 : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    *************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!***************
  • 相关阅读:
    CF854C Planning优先队列|set
    暑假集训-8.9总结
    暑假集训-8.6总结
    AcWing 206. 石头游戏 矩阵乘法|矩阵快速幂
    暑假集训-8.5总结
    KMP 和 扩展KMP
    暑假集训-8.4总结
    暑假集训-8.3总结
    2019牛客暑期多校第二场题解FH
    AcWing 196. 质数距离
  • 原文地址:https://www.cnblogs.com/lvzhenjiang/p/14385777.html
Copyright © 2020-2023  润新知