下面来看一个编写Ansible模块并自定义Facts例子,希望例子能帮助到各位.
背景介绍:Ansible自带的Facts有很多,但很多时候并不够用,比如,Ansible就没有ansible_private_ipv4_address这样一个Facts,用来保存私网IP地址.
而我们恰恰就需要这样的一个Facts,因为我们有很多服务器的默认网卡并非是eth0,有的是bond0,eth1,em0,em1等,而公网IP地址与私网IP地址也并没有固定的绑定在某个网卡上,很多时候还是虚拟网卡.
还好,我们可以通过编写Ansible模块并自定义Facts来实现,具体步骤,代码如下:
- [root@idc-server2 ~]# ifconfig
- eth0 Link encap:Ethernet HWaddr 1B:2B:3B:4B:5B:6B
- inet addr:172.16.1.2 Bcast:172.16.1.255 Mask:255.255.252.0
- ...
- eth1 Link encap:Ethernet HWaddr 1A:2A:3A:4A:5A:6A
- inet addr:100.100.100.100 Bcast:100.100.100.255 Mask:255.255.255.240
- ...
- lo Link encap:Local Loopback
- inet addr:127.0.0.1 Mask:255.0.0.0
- ...
- [root@idc-server1 ansible]# vim myfacts.yml
-
- - hosts: idc-server2
- roles:
- - myfacts
- [root@idc-server1 ansible]# mkdir -p roles/myfacts/{tasks,templates}
- [root@idc-server1 ansible]# vim roles/myfacts/tasks/main.yml
-
- - name: run myfacts module to get customized facts
- myfacts: get_facts=yes
- - name: update file with the customized facts
- template: src=myfacts.txt.j2 dest=/tmp/myfacts.txt
- [root@idc-server1 ansible]# vim roles/myfacts/templates/myfacts.txt.j2
- ansible_private_ipv4_address : {{ ansible_private_ipv4_address }}
- [root@idc-server1 ansible]# mkdir /usr/share/ansible/heylinux
- [root@idc-server1 ansible]# vim /usr/share/ansible/heylinux/myfacts
- #!/usr/bin/python
- import sys
- import json
- import shlex
- import commands
- import re
- def get_ansible_private_ipv4_address():
- iprex = "(^192.168)|(^10.)|(^172.1[6-9])|(^172.2[0-9])|(^172.3[0-1])"
- output = commands.getoutput("""/sbin/ifconfig |grep "Link encap" |awk '{print $1}' |grep -wv 'lo'""")
- nics = output.split('n')
- t_nic_info = ""
- for i in nics:
- ipaddr = commands.getoutput("""/sbin/ifconfig %s |grep -w "inet addr" |cut -d: -f2 | awk '{print $1}'""" % (i))
- if re.match(iprex,ipaddr):
- ansible_private_ipv4_address = ipaddr
- return ansible_private_ipv4_address
-
- args_file = sys.argv[1]
- args_data = file(args_file).read()
- arguments = shlex.split(args_data)
- for arg in arguments:
- if "=" in arg:
- (key, value) = arg.split("=")
- if key == "get_facts" and value == "yes":
- ansible_private_ipv4_address = get_ansible_private_ipv4_address()
-
- print json.dumps({
- "changed" : False,
- "ansible_facts" : {
- "ansible_private_ipv4_address" : ansible_private_ipv4_address
- }
- })
- sys.exit(0)
- print json.dumps({
- "changed" : False
- })
- [root@idc-server1 ansible]# ansible-playbook -u root myfacts.yml -i hosts
- PLAY [idc1-server2] ***************************************************************
- GATHERING FACTS ***************************************************************
- ok: [idc1-server2]
- TASK: [myfacts | run myfacts module to get customized facts] **************
- ok: [idc1-server2]
- TASK: [myfacts | update file with the customized facts] *********************
- changed: [idc1-server2]
- PLAY RECAP ********************************************************************
- idc1-server2 : ok=3 changed=1 unreachable=0 failed=0
- [root@idc-server1 ansible]# ssh idc1-server2 'cat /tmp/myfacts.txt'
- ansible_private_ipv4_address : 172.16.1.2
|