变量名仅能由字母、数字和下划线组成,且只能以字母开头。
引用变量的一般方法是 {{ 变量名 }},如果出现位置是第1个元素,需要用双引号括起来。

变量可以在如下几个位置定义:

  • 在 ansible-playbook 命令行中定义(优先级最高)
  • 在资产清单文件中定义(红帽不推荐)
  • 在 playbook 通过 vars 定义
  • 在 playbook 通过 vars_files 定义
  • 通过 host_vars 和 group_vars 目录来定义(红帽推荐)

命令行定义变量

比如,这儿写了一个 playbook,里面引用了未知来源的变量:

# cat demo.yml
---
- hosts: web
  remote_user: root
  tasks:
  - name: stop {{ srv1 }} 
    service: name="{{ srv1 }}" state=stopped

# ansible-playbook -e 'pname=httpd' demo.yml

如果要指定多个变量值,在单引号里用空格隔开。

在资产清单文件中定义

普通变量:主机组中主机单独定义,优先级高于公共变量
公共变量/组变量:针对主机组中所有主机定义统一变量

资产清单文件如下:

# cat hosts 

[allhosts]
servera.lab.example.com shortname=servera
172.25.250.11 shortname=serverb

[allhosts:vars]
domain=lab.example.com
shortname=demo

[web]
servera.lab.example.com

[db]
172.25.250.11

playbook 如下:

# cat hello.yml

---
- hosts: allhosts
  tasks:
  - name: configure hostname
    hostname: 
      name: "{{ shortname }}.{{ domain }}"

在 playbook 通过 vars 定义

---
- hosts: web
  vars:
  - shotname: servera
  - domain: lab.example.com
  tasks:
  - name: configure hostname
    hostname:
      name: "{{ shortname }}.{{ domain }}"

在 playbook 通过 vars_files 定义

playbook如下:

# cat demo.yml
---
- hosts: web
  vars_files:
  - vars.yml
  tasks:
  - name: configure hostname
    hostname:
      name: "{{ shortname }}.{{ domain }}"

变量文件内容如下:

# cat vars.yml
shotname: servera
domain: lab.example.com

通过 host_vars 和 group_vars 目录来定义

在资产清单文件所在的目录中新建两个文件夹 host_vars 和 group_vars。
然后在相应的目录下面,以组名或者主机名创建文件,文件里书写变量。
playbook直接调用变量即可。

变量文件示例如下:

# cat group_vars/web 
shotname: servera
domain: lab.example.com

playbook 如下:

# cat demo.yml 
---
- hosts: web
  tasks:
  - name: configure hostname
    hostname:
      name: "{{ shortname }}.{{ domain }}"

使用 debug 打印变量的值

使用 debug 模块可以将变量的值输出出来(以进行排错)。

一般有两种写法(不能同时混用):

debug: 
  var: variable-name    <== var 选项,直接写变量名
debug: 
  msg: "{{ variable-name }}"        <== msg 选项,变量名要用花括号括起来

示例如下:

# cat demo.yml 
---
- hosts: web
  vars:
    shortname: servera
    domain: lab.example.com
  tasks:
  #- name: print the value of shortname and domain
  #  debug:
  #    msg: "{{ shortname }}.{{ domain }}"
  - name: print the value of shortname
    debug:
      var: shortname
  - name: print the value of domain
    debug:
      var: domain

使用 register 捕获命令的输出

在 ansible 中,任何一个模块都会返回 json 格式的数据,即使是错误信息都是 json 格式的。其内每一项都可以通过变量来引用它,引用的前提是先将其注册为变量。我们可以使用 register 来捕获 task 的输出到一个临时的变量。然后根据变量内容进行打印或者处理。

打印注册变量:

# cat demo.yml 
---
- name: install httpd and print the result
  hosts: web
  tasks:
  - name: install httpd
    yum:
      name: httpd
      state: installed
    register: cy_result

  - name: print the value of var
    debug:
      msg: "{{ cy_result }}"

还可以只取输出结果中的一部分内容。花括号{}表示是一个字典,中括号[]表示是一个数组。
字典值可以使用 "cy_result['results']" 或者 "cy_result.results" 来取,数组值需要使用数字下标 install_result.results[0]来取(注意本例只有一个数组元素)。

处理注册变量:
该例子仅作为练习使用,会有提高和收获,但无实际意义。
要求根据 yum 模块来判断软件是否安装,如果未安装,才调用 yum 模块进行安装。

# cat register.yml 
---
- name: check package and and install
  hosts: web  
  tasks:
   - name: check httpd if installed
     yum: 
       list: httpd
     register: check_result 

   - name: install httpd if not installed
     yum: 
       name: httpd
       state: installed
     when: check_result['results'][0]['yumstate'] == 'available'

   - name: use debug module to print the temporary variable
     debug: var=check_result['results'][0]['yumstate']

using arrays as variables

考虑如下经常遇到的场景:

user1_first_name: san
user1_last_name: zhang
user1_home_dir: /home/zhangsan
user2_first_name: si
user2_last_name: li
user2_home_dir: /home/lisi

对于类似的需求,我们可以使用 arrays 来完成:

---
- name: using arrays as variables
  hosts: web
  vars:
    users:
      zhangsan:
        first_name: san
        last_name: zhang
      lisi:
        first_name: si
        last_name: li 

  tasks:
  - name: print the value of var
    debug:
      #msg: "{{ users.zhangsan.first_name }}"
      msg: "{{ users['zhangsan']['first_name'] }}"

注意: 当使用 . 这种书写方式时,如果 key 的名字跟 python 的 method/attributes 一样,例如 discard, copy, add 等,则会报错,使用 [] 可以避免这种问题。

-- By 许望(RHCA、OCM、VCP)
最后修改:2020 年 04 月 23 日 09 : 17 AM
如果觉得我的文章对你有用,请随意赞赏