• Ansible之路——第七章:Ansible的变量


    7.1 变量来源

    • inventoryfile中定义
    • playbook中定义
    • include文件和角色中定义变量
    • 系统facts:ansible hostname -m setup
    • local facts

     

    7.2 变量的使用

    复杂变量可以像字典或者数字一样访问。效果一样

    {{ ansible_eth0["ipv4"]["address"] }} 
    或者 
    {{ ansible_eth0.ipv4.address }}
    

     

    7.3 本地变量

    ansible hostname -m setup 可以获取固定的系统facts, 在playbook中设置gather_facts:yes,playbook会自动获取远程机器的facts。

    但是ansible也支持用户自定义facts,例如:

    vim /etc/ansible/facts.d/preferences.fact:
    [general]
    asdf=1
    bar=2

    则可以使用变量 {{ ansible_local.preferences.general.asdf }},如:

    7.4 魔法变量(内置变量)

    • hostvars:可以让你调用其他host的变量和facts,即使你没有在这个机器上执行过playbook,你仍然可以访问变量,但是不能访问facts。例如: {{ hostvars['test.example.com']['ansible_distribution'] }}
    • group_names:当前host所在的group的组名列表,包括其父组
    • groups:所有组包括组中的hosts
    • inventory_hostname:配置在inventory文件中当前机器的hostname
    • play_hosts:执行当前playbook的所有机器的列表
    • inventory_dir:inventory文件的路径
    • inventory_file:inventory文件的路径和文件名
    • role_path:当前role的路径

    7.5 变量作用域

    变量的作用域可以分为四种:

    • 作用于全局的变量
    • 作用于play的变量
    • 作用于task的变量
    • 作用于host的变量

    7.5.1 作用于全局的变量

             1)配置文件变量

                 ansible配置文件会定义一些变量信息,主要是对执行环境、连接信息变量的定义。例如inventory目录、library目录、与目的主机连接方式、越权信息、连接超时时间等等。

              2)系统环境变量

                 在ansible连接到目的主机时,会以non-login shell登陆到目的主机,此时目的主机的/etc/bashrc和~/.basrc的环境变量会被加载,所以这两个文件中设置的环境变量会作用于playbook全局。

              3)命令行变量

                 我们可以在执行playbook的命令行指定变量,需要注意的是,命令行指定的变量在所有其他变量中优先级是最高的。也就是说如果命令行指定的变量和其他地方指定的变量有冲突时,那么ansible最终会采用命令行定义的变量。

    7.5.2 作用于play的变量

              1)playbook中的变量

                   vars语句定义全局变量:我们可以在playbook中使用「vars」语句定义变量,该变量作用于整个play。例如:

    - hosts: node1
      vars:
        http_port: 80

                  引用变量文件:除了将变量写在playbook中,我们也可以将变量放在一个单独的YAML文件中,通过vars_files语句来导入。vars_files变量只能作用于play全局,不能在某个task中单独被引用。vars_files参数可以使用系统绝对路径或playbook文件的相对路径。

    - hosts: node1
      vars_files: ./vars-files.yaml
      tasks:
        - debug:
          msg: "My age is {{ age }}"

              2) roles中的变量

                  default变量:default变量位于roles/defaults/main.yml文件中,该变量作用于role里的所有play,通常作为模版或模块里的默认参数。default变量与 ansible filter变量 {{ some_variable | default("some_value") }} 具有同样的作用,在所有ansible变量中优先级最低。

                 dependencies变量:dependencies变量位于roles/meta/main.yaml文件中,该变量与 role 语句同级缩进,作用于本身的 role 和 dependencies role。如:

                 role_A 和 role_B定义了相同的task,debug出「age」变量:

                 

                 role_A/meta/main.yaml定义role_A依赖role_B,并指定「age」变量等于26:

                 

                 写playbook,引用role_A:

                 

                 执行结果:

                 

                 输出结果显示,dependencise变量「age」在role_A和role_B均生效。

              3) vars变量

                  vars变量位于roles/vars/main.yml,该变量作用于role里的所有模块。通常将除了默认变量的其他的变量放在这个文件内。

              4)  register变量

                   register方法能够将一个task的执行结果注册为一个变量。书写格式要与模块名称对齐,该变量作用于整个play。

    7.5.3 作用于task的变量

              1)playbook中的变量

                   with modules:我们可以为某个模块定义变量,该变量作用于这个task。

                   示例:为 debug模块定义了 name 和 age 变量并在 msg 参数后使用了这两个变量:

                    

                    

                    with import*/include*:在使用import_playbook、import_tasks、include_tasks、import_role、include_role时可以在import*/include*的同级位置指定变量,该变量作用于导入的所有play。

                   例如:playbook导入role_A,并定义变量 age , 这样 role_A 内的 play 就可以使用 age 变量了:

                      

                    

                   其他import*/include*的语句使用方法类似,只要记住缩进与import*/include*语句保持一致即可。

                   with roles:在playbook中使用roles语句来导入role时也可以定义变量,该变量作用于role包含的所有play。

                   例如:playbook使用roles语句导入role_A,并定义变量 age:

                    

                    

               2)roles中的变量

                    指的是在tasks/main.yaml或handlers/main.yaml内书写task时指定的变量,该变量作用于某个task,这个变量类型与with modules类似。

    7.5.4 作用于host的变量

               1)系统变量Facts

                    facts变量:ansible中有个特殊的变量,这些变量不是开发者定义的,而是ansible根据目的主机环境信息自动收集的,称之为fact变量。

                    

                    facts缓存:在执行playbook时,我们发现在「Gathering Facts」步骤时总会卡住一会,如果定义的play多了,会非常耗时。其实这步就是ansible在收集目的主机的facts信息。

                    如果我们定义的playbook中并没有使用到fact变量,那么我们可以选择将其关闭,只需添加「gather_facts: false」即可。

                    假设本地redis服务正常运行,我们只需更改ansible配置文件即可达到缓存fact的目的。

                    redis缓存:

    [defaults]
    gathering = smart
    fact_caching = redis
    fact_caching_timeout = 86400

                    json文件缓存:

    [defaults]
    gathering = smart
    fact_caching = jsonfile
    fact_caching_connection = /path/to/cachedir
    fact_caching_timeout = 86400
    

      

                2)inventory中的变量

                     主机变量:是指作用在某一台主机上的变量。位置可以与主机定义写在一起也可以写在inventory/host_vars/a_host_name.yaml文件里。通常前者使用使用INI格式,后者使用YAML格式。

                     这里要注意一下YAML的语法,在 ":" 后面要留有一个空格。如果组变量和主机变量都对同一个主机定义了相同的变量,那么ansible最终会采用主机变量而放弃组变量。主机变量示例:INI格式:

                     

                     转换为YAML格式:

                     

                     组变量:和主机变量类似,组变量作用于主机组,即多个主机。位置可以与主机组定义写在一起也可以写在inventory/group_vars/a_group_name.yaml文件里。通常前者使用使用INI格式,后者使用YAML格式。

    7.6变量的调用顺序

    下面是ansible的调用变量的顺序,越靠后变量优先级越高。

    • 命令行参数(非-e指定的参数,eg: "-u user -b yes")
    • roles defaults目录下的变量
    • 组变量:inventory 文件
    • 组变量:inventory/group_vars/all
    • 组变量:playbook/group_vars/all
    • 组变量:inventory/group_vars/*
    • 组变量:playbook/group_vars/*
    • 主机变量:inventory 文件
    • 主机变量:inventory/group_vars/*
    • 主机变量:playbook/group_vars/*
    • facts变量
    • play变量:vars定义的
    • play变量:vars_prompt定义的
    • play变量:vars_files导入的
    • roles vars目录下的变量
    • block中task定义的变量
    • playbook中task定义的变量
    • include_vars导入的变量
    • set_facts/register注册的变量
    • 使用roles/include_role/import_role语句时定义的变量
    • 使用include语句(ansible旧版本)时定义的变量
    • 命令行-e参数指定的额外变量(优先级最高)

    7.7变量的使用

    7.7.1 模块使用变量

    一个变量被定义后,在它的作用域内的play可以直接调用,例如:

    我们定义了整个play作用域的变量「name」和「age」,那么在之后的两个debug模块内可以直接调用。如:

     输出结果展示:

    7.7.2 模版使用变量

    变量被频繁使用的还有模板,位于templates/目录或者roles/templates/目录下,该模版使用python的Jinja2模版语法。

    模版多被用于生成服务的配置文件,所以会调用很多的变量。

    天道酬勤
  • 相关阅读:
    感知机简单算法的实现
    C语言博客作业02
    我的第二次C语言作业
    [原]wpf foundation Part 1 of n (object resource )
    [orginal]TabControlView based on css ,js and html .
    [orginal]checkBox based on web(thinking in & implementation)
    [orginal] Progressbar implementation with js,css,and html
    [orginal]Combolist visual design & and implementation ( based on css ,js and html)
    [orginal] nice look ListBox with powerful methodes designing & implementation based on web technology.
    [orginal]treeView control based on WEB
  • 原文地址:https://www.cnblogs.com/wangwei1/p/12875182.html
Copyright © 2020-2023  润新知