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模版语法。

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

 

posted @ 2020-05-12 13:52  逐浪子  阅读(1192)  评论(0编辑  收藏  举报