Ansible 实战案例--Playbook 详解 之 变量与引用

前言

Ansible 支持利用变量来存储值,并在Ansible 项目的所有文件中重复使用这些值。这可以大大简化项目的创建和维护,并减少错误的数量


提示:本篇文章所使用的环境为centos-8.2基于ansible-2.8.0 搭建
具体环境搭建,请参考:ansible-2.8.0 搭建链接

Ansible 中的变量

通过变量,我们可以轻松地在Ansible 项目中管理给定环境的动态值。例如,变量可能包含这些值:

  • 要创建的用户
  • 要安装的软件包
  • 要重新启动的服务
  • 要删除的文件
  • 要从互联网检索的存档

变量的命名

变量的命令必须以字母开头,并且只能含有数字、字母、下划线。

在Ansible 中定义变量

一、通过 Inventory 文件定义主机以及主机组变量

  • 基于主机定义变量
#编辑Playbook
[root@ansible-server ansible]# vim var1.yml
---
- hosts: all
  tasks:
    - name: Show var
      debug:
        msg: The {{ inventory_hostname }} Vaule is {{ key }}

#检查语法
[root@ansible-server ansible]# ansible-playbook var1.yml --syntax-check

playbook: var1.yml

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var1.yml 

PLAY [all] *********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [node04]
ok: [node02]
ok: [node03]
ok: [node01]

TASK [Show var] ****************************************************************************************************
ok: [node01] => {
    "msg": "The node01 Vaule is 1"
}
ok: [node04] => {
    "msg": "The node04 Vaule is 4"
}
ok: [node02] => {
    "msg": "The node02 Vaule is 2"
}
ok: [node03] => {
    "msg": "The node03 Vaule is 3"
}

PLAY RECAP *********************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  • 基于主机组定义变量
#定义变量
[root@ansible-server ansible]# vim inventory 
#node01 key=1
#node02 key=2
#node03 key=3
#node04 key=4
[dev]
node02
[test]
node03
[prod]
node01
node04
[webservers:children]
dev
test
[webservers:vars]
key=web

#编辑Playbook 文件
---
- hosts: webservers
  tasks:
    - name: Show var
      debug:
        msg: The {{ inventory_hostname }} Vaule is {{ key }}

#检查语法
[root@ansible-server ansible]# ansible-playbook var2.yml --syntax-check

playbook: var2.yml

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var2.yml 

PLAY [webservers] *********************************************************************************************

TASK [Gathering Facts] ****************************************************************************************
ok: [node02]
ok: [node03]

TASK [Show var] ***********************************************************************************************
ok: [node02] => {
    "msg": "The node02 Vaule is web"
}
ok: [node03] => {
    "msg": "The node03 Vaule is web"
}

PLAY RECAP ****************************************************************************************************
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignore

注意:在主机清单定义变量,主机变量的优先级高于主机组的优先级

二、通过 /etc/ansible/ 下的文件定义主机以及主机组变量

  • 基于主机定义变量
#定义变量
[root@ansible-server ansible]# mkdir host_vars
[root@ansible-server ansible]# cd host_vars/
[root@ansible-server host_vars]# echo "key: node01" > node01
[root@ansible-server host_vars]# echo "key: node02" > node02
[root@ansible-server host_vars]# echo "key: node03" > node03
[root@ansible-server host_vars]# echo "key: node04" > node04

#查看定义的变量
[root@ansible-server ~]# cd /ansible/
[root@ansible-server ansible]# head host_vars/*
==> host_vars/node01 <==
key: node01

==> host_vars/node02 <==
key: node02

==> host_vars/node03 <==
key: node03

==> host_vars/node04 <==
key: node04

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var1.yml 

PLAY [all] ****************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************
ok: [node03]
ok: [node02]
ok: [node04]
ok: [node01]

TASK [Show var] ***********************************************************************************************
ok: [node01] => {
    "msg": "The node01 Vaule is node01"
}
ok: [node04] => {
    "msg": "The node04 Vaule is node04"
}
ok: [node02] => {
    "msg": "The node02 Vaule is node02"
}
ok: [node03] => {
    "msg": "The node03 Vaule is node03"
}

PLAY RECAP ****************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignore
  • 基于主机组定义变量
#定义变量
[root@ansible-server ansible]# mkdir group_vars
[root@ansible-server ansible]# cd group_vars/
[root@ansible-server group_vars]# echo "key: https" > prod

#删除主机变量文件--主机优先生效于主机组
[root@ansible-server group_vars]# cd ..
[root@ansible-server ansible]# rm -fr host_vars/

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var1.yml 

PLAY [all] ****************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************
ok: [node01]
ok: [node04]
ok: [node02]
ok: [node03]

TASK [Show var] ***********************************************************************************************
ok: [node01] => {
    "msg": "The node01 Vaule is https"
}
ok: [node04] => {
    "msg": "The node04 Vaule is https"
}
ok: [node02] => {
    "msg": "The node02 Vaule is web"
}
ok: [node03] => {
    "msg": "The node03 Vaule is web"
}

PLAY RECAP ****************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

三、通过 ansible-playbook 命令行传入变量

#直接传入变量的值
[root@ansible-server ansible]# ansible-playbook var1.yml -e 'key=webservers'

PLAY [all] ****************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************
ok: [node03]
ok: [node04]
ok: [node02]
ok: [node01]

TASK [Show var] ***********************************************************************************************
ok: [node01] => {
    "msg": "The node01 Vaule is webservers"
}
ok: [node04] => {
    "msg": "The node04 Vaule is webservers"
}
ok: [node02] => {
    "msg": "The node02 Vaule is webservers"
}
ok: [node03] => {
    "msg": "The node03 Vaule is webservers"
}

PLAY RECAP ****************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignore


#通过文件传入变量
[root@ansible-server ansible]# echo '{"key": "test"}' > var.test
[root@ansible-server ansible]# more var.test 
{"key": "test"}
[root@ansible-server ansible]# ansible-playbook var1.yml -e '@var.test'

PLAY [all] *********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [node03]
ok: [node01]
ok: [node04]
ok: [node02]

TASK [Show var] ****************************************************************************************************
ok: [node01] => {
    "msg": "The node01 Vaule is test"
}
ok: [node04] => {
    "msg": "The node04 Vaule is test"
}
ok: [node02] => {
    "msg": "The node02 Vaule is test"
}
ok: [node03] => {
    "msg": "The node03 Vaule is test"
}

PLAY RECAP *********************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

四、在 playbook 文件内使用 vars

[root@ansible-server ansible]# vim var1.yml 
---
- hosts: all
  vars:
    key: tests
  tasks:
    - name: Show var
      debug:
        msg: The {{ inventory_hostname }} Vaule is {{ key }}

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var1.yml 

PLAY [all] *********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [node03]
ok: [node04]
ok: [node01]
ok: [node02]

TASK [Show var] ****************************************************************************************************
ok: [node01] => {
    "msg": "The node01 Vaule is tests"
}
ok: [node04] => {
    "msg": "The node04 Vaule is tests"
}
ok: [node02] => {
    "msg": "The node02 Vaule is tests"
}
ok: [node03] => {
    "msg": "The node03 Vaule is tests"
}

PLAY RECAP *********************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

五、在 playbook 文件内使用 vars_files

[root@ansible-server ansible]# vim var3.yml
---
- hosts: all
  vars_files:
    - var.test
  tasks:
    - name: Show var
      debug:
        msg: The {{ inventory_hostname }} Vaule is {{ key }}

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var3.yml 

PLAY [all] *********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [node01]
ok: [node03]
ok: [node04]
ok: [node02]

TASK [Show var] ****************************************************************************************************
ok: [node01] => {
    "msg": "The node01 Vaule is test"
}
ok: [node04] => {
    "msg": "The node04 Vaule is test"
}
ok: [node02] => {
    "msg": "The node02 Vaule is test"
}
ok: [node03] => {
    "msg": "The node03 Vaule is test"
}

PLAY RECAP *********************************************************************************************************
node01                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

六、使用 register 内的变量

[root@ansible-server ansible]# vim var4.yml
---
- hosts: all
  tasks:
    - name: register variable
      shell: hostname
      register: smm

    - name: show register
      debug:
        msg: hostname is {{ smm }}

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var4.yml 

PLAY [all] *********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [node02]
ok: [node01]
ok: [node03]
ok: [node04]

TASK [register variable] *******************************************************************************************
changed: [node04]
changed: [node02]
changed: [node03]
changed: [node01]

TASK [show register] ***********************************************************************************************
ok: [node01] => {
    "msg": "hostname is {'cmd': 'hostname', 'stdout': 'node01', 'stderr': '', 'rc': 0, 'start': '2020-10-01 21:30:16.886943', 'end': '2020-10-01 21:30:16.891430', 'delta': '0:00:00.004487', 'changed': True, 'stdout_lines': ['node01'], 'stderr_lines': [], 'failed': False}"
}
ok: [node04] => {
    "msg": "hostname is {'cmd': 'hostname', 'stdout': 'node04', 'stderr': '', 'rc': 0, 'start': '2020-10-01 21:29:45.990403', 'end': '2020-10-01 21:29:45.995018', 'delta': '0:00:00.004615', 'changed': True, 'stdout_lines': ['node04'], 'stderr_lines': [], 'failed': False}"
}
ok: [node02] => {
    "msg": "hostname is {'cmd': 'hostname', 'stdout': 'node02', 'stderr': '', 'rc': 0, 'start': '2020-10-01 21:29:43.287218', 'end': '2020-10-01 21:29:43.292358', 'delta': '0:00:00.005140', 'changed': True, 'stdout_lines': ['node02'], 'stderr_lines': [], 'failed': False}"
}
ok: [node03] => {
    "msg": "hostname is {'cmd': 'hostname', 'stdout': 'node03', 'stderr': '', 'rc': 0, 'start': '2020-10-01 21:30:01.085457', 'end': '2020-10-01 21:30:01.090727', 'delta': '0:00:00.005270', 'changed': True, 'stdout_lines': ['node03'], 'stderr_lines': [], 'failed': False}"
}

PLAY RECAP *********************************************************************************************************
node01                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

可以看到 info 的结果是一段 Python 字典数据, 里面存储着很多信息包括执行时间状态变化输岀等信
息。 register 的输岀数据结果都是 Python 字典, 我们可以很容易地挑选出我们想要的信息, 比如下
面想标准输出 stdout 的信息时, 只需要指定 stdout这个 key 即可

[root@ansible-server ansible]# vim var4.yml
---
- hosts: all
  tasks:
    - name: register variable
      shell: hostname
      register: smm

    - name: show register
      debug:
        msg: hostname is {{ smm['stdout'] }}

#执行Playbook
[root@ansible-server ansible]# ansible-playbook var4.yml 

PLAY [all] *********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [node03]
ok: [node01]
ok: [node02]
ok: [node04]

TASK [register variable] *******************************************************************************************
changed: [node01]
changed: [node02]
changed: [node04]
changed: [node03]

TASK [show register] ***********************************************************************************************
ok: [node01] => {
    "msg": "hostname is node01"
}
ok: [node04] => {
    "msg": "hostname is node04"
}
ok: [node02] => {
    "msg": "hostname is node02"
}
ok: [node03] => {
    "msg": "hostname is node03"
}

PLAY RECAP *********************************************************************************************************
node01                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

注意:python 字典 可以使用 smm[‘stdout’] 或者 smm.stdout 去其中的值

七、使用 vars_prompt 传入

[root@ansible-server ansible]# vim var5.yml
---
- hosts: all
  vars_prompt:
    - name: one
      prompt: please input first value
      private: no

    - name: two
      prompt: please input second value
      private: yes
      default: two

  tasks:
    - name: show first value
      debug:
        msg: one value is {{ one }}

    - name: show second value
      debug:
        var: two

#执行Playbook,并分别键入1 、2 
[root@ansible-server ansible]# ansible-playbook var5.yml 
please input first value: 1
please input second value [two]: 

PLAY [all] *********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [node04]
ok: [node01]
ok: [node03]
ok: [node02]

TASK [show first value] ********************************************************************************************
ok: [node01] => {
    "msg": "one value is 1"
}
ok: [node04] => {
    "msg": "one value is 1"
}
ok: [node02] => {
    "msg": "one value is 1"
}
ok: [node03] => {
    "msg": "one value is 1"
}

TASK [show second value] *******************************************************************************************
ok: [node01] => {
    "two": "2"
}
ok: [node04] => {
    "two": "2"
}
ok: [node02] => {
    "two": "2"
}
ok: [node03] => {
    "two": "2"
}

PLAY RECAP *********************************************************************************************************
node01                     : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node02                     : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node03                     : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node04                     : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

八、使用数组方式定义变量

#定义用户数组文件
[root@ansible-server ansible]# vim users.yml 
users:
  bob:
    user_name: bob
    home_dir: /home/bob
    user_shell: /sbin/nologin

#编辑Playbook
[root@ansible-server ansible]# vim create_user.yml
---
- hosts: dev
  vars_files:
    - users.yml
  tasks:
    - name: create user
      user:
        name: '{{ users.bob.user_name }}'
        shell: '{{ users.bob.user_shell }}'
        home: '{{ users.bob.home_dir}}'

#检查语法
[root@ansible-server ansible]# ansible-playbook  create_user.yml --syntax-check 

playbook: create_user.yml

#执行Playbook
[root@ansible-server ansible]# ansible-playbook create_user.yml 

PLAY [dev] *********************************************************************************************************

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

TASK [create user] *************************************************************************************************
ok: [node02]

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

#查看执行结果
[root@node02 ~]# tail -1 /etc/passwd
bob:x:1001:1001::/home/bob:/sbin/nologin
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值