ansible支持变量,用于存储会在整个项目中重复使用到的一些值。以简化项目的创建与维护,降低出错的机率。

变量的定义:

  • 变量名应该由字母、数字下划数组成
  • 变量名必须以字母开头
  • ansible内置关键字不能作为变量名

1. 在Inventory中定义变量

1.1. 定义主机变量

1.1.1. 内置主机变量

所谓内置变量其实就是ansible.cfg配置文件中的选项,在其前加上ansible_即成为内置变量。当然内置变拥有比ansible.cfg中选项更高的优先级,而且针对不同的主机,可以定义不同的值。

# 一般连接
ansible_ssh_host #用于指定被管理的主机的真实IP
ansible_ssh_port #用于指定连接到被管理主机的ssh端口号,默认是22
ansible_ssh_user #ssh连接时默认使用的用户名 # 特定ssh连接
ansible_connection #SSH连接的类型:local, ssh, paramiko,在ansible 1.2 之前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(如果支持的话)
ansible_ssh_pass #ssh连接时的密码
ansible_ssh_private_key_file #秘钥文件路径,如果不想使用ssh-agent管理秘钥文件时可以使用此选项
ansible_ssh_executable #如果ssh指令不在默认路径当中,可以使用该变量来定义其路径 # 特权升级
ansible_become #相当于ansible_sudo或者ansible_su,允许强制特权升级
ansible_become_user #通过特权升级到的用户,相当于ansible_sudo_user或者ansible_su_user
ansible_become_pass # 提升特权时,如果需要密码的话,可以通过该变量指定,相当于ansible_sudo_pass或者ansible_su_pass
ansible_sudo_exec #如果sudo命令不在默认路径,需要指定sudo命令路径 # 远程主机环境参数
ansible_shell_executable # 设置目标机上使用的shell,默认为/bin/sh
ansible_python_interpreter #用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径
ansible_*_interpreter #其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等其他语言

下面是一个简单的示例:

192.168.132.131 ansible_ssh_user=ansible ansible_become_user=user1  ansible_become_method=sudo ansible_become_pass="redhat"
192.168.132.132 ansible_python_interpreter=/usr/local/python3/bin/python3
192.168.132.133  ntpserver=192.168.132.134 zabbixserer=192.168.132.134

1.2 定义主机组变量

变量也可以通过组名,应用到组内的所有成员:

[web]
node1
node2
[web:vars]
ntpserver=192.168.132.134

[root@node1 ansible]# vim vars_play1.yml

- hosts: web
tasks:
- package:
name: ntpdate
state: present
- cron:
name: sync time
minute: "*/5"
job: "ntpdate {{ ntpserver }}"

[root@node1 ansible]# ansible-playbook   vars_play1.yml

PLAY [web] ********************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************
ok: [node1]
ok: [node2]
TASK [package] ****************************************************************************************************
changed: [node2]
changed: [node1]
TASK [cron] *******************************************************************************************************
changed: [node1]
changed: [node2]
PLAY RECAP ********************************************************************************************************
node1 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node2 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

检查

[root@node1 ansible]# ansible web -m shell -a "crontab -l"

node2 | CHANGED | rc=0 >>
#Ansible: tectcron
* * * * * echo `date` >> /tmp/test.txt
#Ansible: sync time
*/5 * * * * ntpdate 192.168.132.134
node1 | CHANGED | rc=0 >>
#Ansible: tectcron
* * * * * echo `date` >> /tmp/test.txt
#Ansible: sync time
*/5 * * * * ntpdate 192.168.132.134

变量的优先级,主机变量拥有最高的优先级

[web]
node1 ntpserver=ntp1.aliyun.com
node2
[web:vars]
ntpserver=192.168.132.134

2. 在Playbook中定义变量

2.1. 变量的定义方式

2.1.1. 通过vars关键字定义

拥有比主机和主机组更高的优先级

前面的一个示例:

- hosts: web
vars:
ntpserver: ntp2.aliyun.com
tasks:
- package:
name: ntpdate
state: present
- cron:
name: sync time
minute: "*/5"
job: "ntpdate {{ ntpserver }}"

[root@node1 ansible]# ansible-playbook vars_play1.yml

[root@node1 ansible]# ansible web -m shell -a "crontab -l"

node1 | CHANGED | rc=0 >>
#Ansible: tectcron
* * * * * echo `date` >> /tmp/test.txt
#Ansible: sync time
*/5 * * * * ntpdate ntp2.aliyun.com
node2 | CHANGED | rc=0 >>
#Ansible: tectcron
* * * * * echo `date` >> /tmp/test.txt
#Ansible: sync time
*/5 * * * * ntpdate ntp2.aliyun.com

自定义变量,debug调试

- hosts: web
vars:
ntpserver: ntp2.aliyun.com
# users: [{"name":"natasha","gender"},{"name":"tom","gender":"male" }]
users:
- name: natasha
gender: famale
- name: tom
gender: male
tasks:
- debug:
msg: "print users: {{ users }}"
- debug:
var: users

[root@node1 ansible]# ansible-playbook vars_play1.yml

PLAY [web] ************************************************************************************************************************************
TASK [debug] **********************************************************************************************************************************
ok: [node1] => {
"msg": "print users: [{u'gender': u'famale', u'name': u'natasha'}, {u'gender': u'male', u'name': u'tom'}]"
}
ok: [node2] => {
"msg": "print users: [{u'gender': u'famale', u'name': u'natasha'}, {u'gender': u'male', u'name': u'tom'}]"
}
TASK [debug] **********************************************************************************************************************************
ok: [node1] => {
"users": [
{
"gender": "famale",
"name": "natasha"
},
{
"gender": "male",
"name": "tom"
}
]
}
ok: [node2] => {
"users": [
{
"gender": "famale",
"name": "natasha"
},
{
"gender": "male",
"name": "tom"
}
]
}

2.1.2. 通过vars_files关键字引入变量文件

下面是一个简单示例:

- hosts: web
vars_files:
- ntp.yml
- users.yml
tasks:
- package:
name: ntpdate
state: present
- cron:
name: sync time
minute: "*/5"
job: "ntpdate {{ ntpserver }}"
- debug:
msg: "print users: {{ users }}"
- debug:
var: users

[root@node1 ansible]# vim ntp.yml

ntpserver: ntp3.aliyun.com

[root@node1 ansible]# vim users.yml

users:
- name: natasha
gender: famale
- name: tom
gender: male

变量的定义格式是成键值对出现的,键值对之间可以嵌套,最终形成一个大字典,效果和前面一样

2.2 在playbook中通过host_vars和group_vars目录定义变量

定义inventory

demo5.example.com
[datacenter1]
demo1.example.com
demo2.example.com [datacenter2]
demo3.example.com
demo4.example.com [webserver]
demo1.example.com
demo2.example.com
demo3.example.com [mysqlserver]
demo4.example.com
demo5.example.com [datacenters:children]
datacenter1
datacenter2

创建两个目录

[root@node1 ansible]# mkdir group_vars
[root@node1 ansible]# mkdir host_vars

这两个目录用于存放变量的配置文件

主机组使用变量

[root@node1 ansible]# vim group_vars/datacenter1
package: "tomacat1"
[root@node1 ansible]# vim group_vars/datacenter2
package: "tomacat2"
[root@node1 ansible]# vim group_vars/datacenters
package: "tomacat3"
[root@node1 ansible]# vim group_vars/mysqlserver
package: "mysql"

主机变量

[root@node1 ansible]# vim host_vars/demo1.example.com
package: "nginx1"
[root@node1 ansible]# vim host_vars/demo3.example.com
package: "nginx3"
[root@node1 ansible]# vim host_vars/demo5.example.com
package: "nginx5"

目录结构

[root@node1 ansible]# tree
.
├── ansible.cfg
├── group_vars
│   ├── datacenter1
│   ├── datacenter2
│   ├── datacenters
│   └── mysqlserver
├── hosts
├── host_vars
│   ├── demo1.example.com
│   ├── demo3.example.com
│   └── demo5.example.com
├── inventory
└── roles

[root@node1 ansible]# cat datacenter.yml

- hosts:  datacenter1
tasks:
- name: fetch vars
debug:
msg: "{{ package}}"

执行

TASK [fetch vars] *****************************************************************************************************************************
ok: [demo1.example.com] => {
"msg": "nginx1"
}
ok: [demo2.example.com] => {
"msg": "tomacat1"
}

[root@node1 ansible]# vim datacenter.yml

- hosts: all
tasks:
- name: fetch vars
debug:
msg: "{{ package}}"

root@node1 ansible]# ansible-playbook datacenter.yml

TASK [fetch vars] *****************************************************************************************************************************
ok: [demo4.example.com] => {
"msg": "tomcat2"
}
ok: [demo5.example.com] => {
"msg": "nginx5"
}
ok: [demo1.example.com] => {
"msg": "nginx1"
}
ok: [demo2.example.com] => {
"msg": "tomacat1"
}
ok: [demo3.example.com] => {
"msg": "nginx3"
}

如果主机组定义的变量与主机冲突,主机变量优先级最高

2.3  注册变量

在有些时候,可能需要将某一条任务执行的结果保存下来,以便在接下的任务中调用或者做些判断。可以通过register关键字来实现将某一任务结果保存为一个变量。

注册变量的应用场景:

  • 在一台远端的服务器获取一个目录下的一列表的文件,然后下载这些文件
  • 在handler执行之前,发现前面一个task发生了changed,然后执行一个指定的task
  • 获取远端服务器的ssh key的内容,构建出known_hosts文件

[root@node1 ansible]# vim var_test.yml

- hosts: demo5.example.com
tasks:
- name: list /home
shell: ls /home
register: list
- debug:
var: list

[root@node1 ansible]# ansible-playbook var_test.yml

PLAY [demo5.example.com] **********************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [demo5.example.com]
TASK [list /home] *****************************************************************************************************************************
changed: [demo5.example.com]
TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"list": {
"changed": true,
"cmd": "ls /home",
"delta": "0:00:00.005802",
"end": "2020-01-28 13:09:38.768490",
"failed": false,
"rc": 0, #命令执行的正常的返回
"start": "2020-01-28 13:09:38.762688",
"stderr": "",
"stderr_lines": [],
"stdout": "ansible\njoy", #换行输出
"stdout_lines": [ #这个包含也是的是正常的返回
"ansible",
"joy"
]
}
}
PLAY RECAP ************************************************************************************************************************************
demo5.example.com : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

当shell执行报错,错误可以使用ignore_error忽略,继续执行

[root@node1 ansible]# vim var_test.yml

- hosts: demo5.example.com
tasks:
- name: list /home
shell: ls /home
register: list
- shell: error_test
register: error
ignore_errors: True
- debug:
var: list
- debug:
var: error

[root@node1 ansible]# ansible-playbook var_test.yml

PLAY [demo5.example.com] **********************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [demo5.example.com]
TASK [list /home] *****************************************************************************************************************************
changed: [demo5.example.com]
TASK [shell] **********************************************************************************************************************************
fatal: [demo5.example.com]: FAILED! => {"changed": true, "cmd": "error_test", "delta": "0:00:00.004308", "end": "2020-01-28 13:21:53.726688", "msg": "non-zero return code", "rc": 127, "start": "2020-01-28 13:21:53.722380", "stderr": "/bin/sh: error_test: command not found", "stderr_lines": ["/bin/sh: error_test: command not found"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"list": {
"changed": true,
"cmd": "ls /home",
"delta": "0:00:00.005806",
"end": "2020-01-28 13:21:53.151761",
"failed": false,
"rc": 0, #正常返回
"start": "2020-01-28 13:21:53.145955",
"stderr": "",
"stderr_lines": [],
"stdout": "ansible\njoy",
"stdout_lines": [
"ansible",
"joy"
]
}
}
TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"error": {
"changed": true,
"cmd": "error_test",
"delta": "0:00:00.004308",
"end": "2020-01-28 13:21:53.726688",
"failed": true,
"msg": "non-zero return code",
"rc": 127, #命令不存在返回
"start": "2020-01-28 13:21:53.722380",
"stderr": "/bin/sh: error_test: command not found", #找到不到命令
"stderr_lines": [
"/bin/sh: error_test: command not found"
],
"stdout": "",
"stdout_lines": []
}
}
PLAY RECAP ************************************************************************************************************************************
demo5.example.com : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1

2.4 通过命令行设置变量

- hosts: '{{ hosts }}'
remote_user: '{{ user }}'
tasks:
- debug:
var: hosts
- debug:
var: user

[root@node1 ansible]# ansible-playbook var_test.yml --extra-vars "hosts=demo5.example.com user=ansible"

或者

[root@node1 ansible]# ansible-playbook var_test.yml --extra-vars '{"hosts":"demo5.example.com","user":"ansible"}'

TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"hosts": "demo5.example.com"
} TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"user": "ansible"
}

2.5 变量的使用和调试

定义一个变量文件

[root@node1 ansible]# vim users.yml

users:
- name: natash
gender: female
hobby:
- swimming
- running
- name: tom
gender: male
hobby:
- football
- basketball
- sleepping

[root@node1 ansible]# vim use_users.yml

- hosts: demo5.example.com
vars_files: #调用变量文件
- users.yml
tasks:
- debug:
var: users #获取users变量的信息结构等

[root@node1 ansible]# ansible-playbook use_users.yml

TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => { #user变量的结构
"users": [ #列表有序
{
"gender": "female",
"hobby": [
"swimming",
"running"
],
"name": "natash"
},
{
"gender": "male",
"hobby": [
"football",
"basketball",
"sleepping"
],
"name": "tom"
}
]
}

获取user当中,第一个用户的第一个爱好

- hosts: demo5.example.com
vars_files:
- users.yml
tasks:
- debug:
var: users[0].hobby[0] #第一个用户的第一个爱好
- debug:
msg: "{{ users[1].hobby[2] }}" #第二个用户的第三个爱好

执行输出

TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"users[0].hobby[0]": "swimming"
} TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"msg": "sleepping"
}

重新定义变量

[root@node1 ansible]# vim users.yml

users:
natash:
- name: natash
gender: female
hobby:
- swimming
- running
tom:
- name: tom
gender: male
hobby:
- football
- basketball
- sleepping

[root@node1 ansible]# vim use_users.yml

- hosts: demo5.example.com
vars_files:
- users.yml
tasks:
- debug:
var: users.natash[0].hobby[0]
- debug:
msg: "{{ users.tom[0].hobby }}" #获取所有爱好

[root@node1 ansible]# ansible-playbook use_users.yml

TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"users.natash[0].hobby[0]": "swimming"
} TASK [debug] **********************************************************************************************************************************
ok: [demo5.example.com] => {
"msg": [
"football",
"basketball",
"sleepping"
]
}

另外的引用变量方式

    - debug:
var: users.natash.0.hobby.0
- debug:
msg: "{{ users.tom.0.hobby }}"
- debug:
msg: "{{ users['tom'][0]['hobby'] }}"

2.6 关于debug介绍

关于输出的debug部分重点说明如下:

  • login: 变量名,其值为一个字典
  • changed:ansible基于此来判断是否发生了状态改变
  • cmd:被调用的命令
  • failed:是否运行失败
  • rc:返回值,0代表正常,非0代表异常
  • stderr:如果出现异常,会在这里显示错误输出
  • stderr_lines:按行分割的错误输出
  • stdout:如果指令正常运行,则在这里输出返回结果
  • stdout:按行分割的返回结果

需要说明的是,通过register注册的变量的结果并不是一成不变的,在不确定返回值的情况下,尽量调试看看输出结果。

关于debug的更多用法说明:

调试模块,用于在调试中输出信息
常用参数:

  • msg:调试输出的消息
  • var:将某个变量传递给debug模块,debug会直接将其打印输出
  • verbosity:debug的级别

博主声明:本文的内容来源主要来自誉天教育晏威老师,由本人实验完成操作验证,需要的博友请联系誉天教育(http://www.yutianedu.com/),获得官方同意或者晏老师(https://www.cnblogs.com/breezey/)本人同意即可转载,谢谢!

006.Ansible自定义变量的更多相关文章

  1. ansible自定义模块

    参考官网:http://www.ansible.com.cn/docs/developing_modules.html#tutorial 阅读 ansible 附带的模块(上面链接)是学习如何编写模块 ...

  2. 【持续集成】[Jenkins]Job中如何传递自定义变量

    [Jenkins]Job中如何传递自定义变量 来自dweiwei   2015-06-27 18:37:19|  分类: 自动化测试 |举报 |字号大中小 订阅 用微信  “扫一扫” 将文章分享到朋友 ...

  3. 【freemaker】之自定义变量,特殊变量 globals ,循环对象取值

    entity public class Employee { private Integer id; private String name; private Integer age; private ...

  4. Shell变量之自定义变量、环境变量

    1:环境变量        环境变量可以帮我们达到很多功能-包括家目录的变换啊.提示字符的显示啊.运行文件搜寻的路径啊等等的那么,既然环境变量有那么多的功能,问一下,目前我的 shell 环境中, 有 ...

  5. v9站点自定义变量

    打开 \phpcms\modules\admin\templates\site_edit.tpl.php 文件,找到最后一个 </fieldset> ,在他后面添加一下代码:<!-- ...

  6. Mysql自定义变量的使用

    用户自定义变量是一个容易被遗忘的MySQL特性,但是如果能用的好,发挥其潜力,在某些场景可以写出非常高效的查询语句.在查询中混合使用过程化和关系化逻辑的时候,自定义变量可能会非常有用.单纯的关系查询将 ...

  7. Linux常用基本命令:三剑客命令之-awk内置变量与自定义变量

    AWK中,变量分为两种:内置变量与自定义变量. 常见的内置变量有: FS:输入字段分隔符, 默认为空白字符 OFS:输出字段分隔符, 默认为空白字符 RS:输入记录分隔符(输入换行符), 指定输入时的 ...

  8. dedecms前端无法调用自定义变量怎么解决

    网友问ytkah说他的dedecms前端无法调用自定义变量要怎么解决,登录他的网站后台看了一下,自定义变量已经添加了,也写入了数据库表中,但是就是前台没办法调用出来,后面想想可能是文件权限不够,具体是 ...

  9. python删除所有自定义变量方法--转载

    http://blog.sina.com.cn/s/blog_b2f983a50102yexs.html   当我们在pythonwin中创建多个变量后,通过dir()函数,可以看到所有已创建变量,这 ...

随机推荐

  1. redis的主从复制(哨兵模式)

    p.p1 { margin: 0; font: 10px ".SF NS Text" } Master以写为主,Slave以读为主 读写分离 容灾恢复 一.一主多从 配置文件修改: ...

  2. MySQL性能压力基准测试工具sysbench

    1.sysbench介绍 这里介绍一款MySQL数据库的压力测试软件sysbench,用它来进行基准测试. sysbench 是一个开源的.模块化的.跨平台的多线程性能测试工具, 可以用来进行CPU. ...

  3. 关于Maven中<packaging>产生的一些问题

    关于Maven中产生的一些问题 一.项目的打包类型 jar 默认的打包格式 war 打包成需要部署的项目 pom 父类型为pom类型 二. pom 简单来说,一个多模块项目通过一个父POM 引用一个或 ...

  4. shell 使用 cat 配合 EOF 创建文件并写入多行内容

    之前折腾 GtiHub Actions 想实现提交 issue 后将 issue 的内容生成一个 Markdown 文件提交到仓库,从而实现自动发布到 GitHub Pages 的目的.倒是有一些现成 ...

  5. HUAWEI AppGallery Connect获得SOC国际权威认证,多举措保护信息和隐私安全

    近日,华为应用市场AppGallery Connect(简称AGC)一次性成功通过国际权威标准组织"美国注册会计师协会(AICPA)"认定的SOC1 Type2.SOC2 Type ...

  6. 3年经验硬抗字节Java岗,25天4轮面试终拿意向书,复述原题及经验

    这次面试字节跳动也是做了很多的准备,还好顺利拿到了offer,特分享一下这次的4面技术面真题,以及一份字节2-2师兄整理的面试手册,希望能够给一些正在面试字节或计划面试大厂的朋友提供帮助. 字节跳动技 ...

  7. Day10_53_Collections.synchronizedList() 将Arraylist集合转换为线程安全的集合

    将Arraylist集合转换为线程安全的集合 import java.util.ArrayList; import java.util.Collections; import java.util.Li ...

  8. jasypt在springboot项目中遇到异常:Error creating bean with name 'enableEncryptablePropertySourcesPostProcessor' defined in class path resource

    背景 在使用jasypt对spring boot的配置文件中的敏感信息进行加密处理时,使用stater直接启动时,遇到了一个异常 <dependency> <groupId>c ...

  9. 代码安全丨第二期:URL重定向(跳转)漏洞

    URL重定向: URL重定向(URLredirection)漏洞,又称跳转漏洞,指的是网络应用程序接受用户可控的输入作为到外部站点的链接,然后在重定向中使用该链接.该安全漏洞给网络钓鱼攻击提供了极大的 ...

  10. 图解高性能网络架构:Reactor 和 Proactor

    小林,来了. 这次就来图解 Reactor 和 Proactor 这两个高性能网络模式. 别小看这两个东西,特别是 Reactor 模式,市面上常见的开源软件很多都采用了这个方案,比如 Redis.N ...