简单说明

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等其他语言

下面是一个简单的示例:

# 指定了三台主机,三台主机的用密码分别是P@ssw0rd、123456、45789,指定的ssh连接的用户名分别为root、breeze、bernie,ssh 端口分别为22、22、3055 ,这样在ansible命令执行的时候就不用再指令用户和密码等了

[test]
192.168.1.1 ansible_ssh_user=root ansible_ssh_pass='P@ssw0rd'
192.168.1.2 ansible_ssh_user=breeze ansible_ssh_pass='123456'
192.168.1.3 ansible_ssh_user=bernie ansible_ssh_port=3055 ansible_ssh_pass='456789'

1.2. 定义主机组变量

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

# test组中包含两台主机,通过对test组指定vars变更,相应的host1和host2相当于相应的指定了ntp_server和proxy变量参数值

[test]
host1
host2
[test:vars]
ntp_server=192.168.1.10
proxy=192.168.1.20

主机组变量示例:

# 下面是一个示例,指定了一个武汉组有web1、web2;随州组有web3、web4主机;又指定了一个湖北组,同时包含武汉和随州;同时为该组内的所有主机指定了2个vars变量。设定了一个组中国组,包含湖北、湖南。

[wuhan]
web1
web2 [suizhou]
web4
web3 [hubei:children]
wuhan
suizhou [hubei:vars]
ntp_server=192.168.1.10
zabbix_server=192.168.1.10

2. 在Playbook中定义变量

2.1. 变量的定义方式

2.1.1. 通过vars关键字定义

下面是一个简单示例:

- name: use vars define invrionmemnt
hosts: test
user: ansible
vars:
http_port: 80
server_name: localhost
conf_file: /etc/nginx/conf/default.conf

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

下面是一个简单示例:

- hosts: all
remote_user: root
vars:
favcolor: blue
vars_files:
- vars/external_vars.yml
- vars/user_vars.yml # vars/user_vars.yml示例: users:
bjones:
first_name: Bob
last_name: Jones
home_dirs: /users/bjones
acook:
first_name: Anne
last_name: Cook
home_dirs: /users/acook

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

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

下面这是一个项目的playbook目录结构。这个项目中,包含一个ansible.cfg文件,一个inventory文件,一个playbook.yml文件,一个group_vars目录和一个host_vars目录:

# tree /etc/ansible/playbooks/project
/etc/ansible/playbooks/project
├── ansible.cfg
├── group_vars
│   ├── datacenter1
│   ├── datacenter2
│   └── datacenters
├── host_vars
│   ├── demo1.example.com
│   ├── demo2.example.com
│   ├── demo3.example.com
│   └── demo4.example.com
├── inventory
└── playbook.yml

其中inventory文件的示例如下:

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

可以看到group_vars目录中,定义了三个文件,分别以inventory文件中的三个主机组命名,所以这三个文件中定义的就分别是这三个组可以使用的变量。

# cat datacenter1
package: httpd # cat datacenter2
package: apache # cat datacenters
package: httpd

在host_vars目录中,定义了三个文件,分别以inventory文件中的四个主机命名,所以这四个文件中定义的就分别是这四个主机可以使用的变量。

# cat demo1.example.com
package: httpd # cat demo2.example.com
package: apache # cat demo3.example.com
package: mariadb-server # cat demo4.example.com
package: mysql-server

需要说明的是,如果主机组定义的变量与主机冲突,主机变量优先级最高

2.1.4. 注册变量

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

下面是个简单的例子,将whoami命令执行的结果注册到变量login:

- name: register variables
hosts: test
tasks:
- name: capture output of whoami command
command: whoami
register: login

注册变量的应用场景:

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

2.1.5. 通过命令行设置变量

示例如下:

---
- hosts: '{{ hosts }}'
remote_user: '{{ user }}'
tasks:
- ... ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"

也可以写成类似如下方式:

--extra-vars '{"hosts":"vipers","user":"starbuck"}'

2.2 使用与调试变量

我们通过以上5种方式在playbook中定义了各种变量。说到底,最终的目的,还是为了方便使用。下面我们就看一看具体如何使用这些变量。

2.2.1. 变量的引用

下面是一个变量的基本使用示例,前面的变量定义部分,直接使用的2.1.1中的变量示例:

- name: use vars define variables
hosts: test
vars:
http_port: 80
server_name: localhost
conf_file: /etc/nginx/conf/default.conf tasks:
- name: print variables
shell: echo "{{ http_port }} {{ server_name }} {{ conf_file }}" > /tmp/text.txt

在2.1.2中,我们通过vars_files引用了一个文件user_vars.yml,在该文件中定义了一个稍微复杂的字典变量,现在我想要获取usersbjones用户的first_nameacook用户的home_dirs,可以使用如下方法:

{{ users.bjones.first_name }}
{{ users.acook.home_dirs }}

或者如下写法:

{{ users['bjones']['first_name'] }}
{{ users['acook']['home_dirs'] }}

2.2.2. 变量的调试输出

有些时候,我们在引用变量的时候,可能需要知道变量中包含哪些信息,以方便在执行过程中,对变量做些处理。ansible提供一个debug模块用于调试变量输出:

- name: register variables
hosts: test
tasks:
- name: capture output of whoami command
command: whoami
register: login
- debug: var=login

执行后输出如下:

# ansible-playbook register.yml 

PLAY [register variables] ***************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [10.1.61.187] TASK [capture output of whoami command] *************************************************************************************************************************************
changed: [10.1.61.187] TASK [debug] ****************************************************************************************************************************************************************
ok: [10.1.61.187] => {
"login": {
"changed": true,
"cmd": [
"whoami"
],
"delta": "0:00:00.004279",
"end": "2019-05-24 00:41:43.710398",
"failed": false,
"rc": 0,
"start": "2019-05-24 00:41:43.706119",
"stderr": "",
"stderr_lines": [],
"stdout": "root",
"stdout_lines": [
"root"
]
}
} PLAY RECAP ******************************************************************************************************************************************************************
10.1.61.187 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

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

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

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

关于debug的更多用法说明:

调试模块,用于在调试中输出信息

常用参数:

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

示例:

# Example that prints the loopback address and gateway for each host
- debug: msg="System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}" - debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}"
when: ansible_default_ipv4.gateway is defined - shell: /usr/bin/uptime
register: result - debug: var=result verbosity=2 #直接将上一条指令的结果作为变量传递给var,由debug打印出result的值 - name: Display all variables/facts known for a host
debug: var=hostvars[inventory_hostname] verbosity=4

Ansible8:Playbook循环的更多相关文章

  1. Ansible8:Playbook循环【转】

    在使用ansible做自动化运维的时候,免不了的要重复执行某些操作,如:添加几个用户,创建几个MySQL用户并为之赋予权限,操作某个目录下所有文件等等.好在playbook支持循环语句,可以使得某些需 ...

  2. Ansible playbook循环实践总结<一>

    1.标准Loops 标准loops可以直接减少task的次数,如下: [root@zero01 playbook]# vi loops.yaml --- - hosts: all gather_fac ...

  3. Ansible Playbook 循环

    Standard Loops 为了节省一些打字,重复的任务可以写成如下: - name: add several users user: name: "{{ item }}" st ...

  4. Ansible13:Playbook循环语句

    目录 循环语句 简介 loop关键字说明 在循环语句中注册变量 旧循环语句 1. with_items 2. with_nested 3. with_dict 4. with_fileglob 5. ...

  5. Ansible Playbook 详解

    一.playbook 的简单使用 1.创建文件实例 (1)编辑配置文件 [root@tiejiangSRC1 ~]# cd /etc/ansible/ [root@tiejiangSRC1 ansib ...

  6. ansible playbook基本操作

    一.ansible playbook简单使用 相当于是把模块写入到配置文件里面 vim /etc/ansible/test.yml //写入如下内容: --- - hosts: 127.0.0.1 r ...

  7. Playbook剧本小结

    1.Playbook剧本小结 1.什么是playbook,playbook翻译过来就是"剧本",那playbook组成如下 play: 定义的是主机的角色task: 定义的是具体执 ...

  8. Playbook剧本初识

    目录 1.Playbook剧本初识 2.Playbook变量使用 3.Playbook变量注册 4.Playbook条件语句 5.Playbook循环语句 6.Playbook异常处理 7.Playb ...

  9. Ansible PlayBook语法

    PlayBook语法实例 playbook是由一个或多个play组成的列表,play的主要功能在于将事先归并为一组的主机装扮成事先通过Ansible中的tasks定义好的角色(play的内容被称为ta ...

随机推荐

  1. PHP使用Sublime Text3技巧

    1 下载安装 2 安装Package Control 3 安装插件 4 快捷键 5 项目管理 6 设置代理 PHP开发时,笔者用过EditPlus3.Nodpad++.Vi.Vim和Netbeans, ...

  2. 为什么你学过Java却忘光了——记第一次助教同学见面会

    大约两周之前,主讲老师刘志勇老师和我约定,让我上周四到课堂上和同学们认识.交流一下.一开始我不太明了去和大家见面要说些什么,也不太理解这么做的必要性是什么.但随着日子临近,我请教了周筠老师,周筠老师和 ...

  3. Java 反射 不定参数bug

    遇到的第一个关于反射的bug:java.lang.IllegalArgumentException: wrong number of arguments的问题解析如下: 1.错误bug wrong n ...

  4. Internet History, Technology and Security (Week6)

    Week6 The Internet is desinged based on four-layer model. Each layer builds on the layers below it. ...

  5. 项目冲刺Beta第二篇博客

    Beta版本冲刺计划安排 1.当天站立式会议照片: 2.工作分工: 团队成员 分工 张洪滨060  排行榜界面美化 陈敬轩059  注册成功界面美化 黄兴067  登录界面美化 林国梽068  答题界 ...

  6. printf in KEIL C51

    转自:http://blog.csdn.net/it1988888/article/details/8821713 在keil中printf默认是向串口中发送数据的,所以,如果应用该函数,必须先初始化 ...

  7. 解决tomcat登录需要给角色授权

    1:编辑/usr/local/tomcat/conf/tomcat-users.xml文件,在没有注释的内容中添加: <role rolename="manager-gui" ...

  8. 使用 Vagrant 打造跨平台开发环境fffff

    Vagrant 是一款用来构建虚拟开发环境的工具,非常适合 php/python/ruby/java 这类语言开发 web 应用,“代码在我机子上运行没有问题”这种说辞将成为历史. 我们可以通过 Va ...

  9. delphi手动创建dataset并插入值

    unit Unit1; interface uses  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Syste ...

  10. js小功能记录

    个人日常中遇到的js小功能记录,方便查看. /** * 判断是否包含字符串某字符串 * @param {[type]} str [被检测的字符串] * @param {[type]} substr [ ...