• 第5章 ansible的各种变量定义方式和变量引用


    第5章 ansible的各种变量定义方式和变量引用

    • 5.1. ansible facts
    • 5.2. 变量引用json数据的方式

    5.2.1. 引用json字典数据的方式
    5.2.2. 引用json数组数据的方式
    5.2.3. 引用facts数据

    • 5.3. 设置本地facts
    • 5.4. 输出和引用变量
    • 5.5. 注册和定义变量的各种方式

    5.5.1. register注册变量
    5.5.2. set_fact定义变量
    5.5.3. vars定义变量
    5.5.4. vars_files定义变量
    5.5.5. roles中的变量
    5.5.6. 命令行传递变量
    5.5.7. 借助with_items叠加变量
    5.5.8. inventory中主机变量和主机组变量
    5.5.9. 内置变量


    第5章 ansible的各种变量定义方式和变量引用

    5.1. ansible facts

    facts组件是用来收集被管理节点信息的,使用setup模块可以获取这些信息。

    [root@localhost ~]# ansible-doc -s setup
    - name: Gathers facts about remote hosts
    
    # 以下是收集信息示例的部分截取内容
    [root@localhost ~]# ansible web1 -m setup
    web1 | SUCCESS => {
        "ansible_facts": {
            "ansible_all_ipv4_addresses": [
                "10.0.0.12"
            ],
            "ansible_all_ipv6_addresses": [
                "fe80::20c:29ff:feb1:919e"
            ],
            "ansible_apparmor": {
                "status": "disabled"
            },
            "ansible_architecture": "x86_64",
            "ansible_bios_date": "07/31/2013",
            "ansible_bios_version": "6.00",
            "ansible_cmdline": {
                "BOOT_IMAGE": "/vmlinuz-3.10.0-693.el7.x86_64",
                "LANG": "en_US.UTF-8",
                "quiet": true,
                "rhgb": true,
                "ro": true,
                "root": "UUID=de7cadf7-bd2c-40d5-b68e-0c4dfea77d80"
            },
            "ansible_date_time": {
                "date": "2020-02-25",
                "day": "25",
                "epoch": "1582619760",
                "hour": "16",
                "iso8601": "2020-02-25T08:36:00Z",
                "iso8601_basic": "20200225T163600276641",
                "iso8601_basic_short": "20200225T163600",
                "iso8601_micro": "2020-02-25T08:36:00.276815Z",
                "minute": "36",
                "month": "02",
                "second": "00",
                "time": "16:36:00",
                "tz": "CST",
                "tz_offset": "+0800",
                "weekday": "Tuesday",
                "weekday_number": "2",
                "weeknumber": "08",
                "year": "2020"
            },
    

    用filter可以筛选指定的facts信息。例如:

    [root@localhost ~]# ansible web1 -m setup -a 'filter=changed'
    web1 | SUCCESS => {
        "ansible_facts": {},
        "changed": false
    }
    [root@localhost ~]# ansible web1 -m setup -a 'filter="*ipv4"'
    web1 | SUCCESS => {
        "ansible_facts": {
            "ansible_default_ipv4": {
                "address": "10.0.0.12",
                "alias": "ens32",
                "broadcast": "10.0.0.255",
                "gateway": "10.0.0.2",
                "interface": "ens32",
                "macaddress": "00:0c:29:b1:91:9e",
                "mtu": 1500,
                "netmask": "255.255.255.0",
                "network": "10.0.0.0",
                "type": "ether"
            }
        },
        "changed": false
    }
    

    facts收集的信息是json格式的,其内任一项都可以当做变量被直接引用(如在playbook,jinja2模板中)引用。


    5.2. 变量引用json数据的方式

    在ansible中,任何一个模块都会返回json格式的数据,即使是错误信息都是json格式的。

    在ansible中,json格式的数据,其内每一项都可以通过变量来引用它。当然,引用的前提是先将其注册为变量。

    例如,下面的playbook是将shell模块中echo命令的结果注册为变量,并使用debug模块输出。

    [root@localhost ansible]# cat test1.yml
    ---
        - hosts: web1
          tasks:
            - shell: echo hello world
              register: say_hi
            - debug: var=say_hi
    
    [root@localhost ansible]# ansible-playbook test1.yml
    
    PLAY [web1] ********************************************************************
    
    TASK [shell] *******************************************************************
    changed: [web1]
    
    TASK [debug] *******************************************************************
    ok: [web1] => {
        "say_hi": {
            "changed": true,
            "cmd": "echo hello world",
            "delta": "0:00:00.164212",
            "end": "2020-02-25 16:40:31.244806",
            "failed": false,
            "rc": 0,
            "start": "2020-02-25 16:40:31.080594",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "hello world",
            "stdout_lines": [
                "hello world"
            ]
        }
    }
    
    PLAY RECAP *********************************************************************
    web1                       : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    可以看出,结果是一段json格式的数据,最顶端的key为say_hi,其内是一大段的字典(即使用大括号包围的),其中的stdout_lines 还包含了一个json数组,也就是所谓的yaml列表项(即使用中括号包围的)。

    5.2.1. 引用json字典数据的方式

    如果想要输出json数据的某一字典项,则应该使用"key.dict"或"key['dict']"的方式应用。例如最常见的stdout项“hello world”是想要输出的项,一下两种方式都能引用该字典变量。

    [root@localhost ansible]# cat test1.yml
    ---
        - hosts: web1
          tasks:
            - shell: echo hello world
              register: say_hi
            - debug: var=say_hi.stdout
            - debug: var=say_hi['stdout']
    
    # 部分输出结果
    TASK [debug] *************************************************************************************
    ok: [web1] => {
        "say_hi.stdout": "hello world"
    }
    
    TASK [debug] *************************************************************************************
    ok: [web1] => {
        "say_hi['stdout']": "hello world"
    }
    
    

    "key.dict"或"key['dict']"的方式都能引用,但在dict字符串本身就包含"."的时候,应该使用中括号的方式应用。例如:

    anykey['192.168.100.65']
    

    5.2.2. 引用json数组数据的方式

    如果想要输出json数据中的某一数组项(列表项),则应该使用"key[N]"的方式引用数组中的第N项,其中N是数组的index,从0开始计算。如果不使用index,则输出的是整个数组列表。

    例如想要输出上面的stdout_lines中的“hello world”,它是数组stdout_lines中第一项所以使用stdout_lines[0]来引用,再加上stdout_lines上面的say_hi,于是引用方式如下:

    ---
        - hosts: web1
          tasks:
            - shell: echo hello world
              register: say_hi
            - debug: var=say_hi.stdout_lines[0]
    
    # 执行部分输出结果
    TASK [debug] *************************************************************************************
    ok: [web1] => {
        "say_hi.stdout_lines[0]": "hello world"
    }
    

    再看下面一段json数据

    "ipv6": [
       {
           "address": "fe80::20c:29ff:fe26:1498", 
           "prefix": "64", 
           "scope": "link"
       }
    ]
    
    # 其中key=ipv6,其内有且仅有一个列表项,但该列表内包含了数个字典项。要引用列表内的字典,例如上面的address项。应该如下引用:
    ipv6[0].address
    

    5.2.3. 引用facts数据

    既然已经了解了json数据中的字典和列表项的引用方式,显然facts中的一大堆数据就能引用并排上用场。例如以下是一段facts数据。

    [root@localhost ~]# ansible localhost -m setup -a 'filter="*ens32*"'
    localhost | SUCCESS => {
        "ansible_facts": {
            "ansible_ens32": {
                "active": true,
                "device": "ens32",
                "features": {
                    "busy_poll": "off [fixed]",
                    "fcoe_mtu": "off [fixed]",
                    "generic_receive_offload": "on",
                    ·····························
                },
                "ipv4": {
                    "address": "10.0.0.12",
                    "broadcast": "10.0.0.255",
                    "netmask": "255.255.255.0",
                    "network": "10.0.0.0"
                },  
                ·····························
    
                "macaddress": "00:0c:29:b1:91:9e",
                "module": "e1000",
                ·····························
        },
        "changed": false
    }
    
    

    显然,facts数据的顶级key为ansible_facts,在引用时应该将其包含在变量表达式中。但自动收集的facts比较特殊,它以ansible_facts作为key,ansible每次收集后会自动将其注册为变量,所facts中的数据都可以直接通过变量引用,甚至连顶级keyansible_facts都要省略。

    例如引用上面的ipv4的地址address项

    ansible_ens32.ipv4.address
    
    # 不能写成
    ansible_facts.ansible_ens32.ipv4.address
    其他任意时候,都应该带上所有的key
    

    5.3. 设置本地facts

    在ansible收集facts时,还会自动收集/etc/ansible/facts.d/*.fact文件中的数据到facts中,且以ansible_local作为key。目前fact支持两种类型的文件:ini和json。当然,如果fact文件的json或ini格式写错了导致无法解析,那么肯定也无法收集。

    例如:在/etc/ansible/facts.d目录下存在一个my.fact的文件,其内数据如下:

    [root@localhost ~]# cat /etc/ansible/facts.d/my.fact
    {
        "family": {
            "father": {
                "name": "Zhangsan",
                "age": "39"
            },
            "mother": {
                "name": "Lisi",
                "age": "35"
            }
        }
    }
    
    # ansible收集facts后的本地facts数据如下:
    [root@localhost ~]# ansible localhost -m setup -a 'filter=ansible_local'
    localhost | SUCCESS => {
        "ansible_facts": {
            "ansible_local": {
                "my": {
                    "family": {
                        "father": {
                            "age": "39",
                            "name": "Zhangsan"
                        },
                        "mother": {
                            "age": "35",
                            "name": "Lisi"
                        }
                    }
                }
            }
        },
        "changed": false
    }
    
    
    # 可见,如果想要引用本地文件中的某个key,除了带上ansible_local外,还必须带上fact文件的文件名,例如,引用father的name
    ansible_local.my.family.father.name
    

    5.4. 输出和引用变量

    上文已经展示了一种变量的引用方式:使用debug的var参数。debug的另一个参数msg也能输出变量,且msg可以输出自定义信息,而var参数只能输出变量。

    另外,msg和var引用参数的方式有所不同。例如:

    [root@localhost ansible]# cat test2.yml
    ---
        - hosts: localhost
          tasks:
            - debug: 'msg="ipv4 adress: {{ ansible_ens32.ipv4.address }}"'
            - debug: var=ansible_ens32.ipv4.address
    
    # 输出结果部分截取如下:
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "msg": "ipv4 adress: 10.0.0.12"
    }
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "ansible_ens32.ipv4.address": "10.0.0.12"
    }
    

    msg引用变量需要加上双大括号,既然加了大括号,为了防止被解析为内联字典,还得加引号包围。这里使用了两段引号,因为其内还包括了一个":",加引号可以防止它被解析为"key: "的格式。而var参数引用变量则直接指定变量名。

    这就像bash中引用变量的方式是一样的,有些时候需要加上$,有时候不能加$。也就是说,当引用的是变量的值,就需要加双大括号,就像加$一样,而引用变量本身,则不能加双大括号。其实双大括号就是jinja2中的分隔符。

    几乎所有地方都可以引用变量,例如循环、when语句 、信息输出语句、template文件等等。只不过有些地方不能使用双大括号,有些地方需要使用。

    5.5. 注册和定义变量的各种方式

    ansible中定义变量的方式有很多种,大致有:

    • 将模块的执行结果注册为变量;
    • 直接定义字典类型的变量;
    • role中文件内定义变量;
    • 命令行传递变量;
    • 借助with_items迭代将多个task的结果赋值给一个变量;
    • inventory中的主机或主机组变量;
    • 内置变量。

    5.5.1. register注册变量

    使用register选项,可以将当前task的输出结果赋值给一个变量。例如:下面的示例中将echo的结果“haha”赋值给say_hi变量。主义,模块的输出结果是json格式的,所以,引用变量时要指定引用的对象。

    [root@localhost ansible]# cat test3.yml
    ---
        - hosts: web1
          tasks:
            - shell: echo haha
              register: say_hi
            - debug: var=say_hi.stdout
    
    # 截取输出结果
    TASK [debug] *************************************************************************************
    ok: [web1] => {
        "say_hi.stdout": "haha"
    }
    

    5.5.2. set_fact定义变量

    set_fact和register的功能很相似,也是将值赋值给变量。它更像shell中变量的赋值方式,可以将某个变量的值赋值给另一个变量,也可以将字符串赋值给变量。

    [root@localhost ansible]# cat test4.yml
    ---
        - hosts: web1
          tasks:
            - shell: echo haha
              register: say_hi
            - set_fact: var1="{{say_hi.stdout}}"
            - set_fact: var2="your name is"
            - debug: msg="{{var2}} {{var1}}"
            
    # 截取输出结果
    TASK [debug] *************************************************************************************
    ok: [web1] => {
        "msg": "your name is haha"
    }
    

    5.5.3. vars定义变量

    可以在play或task层次使用vars定义字典型变量。如果同名,则task层次的变量覆盖play层次的变量。

    [root@localhost ansible]# cat test5.yml
    ---
        - hosts: web1
          vars:
            var1: value1
            var2: value2
          tasks:
            - debug: msg="{{var1}} {{var2}}"
              vars:
                var2: value2.2
    
    # 截取输出结果
    TASK [debug] *************************************************************************************
    ok: [web1] => {
        "msg": "value1 value2.2"
    }
    

    5.5.4. vars_files定义变量

    和vars一样,只不过它是将变量以字典格式定义在独立的文件中,且vars_files不能定义在task层次,只能定义在play层次

    [root@localhost ansible]# cat test6.yml
    ---
        - hosts: web1
          vars_files:
            - /tmp/var_file1.yml
            - var_file2.yml
          tasks:
            - debug: msg="{{var1}} {{var2}}"
    
    # 上面var_file2.yml 使用的是相对路径,基于playbook所在的路径。
    # 例如,该playbook为/tmp/xx.yml,则var_file2.yml也应该在/tmp下。当然,也可以使用绝对路径。
    

    5.5.5. roles中的变量

    由于role是整合playbook的,它有默认的文件组织结构。其中有一个目录vars,其内的main.yml用于定义变量。还有defaults目录内的main.yml则是定义role默认变量的,默认变量的优先级最低。

    [root@localhost ansible]# tree yaml/
    /yaml
    ├── roles
    │   └── nginx
    │       ├── defaults
    │           └── main.yml      
    │       ├── files
    │       ├── handlers
    │       ├── meta
    │       ├── tasks
    │       ├── templates
    │       └── vars
    │           └── main.yml
    └── site.yml
    
    # main.yml中变量定义方式也是字典格式,例如:
    ---
        mysql_port: 3306
    

    5.5.6. 命令行传递变量

    ansible和ansible-playbook命令的"-e"选项都可以传递变量,传递的方式有两种: -e key=value 和 -e @var_file 。注意,当key=value方式传递变量时,如果变量中包含特殊字符,必须防止其被shell解析。

    例如:

    [root@localhost ~]# ansible localhost -m shell -a "echo {{say_hi}}" -e 'say_hi="hello world"'
    localhost | CHANGED | rc=0 >>
    hello world
    
    [root@localhost ~]# ansible localhost -m shell -a "echo {{say_hi}}" -e @/tmp/var_file1.yml
    localhost | CHANGED | rc=0 >>
    hello world
    
    # /tmp/var_file1.yml内容如下:
    [root@localhost ~]# cat /tmp/var_file1.yml
    ---
        say_hi: hello world
    

    5.5.7. 借助with_items叠加变量

    ansible中可以借助with_items实现列表迭代的功能,作用于变量注册的行为上,就可以实现将多个结果赋值给同一个变量。

    例如下面的playbook中,给出了3个item列表,并在shell模块中通过固定变量"{{item}}"分别迭代,第一次迭代的是haha,第二次迭代的是heihei,第三次迭代的是hehe,也就实现了3次循环。最后,将结果注册为变量hi_var

    [root@localhost ansible]# cat test7.yml
    ---
        - hosts: web1
          remote_user: root
          tasks:
            - name: test
              shell: echo "{{item}}"
              with_items:
                - haha
                - heihei
                - hehe
              register: hi_var
            - debug: var=hi_var.results[0].stdout
            - debug: var=hi_var.results[1].stdout
            - debug: var=hi_var.results[2].stdout
    
    # 部分输出截取:
    TASK [test] **********************************************************************************************
    changed: [web1] => (item=haha)
    changed: [web1] => (item=heihei)
    changed: [web1] => (item=hehe)
    
    TASK [debug] *********************************************************************************************
    ok: [web1] => {
        "hi_var.results[0].stdout": "haha"
    }
    
    TASK [debug] *********************************************************************************************
    ok: [web1] => {
        "hi_var.results[1].stdout": "heihei"
    }
    
    TASK [debug] *********************************************************************************************
    ok: [web1] => {
        "hi_var.results[2].stdout": "hehe"
    }
    

    每次迭代的过程中,调用item的模块都会将结果保存在一个key为results的数组中。因此,引用迭代后注册的变量时,需要在变量名中加上results,并指定数组名。例如上面的hi_var.results[N].stdout

    还可以使用for循环遍历列表。例如:

    - debug: msg="{% for i in hi_var.results %} {{i.stdout}} {% endfor %}"
    
    # 截取部分输出结果
    TASK [test] **************************************************************************************************
    changed: [web1] => (item=haha)
    changed: [web1] => (item=heihei)
    changed: [web1] => (item=hehe)
    
    TASK [debug] *************************************************************************************************
    ok: [web1] => {
        "msg": " haha  heihei  hehe "
    }
    

    为了方便理解,查看一下hi_var的输出结果,下面是hi_var的第一个列表的输出:

    - debug: msg="{{hi_var.results[0]}}"
    
    # 截取输出结果
    TASK [debug] *************************************************************************************************
    ok: [web1] => {
        "msg": {
            "ansible_loop_var": "item",
            "changed": true,
            "cmd": "echo "haha"",
            "delta": "0:00:00.160403",
            "end": "2020-02-26 12:03:20.157947",
            "failed": false,
            "invocation": {
                "module_args": {
                    "_raw_params": "echo "haha"",
                    "_uses_shell": true,
                    "argv": null,
                    "chdir": null,
                    "creates": null,
                    "executable": null,
                    "removes": null,
                    "stdin": null,
                    "stdin_add_newline": true,
                    "strip_empty_ends": true,
                    "warn": true
                }
            },
            "item": "haha",
            "rc": 0,
            "start": "2020-02-26 12:03:19.997544",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "haha",
            "stdout_lines": [
                "haha"
            ]
        }
    }
    

    5.5.8.

    inventory中主机变量和主机组变量,不仅包括内置变量赋值,还包括自定义变量赋值。
    例如:

    web1 ansible_ssh_port=22 var1=1
    [centos7]
    web1 var1=2
    web2
    [centos7vars]
    var1=2.2
    var2=3
    [all:vars]
    var2=4
    

    其中ansible_ssh_port是主机内置变量,为其赋值22.这类变量是设置类变量,不能被引用。此外还在多处为主机web进行了赋值。其中[centos7:vars]和[all:vars]表示为主机组赋值,前者是为centos7这个组复制,后者是为所有组赋值。

    以下是执行语句:

    [root@localhost ~]# ansible web1 -m shell -a 'echo "{{var1}} {{var2}}"'
    web1 | CHANGED | rc=0 >>
    2 3
    

    从结果可知,主机变量优先级 > 主机组变量。给定的主机组变量优先级 > all特殊组。

    除了在inventory文件路径为/etc/ansible/hosts,playbook文件路径为/tmp/xx.yml,则主机web和主机组centos7的变量文件路径可以为以下几种:

    • /etc/ansible/host_vars/web1
    • /etc/ansible/group_vars/centos7
    • /tmp/host_vars/web1
    • /tmp/group_vars/centos7

    以下为几个host_vars和group_vars目录下的文件内容

    [root@localhost ~]# cat /etc/ansible/{host_vars/web1,group_vars/centos7} /tmp/{host_vars/web1,group_vars/centos7}
    var1: 1
    var2: 2
    var3: 3
    var4: 4
    
    # 以下为/tmp/testweb1.yml内容
    [root@localhost ~]# cat /tmp/testweb.yml
    ---
        - hosts: web1
          tasks:
            - debug: msg='{{var1}} {{var2}} {{var3}} {{var4}}'
    
    # 执行结果部分截取如下:
    TASK [debug] *************************************************************************************************
    ok: [web1] => {
        "msg": "1 2 3 4"
    }
    
    

    5.5.9. 内置变量

    ansible除了inventory中内置的一堆不可被引用的设置类变量,还有几个全局都可以引用的内置变量,主要有以下几个:

    inventory_hostname
    inventory_hostname_short
    groups
    group_names
    hostvars
    play_hosts
    inventory_dir
    ansible_versino
    
    • inventory_hostname和inventory_hostname_short
    • 分别代表的是inventory中被控节点的主机名和主机名的第一部分,如果定义的是主机别名,则变量的值也是别名。
    # 例如inventory中centos7主机组定义为如下:
    [centos7]
    192.168.1.60
    web1 ansible_ssh_host=192.168.1.61
    www.web2.com ansible_ssh_host=192.168.1.62
    
    # 分别输出它们的inventory_hostname和inventory_hostname_short
    [root@localhost ~]# ansible centos7 -m debug -a 'msg="{{inventory_hostname}} & {{ inventory_hostname_short}}"'
    192.168.1.60 | SUCCESS => {
        "msg": "192.168.1.60 & 192"
    }
    web1 | SUCCESS => {
        "msg": "web1 & web1"
    }
    www.web2.com | SUCCESS => {
        "msg": "www.web2.com & www"
    }
    
    
    • groups和goup_names
    • group_names返回的事主机所属主机组,如果该主机在多个组中,则返回多个组,如果它不在组中,则返回ungrouped这个特殊组:
    # 例如,某个inventory文件如下:
    [root@localhost ~]# cat /tmp/ansible_hosts
    192.168.1.11
    192.168.1.12
    192.168.1.13
    192.168.1.14
    [centos6]
    192.168.1.11
    [centos7]
    192.168.1.12
    web1 ansible_ssh_host=192.168.1.13
    www.web2.com ansible_ssh_host=192.168.1.14
    [centos:children]
    centos6
    centos7
    

    其中:11 定义在centos6 和centos 中,所以返回这两个组;

    [root@localhost ~]# ansible -i /tmp/ansible_hosts 192.168.1.11 -m debug -a 'msg="{{group_names}}"'
    192.168.1.11 | SUCCESS => {
        "msg": [
            "centos",
            "centos6"
        ]
    }
    

    同理,12 返回centos7 和centos ;

    [root@localhost ~]# ansible -i /tmp/ansible_hosts 192.168.1.12 -m debug -a 'msg="{{group_names}}"'
    192.168.1.12 | SUCCESS => {
        "msg": [
            "centos",
            "centos7"
        ]
    }
    

    13,14 则返回ungrouped,虽然它们在centos7 中都定义了别名,但至少将13,14 作为主机名时,它们不在任何主机组中;

    [root@localhost ~]# ansible -i /tmp/ansible_hosts 192.168.1.13 -m debug -a 'msg="{{group_names}}"'
    192.168.1.13 | SUCCESS => {
        "msg": [
            "ungrouped"
        ]
    }
    [root@localhost ~]# ansible -i /tmp/ansible_hosts 192.168.1.14 -m debug -a 'msg="{{group_names}}"'
    192.168.1.14 | SUCCESS => {
        "msg": [
            "ungrouped"
        ]
    }
    

    另一方面,web1 和www.web2.com 这两个别名主机都返回centos7 和centos 两个组;

    [root@localhost ~]# ansible -i /tmp/ansible_hosts web1 -m debug -a 'msg="{{group_names}}"'
    web1 | SUCCESS => {
        "msg": [
            "centos",
            "centos7"
        ]
    }
    [root@localhost ~]# ansible -i /tmp/ansible_hosts www.web2.com -m debug -a 'msg="{{group_names}}"'
    www.web2.com | SUCCESS => {
        "msg": [
            "centos",
            "centos7"
        ]
    }
    
    • groups变量则返回其所在inventory文件中所有组合其内主机名。注意,该变量对每个控制节点都返回一次,所以返回的内容可能非常多。
    • 例如,上面的inventory中,如果指定被控节点为centos7,则会重复返回3次(因为有3台被控主机)在该inventory文件。其中的第三台主机www.web2.com的返回结果为:
    [root@localhost ~]# ansible -i /tmp/ansible_hosts www.web2.com -m debug -a 'msg="{{groups}}"'
    www.web2.com | SUCCESS => {
        "msg": {
            "all": [
                "192.168.1.13",
                "192.168.1.14",
                "192.168.1.11",
                "192.168.1.12",
                "web1",
                "www.web2.com"
            ],
            "centos": [
                "192.168.1.11",
                "192.168.1.12",
                "web1",
                "www.web2.com"
            ],
            "centos6": [
                "192.168.1.11"
            ],
            "centos7": [
                "192.168.1.12",
                "web1",
                "www.web2.com"
            ],
            "ungrouped": [
                "192.168.1.13",
                "192.168.1.14"
            ]
        }
    }
    
    • hostvars
    • 该变量用于引用其他主机上手机的facts中的数据,或者引用其他主机的主机变量、主机组变量。其key为主机名或主机组名。
    • 举个例子,假如使用ansible部署一台php服务器host1,且配置文件内需要指向另一台数据库服务器host2的ip地址iP2,可以直接在配置文件中指定ip2。但也可以在模板配置文件中直接引用host2收集的facts数据中的ansible_eth0.ipv4.addree变量

    例如:centos7主机组中包含了192.168.1.[60:62]共3台主机。playbook内容如下:

    ---
        - hosts: centos7
          tasks:
            - debug: msg="{{hostvars['192.168.1.61'].ansible_ens34.ipv4.address}}"
    
    # 执行结果部分截取如下:
    TASK [debug] *************************************************************************************************
    ok: [192.168.1.60] => {
        "msg": "192.168.1.61"
    }
    ok: [192.168.1.61] => {
        "msg": "192.168.1.61"
    }
    ok: [192.168.1.62] => {
        "msg": "192.168.1.61"
    }
    

    但注意:在引用其他主机facts中数据时,要求被引用主机进行了facts收集动作,或者有facts缓存。否则都没手机,当然无法引用其facts数据。也就是说,当被引用主机没有facts缓存时,ansible的控制节点中必须同时包含引用主机和被引用主机。

    除了引用其他主机的facts数据,还可以引用其他主机的主机变量和主机组变量,且不要求被引用主机有facts删数据,因为主机变量和主机组变量是在ansible执行任务前加载的。

    例如,

    # inventory中格式如下:
    192.168.1.11
    [centos7]
    192.168.1.12 var12=12
    192.168.1.13
    [centos7:vars]
    var13:13
    
    # playbook内容如下:
    ---
        - hosts: 192.168.1.11
          tasks:
            - debug: msg="{{hostvars['192.168.1.12'].var12}} & {{hostvars['192.168.1.13'].var13}}"
            
    # 执行结果截取如下:
    TASK [debug] ***************************************
    ok: [192.168.1.11] => {
        "msg": "12 & 13"
    }
    
    • play_hosts和inventory_dir
    • play_hosts代表的是当前play所涉及inventory内的所有主机名列表。

    例如:

    # inventory内容为:
    192.168.1.11
    [centos6]
    192.168.1.12
    192.168.1.13
    [centos7]
    192.168.1.14
    192.168.1.15
    
    # 那么,该inventory内的任意一或多台主机作为ansible或ansible-playbook的被控节点时,都会返回整个inventory内的所有主机名称;
    # inventory_dir是所使用inventory所在的目录
    
    • ansible_version
    • 代表的是ansible软件的版本号,变量返回的内容如下:
    {
            "full": "2.3.1.0", 
            "major": 2, 
            "minor": 3, 
            "revision": 1, 
            "string": "2.3.1.0"
        }
    
  • 相关阅读:
    Windows7 如何添加excel,word到鼠标右键
    Java程序安装失败
    交换机
    Hbase
    Hive
    Hdoop
    PL/SQL连不上,报 ORA-12170:TNS 连接超时
    Error in invoking target 'mkldflags ntcontab.o nnfgt.o' of mkdefile '/u01/app/oracle/product/11.2.0
    用js 的for循环打印三角形,提取水仙花数,求本月多少天
    JS循环、数组与练习题
  • 原文地址:https://www.cnblogs.com/HsLM/p/12367067.html
Copyright © 2020-2023  润新知