playbook变量的使用(二)

接上一章:

  • 内置变量
  • 变量的过滤器
31.9 内置变量hostvars
hostvars用来显示指定主机的 fact变量,用法如下。
1 hostvars[' 主机名 '].键值
此变量一般用于,当某个play的 hosts 中只写了A主机组,但是同时想在此play中显示B
主机组中的信息,这时可以选择此变量。
练习:写一个playbook,里面包含一个play,里面的hosts指定为server2,但是要显示
server3的IP地址,命令如下。
[root@pp demo2]# cat 8-hostvars.yaml 
---
- hosts: up
  tasks:
  - name: 打印lp的IP
    debug: msg={{hostvars['lp'].ansible_default_ipv4.address}}
[root@pp demo2]# 
运行此playbook,命令如下
[root@pp demo2]# ansible-playbook 8-hostvars.yaml 

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [打印server3的IP] **********************************************************************
fatal: [up]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: \"hostvars['server3']\" is undefined\n\nThe error appears to be in '/root/demo2/8-hostvars.yaml': line 4, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n  - name: 打印server3的IP\n    ^ here\n"}

PLAY RECAP *******************************************************************************
up                         : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
这里却出现了报错,这是因为play 的hosts中只写了server2,所以只会获取server2的 fact
变量,并不会获取server3的fact变量,也就不会识别server3上的
ansible_default_ipv4.address。
修改8-hostvars.yaml的内容如下。
[root@pp demo2]# ansible-playbook 8-hostvars.yaml 

PLAY [lp] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [lp]

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [打印lp的IP] ***************************************************************************
ok: [up] => {
    "msg": "192.168.248.11"
}

PLAY RECAP *******************************************************************************
lp                         : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
up                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@pp demo2]# 
可以看到,此处已经正确地获取到 server3的IP了。
31.10 内置变量inventory hostname
当ansible主机同时在多台被管理主机上执行任务时,每台被管理主机都会有一个变量记
录它在清单文件中的名称是什么,如图31-2所示。
playbook变量的使用(二)_第1张图片
这个变量就是inventory _hostname,记录了每个主机在清单文件中的名称。
练习:写一个playbook,在主机组db上执行,命令如下。
[root@pp demo2]# cat 9-inventory1.yaml 
---
- hosts: db
  tasks:
  - name: 打印我在清单文件中的名称
    debug: msg={{inventory_hostname}}
    
[root@pp demo2]# 
这里playbook 会在db主机组上执行,即在server2和 server3上执行。在server2上执行
时inventory_hostname的值为server2,在server3上执行时 inventory_hostname的值为
server3,运行结果如下。
[root@pp demo2]# ansible-playbook 9-inventory1.yaml 

PLAY [db] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [lp]
ok: [up]

TASK [打印我在清单文件中的名称] **********************************************************************
ok: [up] => {
    "msg": "up"
}
ok: [lp] => {
    "msg": "lp"
}

PLAY RECAP *******************************************************************************
lp                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
up                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

上面的例子中,hosts 的值写的是 db,所以后续的task是要在server2和 server3上同时
执行的
31.11 变量的过滤器
所谓变量的过滤器,实际上就是对变量的值进行一些操作,例如,进行类型转化、截取、
加密等操作,使用格式如下。
1 {{ 变量名 | 函数 }}
练习:把大写字符转换成小写字符,命令如下。
[root@pp demo2]# cat 10-vars1.yaml 
---
- hosts: up
  vars:
    aa: tom
    bb: BOB
  tasks:
  - name: xxx
    debug: msg={{bb | lower}}
    
[root@pp demo2]# 
这里定义了一个变量bb值为大写的 BOB,通过 lower这个过滤器会把大写字符转换成小
写字符。运行此playbook,命令如下。
[root@pp demo2]# ansible-playbook 10-vars1.yaml 

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [xxx] *******************************************************************************
ok: [up] => {
    "msg": "bob"
}

PLAY RECAP *******************************************************************************
up                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
可以看到,这里显示的是小写的bob。
下面列出几个常见的过滤器。
31.11.1 数字类型
整型int,可以把字符串转换成整型,看下面的例子。
[root@pp demo2]# cat 10-vars2.yaml 
---
- hosts: up
  tasks:
  - name: 数学计算
    debug: msg={{3+'3'}}
这里对3+'3'进行数学运算,但是第二个3用单引号引起来了,说明是一个字符串,用数字
3和字符串3相加是要报错的,运行结果如下。
[root@pp demo2]# ansible-playbook 10-vars2.yaml 

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [数学计算] ******************************************************************************
fatal: [up]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{3+'3'}}): unsupported operand type(s) for +: 'int' and 'str'"}

PLAY RECAP *******************************************************************************
up                         : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[root@pp demo2]# 
这里报错的提示信息的意思是,数字不能和字符串进行数学运算。我们可以把字符串'3'通
过int转换成数字,修改10-vars2.yaml的内容如下。
[root@pp demo2]# cat 10-vars2.yaml 
---
- hosts: up
  tasks:
  - name: 数学计算
    debug: msg={{3+'3' |int}}
[root@pp demo2]# 
其中'3'通过管道传递给int,转换成整型类型的,这样就可以相加了,运行结果如下。
[root@pp demo2]# ansible-playbook 10-vars2.yaml 

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [数学计算] ******************************************************************************
ok: [up] => {
    "msg": "6"
}

PLAY RECAP *******************************************************************************
up                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
31.11.2 列表
前面讲过一个列表中可以包括多个值,列表的过滤器可以求出列表的长度、最大值、最小
值等。
(1)length:用于求列表的长度。
(2)max:用于求列表中的最大值。
(3)min:用于求列表中的最小值。
练习:写一个 playbook,内容如下。
[root@pp demo2]# cat 10-vars3.yaml 
---
- hosts: up
  vars:
    list1: [1,2,8,3,2]
  tasks:
  - name: 求列表长度
    debug: msg="{{list1 | length}}"
  - name: 求列表中的最小值
    debug: msg="{{list1 | min}}"
[root@pp demo2]# 
这里定义了一个列表list1,然后分别求列表的长度、最大值、最小值,运行结果如下。
[root@pp demo2]# ansible-playbook 10-vars3.yaml 

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [求列表长度] *****************************************************************************
ok: [up] => {
    "msg": "5"
}

TASK [求列表中的最小值] **************************************************************************
ok: [up] => {
    "msg": "1"
}

PLAY RECAP *******************************************************************************
up                         : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
31.11.3 设置变量默认值default
如果某个变量没有被定义,那么可以通过default给它设置一个默认值,用法如下。
1 {{ var1 | default(value1) }}
如果某个变量var1已经定义了,则显示它自己的值;如果没有被定义,则被赋值为value1.
练习:写一个playbook,内容如下。
[root@pp demo2]# cat 10-vars4.yaml 
---
- hosts: up
  vars:
    aa: 11
    bb:
  tasks:
  ‐ name: aa的值
    debug: msg="{{ aa | default('xxx')}}"
  ‐ name: bb的值
    debug: msg="{{ bb | default('xxx')}}"
  ‐ name: cc的值
    debug: msg="{{ cc | default('xxx')}}"
[root@pp demo2]# 
这里定义了aa的值为11,定义了bb但是没有赋值,并没有定义cc。所以,打印aa时,会显
示自己的值即11;打印bb时,会显示自己的值即空值;打印 cc时,显示的是default中的值即
xxx。
31-11.4 字符串相关
string能把其他数据类型转换成字符串,看下面的例子。
[root@pp demo2]# cat 10-vars5.yaml 
---
- hosts: up
  tasks:
  - name: 求和
    debug: msg="{{ 3+(3|string)}}"
[root@pp demo2]# 
3+3本身是可以正常运行的,但这里通过3string把第二个3转换成了字符串,因为数字只
能和数字相加,所以上述执行数字3和字符串3相加会报错,运行结果如下。
[root@pp demo2]# ansible-playbook 10-vars5.yaml 

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [求和] ********************************************************************************
fatal: [up]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ 3+(3|string)}}): unsupported operand type(s) for +: 'int' and 'str'"}

PLAY RECAP *******************************************************************************
up                         : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
这个用法其实和前面的3+3'是类似的,单引号也可以转换成字符串。
capitalize过滤器用于把字符串的首字符转换成大写,看下面的例子。
[root@pp demo2]# cat 10-vars5.yaml 
---
- hosts: up
  tasks:
  - name: 字符转换
    debug: msg="{{( 'aa' | capitalize)}}"
[root@pp demo2]# 
运行此playbook,命令如下。
[root@pp demo2]# ansible-playbook 10-vars5.yaml 

PLAY [up] ********************************************************************************

TASK [Gathering Facts] *******************************************************************
ok: [up]

TASK [字符转换] ******************************************************************************
ok: [up] => {
    "msg": "Aa"
}

PLAY RECAP *******************************************************************************
up                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@pp demo2]# 
可以看到,aa通过capitalize过滤器转换之后,首字符变成了大写。
关于字符的过滤器还有upper(把小写字符转换成大写)、lower(把大写字符转换成小写),

你可能感兴趣的:(linux,linux,运维,服务器)