ansible中的变量主要来源于以下几种场景:
- Inventory(host vars,group vars)
- playbook里面
- 命令行
- playbook执行task过程中产生结果,可以register起来,作为变量给下面的task使用
- roles里面
- 来自于nodes上面的facts
其中1-4一般来说都是用户自己定义的,而5和facts则主要是ansible从nodes上面拉取过来,当然facts也可以自己定义。
Inventory里面的变量
/etc/ansible/hosts
[salt]
salt-master http_port=80 ##主机变量
10.240.162.112 ansible_connection=paramiko
[salt:vars] ##组变量
mysql_port=3306
/etc/ansible/host_vars/salt-master ##定义在文件里主机变量,文件名和主机名要一致
lxc:lixc
/etc/ansible/group_vars/salt ##定义在文件里的组变量,文件名要和组名一致
lss:
- liss
- ansible
playbooks里面的变量
---
- hosts: all
user: lixc
vars:
time: 120 ##变量
port: 80
keeplive: 100
vars_files:
- /vars/test.yml ##也可以导入外部的文件里的变量
playbooks里面可以定义变量,也可以导入外部的文件里面的变量
命令行里面的变量
命令行,传递变量给playbooks大概有三种方式
第1种方式,比较简单了。
cat command_vars.yml
---
- hosts: salt-master
remote_user: ‘{{uservar}}‘ ##命令行变量
tasks:
- name: run this command and ignore the result
shell: echo {{echovar}}
- debug: msg=‘{{result.stdout}}‘
ansible-playbook command_vars.yml -e "uservar=lixc echovar=hellomysql" ##传入变量参数
第2种方式,以json的格式传递变量。
ansible-playbook command_vars.yml -e ‘{"uservar":"lixc", "echovar":"hellomysql"}‘
##变量形式较复杂的时候,用json格式较方便,一般的直接用第一种方式就可以了
第3种方式,传入json文件。第二种,第三种方法,一般用于变量形式较复杂的情况。不过,一般估计很少用,因为在命令行传变量本来就不多用吧,还是第一种命令行传递方式稍微常用点。
cat test.json ##json文件
uservar: lixc
echocar: hellomysql
ansible-playbook command_vars.yml -e ‘@test.json‘ ##用@加上json文件
第4种方式,register task的结果,作为变量,给下面的task使用
---
- hosts: slat-master
tasks:
- name: test
command: ls /home
register: result
- debug: msg=‘{{result.stdout}}‘
第五种方式,在roles里定义。
├── group_vars ##全局组变量
│ └── salt
├── hosts
├── roles
│ ├── mysql
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── configure.yml
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ └── my.cnf
│ │ └── vars ##当前role变量
│ │ └── main.yml
第六种方方式,从nodes获取facts,facts和salt-stack里面的grains差不多,主要是nodes本身的一个系统信息,bios信息,网络,硬盘等等信息。不过,facts比salt-stack中的grains获取的信息。要更多一些。
ansible slat-master -m setup|wc -l ##查看facts
284
salt ‘*’ grains.items|wc -l ##查看grains
65
自定义facts
自定义facts有多种方法,有能力的同学,可以直接去修改,setup这个模块。不过官方的东西,咱们还是不要随便改了。
第二种方法,定义在nodes上面,默认定义在/etc/ansible/fact.d/*fact里面。
定义文件的格式,大概三种,分别是ini格式,json格式,或者可执行文件,不过他们返回的必须是json格式。
lixc.fact
{"json":["hello","world"]} ##这个文件内容是json格式
lss.fact
#!/usr/bin/env python ##这个文件是python脚本,返回json格式的字典
import json
dic = {"ansible_addresses": ["10.240.161.139","192.168.115.164"]}
print json.dumps(dic)
lxc.fact
[ini] ##ini格式
lixc=hello
lss=world
在node上创建文件夹并把测试的fact文件传送过去。修改lss.fact这个文件的属性为其它组可执行的权限,否则待会执行不了,用-s参数试了下,也执行不了
ansible salt-master -a "mkdir -p /etc/ansible/fact.d" -s
for file in `ls `;do ansible salt-master -m copy -a "src=${file} dest=/etc/ansible/facts.d/" -s;done >/dev/null
ansible salt-master -m file -a "dest/etc/ansible/facts.d/lss.fact mode=755" > /dev/null -s
##上述有修改python脚本属性,待会要执行
ansible salt-master -m setup -a "filter=ansible_local"
自定义模块,只不过这个模块,返回一个facts格式的结果罢了。
在ansible的module里面,自定义一个文件夹,放自己的module,然后丢给自定义的module进去
mkdir /usr/share/ansible/custom
cat chengge
#!/usr/bin/env python
import json
dic = {"ansible_facts": {‘chengge‘: ‘Hello ansible‘,‘liss‘: "Hello salt=stack"}}
print json.dumps{dic}
##字典的key要为ansible_facts,要不然playbooks里不能用facts了
cp chengge /usr/share/ansible/custom
ansible salt-master -m chengge
具体如何使用自定义模块:
其实,我们想用模块里返回的facts,那么显然,我们使用之前,肯定要先执行以下我们自定义的module
先看看playbooks
---
- hosts: slat-master
tasks:
- name: test custom module
action: chengge ##先执行下自定义module
- debug: msg=‘{{chengge}}‘ ##使用facts
再看看,执行结果