• Ansible之变量


    一)Ansible变量介绍

    我们在PlayBook⼀节中,将PlayBook类⽐成了Linux中的shell。
    那么它作为⼀⻔Ansible特殊的语⾔,肯定要涉及到变量定义、控
    制结构的使⽤等特性。
    在这⼀节中主要讨论变量的定义和使⽤

    二)变量命名规则

    变量的名字由字母、下划线和数字组成,必须以字母开头。
    如下变量命名为正确格式:

    good_a
    ok_b
    
    • 1
    • 2

    如下是错误的变量名:

    _aaa
    2_bb
    
    • 1
    • 2

    保留关键字不可以作为变量名称:

    add, append, as_integer_ratio, bit_length,
    capitalize, center, clear,
    conjugate, copy, count, decode, denominator,
    difference,
    difference_update, discard, encode, endswith,
    expandtabs,
    extend, find, format, fromhex, fromkeys, get,
    has_key,
    hex, imag, index, insert, isalnum, intersection,
    intersection_update, isalpha, isdecimal, isdigit,
    isdisjoint, is_integer, islower,
    isnumeric, isspace, issubset, issuperset, istitle,
    isupper,
    items, iteritems, iterkeys, itervalues, join, keys,
    ljust, lower,
     lstrip, numerator, partition, pop, popitem, real,
    remove,
     replace, reverse, rfind, rindex, rjust, rpartition,
    rsplit, rstrip,
     setdefault, sort, split, splitlines, startswith,
    strip, swapcase,
    symmetric_difference, symmetric_difference_update,
    title,
    translate, union, update, upper, values, viewitems,
    viewkeys,
    viewvalues, zfill
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    三)变量类型

    根据变量的作用范围大体的将变量分为:

    • 全局变量
    • 剧本变量
    • 资产变量

    但这是一种较为粗糙的划分,不足以囊括Ansible中的所有变量。

    1.全局变量

    全局变量,是我们使⽤ansible 或使⽤ansible-playbook 时,⼿动
    通过 -e 参数传递给Ansible 的变量。
    通过ansible 或 ansible-playbook 的 help 帮助, 可以获取具体格
    式使⽤⽅式:

    # ansible-playbook -h | grep var
      -e EXTRA_VARS, --extra-vars EXTRA_VARS
                            set additional variables as key=value or YAML/JSON, if
    
    # ansible -h |grep var
                            path for many features including roles/ group_vars/
      -e EXTRA_VARS, --extra-vars EXTRA_VARS
                            set additional variables as key=value or YAML/JSON, if
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    例子

    传递普通的key=value 的形式

    ansible all -i localhost, -m debug -a "msg='my key is {{ key }}'" -e "key=value"
    
    • 1

    image.png
    传递⼀个YAML/JSON 的形式(注意不管是YAML还是JSON,它们的最终格式⼀定要是⼀个字典)
    Json格式----
    image.png

     ansible all -i localhost, -m debug -a "msg='name is {{ name }}, type is {{ type }}'" -e @a.json
    
    • 1

    image.png
    Yml格式–
    image.png

    ansible all -i localhost, -m debug -a "msg='name is {{ name }}, type is {{ type }}'" -e @a.yml
    
    • 1

    image.png

    2.剧本变量

    在这只介绍两种最常用的定义方式:

    a.通过PLAY属性vars定义
    ---
    - name: test play vars
     hosts: all
     vars:
     user: yu
     home: /home/yu
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    b.通过PLAY属性var_files定义

    当通过vars属性定义的变量很多时,这个Play就会感觉特别臃肿。
    此时我们可以将变量单独从Play中抽离出来,形成单独的YAML ⽂件。

    ---
    - name: test play vars
      hosts: all
      vars_files:
      - vars/users.yml
    
    • 1
    • 2
    • 3
    • 4
    • 5

    image.png

    c.在Playbook中使用变量的注意点
    ---
    # 这⾥我们将上⾯的Playbook中引⽤变量的部分进⾏修改,去掉了双
    引号。
    - name: test play vars
      hosts: all
      vars:
      user: lilei
      home: /home/lilei
      tasks:
      - name: create the user {{ user }}
        user:
     # 注意这⾥将 "{{ user }}" 改成了 {{ user }}
          name: {{ user }}
          home: "{{ home }}”
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    执行以上的Playbook时,就会出现以下的错误:
    image.png
    这样错误的主要原因是PlayBook 是YAML 的⽂件格式, 当Ansible 分析YAML ⽂件时,有可能会误认为字典。name: {{ user }} 是⼀个字典的开始。因此加针对变量的使⽤,加上了双引号,避免Ansible错误解析。

    3.资产变量

    资产变量分为主机变量和主机组变量,分别针对资产中的单个主机
    和主机组。

    3.1主机变量

    下面给大家一个实例,在以下资产中,定义了一个主机变量lilei,此变量只针对192.168.244.130这台服务器有效。
    image.png
    接下来掩饰验证
    先获取定义的变量值

    ansible 192.168.244.131 -i hostsandhostvars -m debug -a "msg='{{user}} {{port}}'"
    
    • 1

    image.png
    可以看见运行结果
    那么未获取到定义的变量值,因为user这个变量针对192.168.244.130主机无效

    ansible 192.168.244.130 -i hostsandhostvars -m debug -a "var=user"
    
    • 1

    image.png

    3.2主机组变量

    以下资产中,定义了⼀个组变量home ,此变量将针对webservers 这个主机组中的所有服务器有效。
    image.png
    验证
    home是web_servers的组变量,会针对这个组内的所有服务器生效。

    ansible webservers -i hostsandgroupvars -m debug -a "var=home"
    
    • 1

    image.png

    3.3主机变量vs主机组变量

    接下来讨论一个问题,如果主机变量和组变量在同一资产中重名,会发生什么呢?
    image.png
    我们在资产中定义主机变量和组变量user,那么此时我们可以发现192.168.244.130这台机器的主机变量user的优先级更高。

    ansible webservers -i hosts_2 -m debug -a "var=user"
    
    • 1

    image.png

    3.4变量的继承

    资产可以继承,那么变量当然也可以继承。
    image.png
    在资产继承的同时,对应的变量也会发生继承。

    ansible allservers -i hosts_3 -m debug -a "var=user"
    
    • 1

    image.png

    ansible dbservers -i hosts_3 -m debug -a "var=user"
    
    • 1

    image.png

    ansible webservers -i hosts_3 -m debug -a "var=user"
    
    • 1

    image.png

    3.5 Inventory内置变量的说明

    内置变量一般都会以ansible_为前缀

    ansible_ssh_host
    #将要连接的远程主机名与你想要设定的主机的别名不同的话,可通过此变量设置.
    ansible_ssh_port
    #ssh端⼝号.如果不是默认的端⼝号,通过此变量设置.
    ansible_ssh_user
    #默认的 ssh ⽤户名
    ansible_ssh_pass
    #ssh 密码(这种⽅式并不安全,官⽅强烈建议使⽤ --askpass 或 SSH 密钥)
    ansible_sudo_pass
    #sudo 密码(这种⽅式并不安全,官⽅强烈建议使⽤ --asksudo-pass)
    ansible_sudo_exe (new in version 1.8)
    #sudo 命令路径(适⽤于1.8及以上版本)
    ansible_ssh_private_key_file
    #ssh 使⽤的私钥⽂件.适⽤于有多个密钥,⽽你不想使⽤ SSH代理的情况.
    ansible_python_interpreter
    #⽬标主机的 python 路径.适⽤于的情况: 系统中有多个Python, 或者命令路径不是"/usr/bin/python",⽐如 /usr/local/bin/python3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    4.Facts变量

    Facts变量不包含在前⽂中介绍的全局变量、剧本变量及资产变量
    之内。
    Facts变量不需要我们⼈为去声明变量名及赋值。
    它的声明和赋值完全有Ansible 中的 setup 模块帮我们完成。
    它收集了有关被管理服务器的操作系统版本、服务器IP地址、主机名,磁盘的使⽤情况、CPU个数、内存⼤⼩等等有关被管理服务器的私有信息。
    在每次PlayBook运⾏的时候都会发现在PlayBook执⾏前都会有⼀个Gathering Facts的过程。这个过程就是收集被管理服务器的Facts信息过程。

    4.1手动收集Facts变量
    ansible all -i localhost, -c local -m setup
    
    • 1

    image.png
    运行结果有很多,我就不全部截取了

    4.2过滤Facts

    通过刚刚的⼿动收集Facts,我们发现facts 信息量很⼤。 能不能有针对性的显示我们想要的信息呢?
    可以通过使⽤Facts 模块中的filter参数去过滤我们想要的信息。
    仅获取服务器的内存情况信息

    ansible all -i localhost, -m setup -a "filter=*memory*" -c local
    
    • 1

    image.png
    仅获取服务器的磁盘挂载情况

    ansible all -i localhost, -m setup -a "filter=*mount*" -c local
    
    • 1

    image.png

    4.3在Playbook中去使用Facts变量

    默认情况下,在执⾏PlayBook的时候,它会去⾃动的获取每台被管理服务器的facts信息。

    ---
    - name: a play example
     hosts: all
     remote_user: root
     tasks:
     - name: install nginx package
     yum: name=nginx state=present
     - name: copy nginx.conf to remote server
     copy: src=nginx.conf
    dest=/etc/nginx/nginx.conf
     - name: start nginx server
     service:
     name: nginx
     enabled: true
     state: started
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    将这段playbook命名为test_1.yml并且执行

    ansible-playbook test_1.yml
    
    • 1

    image.png
    可以像使用其他变量一样,去使用facts变量

    ---
    - name: print facts variable
      hosts: all
      tasks:
      - name: print facts variable
        debug:
           msg: "The default IPV4 address is {{ ansible_default_ipv4.address }}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在playbook中去关闭Facts变量的获取
    若在整个playbook的执行过程中,完全未使用过Facts变量,此时我们可以将其关闭,以加快playbook的执行速度。

    ---
    - name: a play example
      hosts: webservers
      # 关闭 facts 变量收集功能
      gather_facts: no
      remote_user: root
      tasks:
      - name: install nginx package
        yum: name=nginx state=present
      - name: copy nginx.conf to remote server
        copy: src=nginx.conf
              dest=/etc/nginx/nginx.conf
      - name: start nginx server
        service:
          name: nginx
          enabled: true
          state: started
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    将其命名为test_2.yml并且执行

    ansible-playbook -i hosts test_2.yml
    
    • 1

    image.png

    5.注册变量

    往往⽤于保存⼀个task任务的执⾏结果, 以便于debug时使⽤。
    或者将此次task任务的结果作为条件,去判断是否去执⾏其他task任务。
    注册变量在PlayBook中通过register关键字去实现。

    ---
    - name: install a package and print the result
      hosts: webservers
      remote_user: root
      tasks:
      - name: install nginx package
        yum: name=nginx state=present
        register: install_result
      - name: print result
        debug: var=install_result
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    将以上代码命名为test_3.yml并执行

    ansible-playbook test_3.yml
    
    • 1

    image.png

    6.变量优先级

    ⽬前介绍了全局变量、剧本变量、资产变量、Facts变量及注册变量。
    其中Facts变量不需要⼈为去声明、赋值;注册变量只需通过关键字register去声明,⽽不需要赋值。
    ⽽全局变量、剧本变量及资产变量则完全需要⼈为的去声明、赋值。
    变量的优先权讨论,也将着重从这三类变量去分析。
    假如在使⽤过程中,我们同时在全局变量、剧本变量及资产变量声明了同⼀个变量名,那么哪⼀个优先级最⾼呢? 下⾯我们将以实验的形式去验证变量的优先级
    环境准备:
    定义一份资产、且定义了资产变量user
    image.png
    (由于试验机性能问题,我缩减了试验机的数量,读者可自行增加)
    编写一份Playbook、同样定义剧本变量user

    ---
    - name: test variable priority
      hosts: all
      remote_user: root
      vars:
        user: mysql
      tasks:
       - name: print the user value
         debug: msg='the user value is {{ user }}'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    将其命名为test_4.yml
    验证测试–
    同时使用全局变量、剧本变量、资产变量
    当变量user同时定义在全局变量、剧本变量及资产变量中时,全局变量的优先级最⾼。

    ansible-playbook -i hosts test_4.yml -e "user=www"
    
    • 1

    image.png
    同时使用剧本变量和资产变量
    取消全局变量,发现剧本变量的优先级要高于资产变量的优先级

    ansible-playbook -i hosts test_4.yml
    
    • 1

    image.png
    只是用资产变量的情况下
    我们不使用全局变量、且注释掉剧本变量后,资产变量才最终生效。

    ---
    - name: test variable priority
      hosts: all
      remote_user: root
      #vars:
      # user: mysql
      tasks:
       - name: print the user value
         debug: msg='the user value is {{ user }}'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    ansible-playbook -i hosts test_4.yml
    
    • 1

    image.png
    **变量优先级结论 **
    当⼀个变量同时在全局变量、剧本变量和资产变量中定义时,优先级最⾼的是全局变量;其次是剧本变量;最后才是资产变量。

  • 相关阅读:
    JNI 使用案例详解(一)
    【图书管理系统】附源码+教程
    思腾云计算
    Allure精通指南(01)介绍与基本使用
    Java哈希表和哈希冲突
    linux中运行springboot jar包,内存占用多运行时报错
    十二月第一场雪
    mellanox在vmware中的切割
    前端:nodejs多版本管理工具nvm
    基于分布式 KV 存储引擎的高性能 K8s 元数据存储项目 —— KubeBrain
  • 原文地址:https://blog.csdn.net/xiaoyu070321/article/details/132667454