目录
一.debug模块的使用方法
1.帮助文档给出的示例
2.主要用到的参数
(1)msg:主要用这个参数来指定要输出的信息
(2)var:打印指定的变量,一般是通过register注册了的变量
(3)verbosity:调试级别,默认是0表示全部显示
3.输出信息详解
4.在debug中使用when做条件判断
(1)通过rc的结果做判断
(2)通过是否failed做判断
二.fact变量
1.setup简单用法演示
(1)通过filter进行过滤
(2)--tree将信息输出到指定目录
2.手动设置fact
3.使用set_fact模块定义变量
4.手动采集变量
三.fact缓存
1.json方式
2.redis方式
3.memcached方式基本已弃用
一.debug模块的使用方法
ansible上playbook的debug是一个常用的调试模块,主要用于在playbook执行(调试、引用变量)过程输出一些关键信息,并且可以对这些关键信息进行一定的格式化输出和条件判断
1.帮助文档给出的示例
EXAMPLES:
# 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
# Example that prints return information from the previous task
- shell: /usr/bin/uptimeregister: result
- debug:var: resultverbosity: 2
- name: Display all variables/facts known for a hostdebug:var: hostvars[inventory_hostname]verbosity: 4
# Example that prints two lines of messages, but only if there is an environment value set
- debug:msg:- "Provisioning based on YOUR_KEY which is: {{ lookup('env', 'YOUR_KEY') }}"- "These servers were built using the password of '{{ password_used }}'. Please retain this for later use."
2.主要用到的参数
(1)msg:主要用这个参数来指定要输出的信息
演示效果
[root@main ~]# cat iduser.yaml
---
- name: is su existhosts: webserverstasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:msg: "用户存在"[root@main ~]# ansible-playbook iduser.yaml
PLAY [is su exist] ******************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
TASK [test su] **********************************************************************************************************************************
changed: [servera]
TASK [echo it] **********************************************************************************************************************************
ok: [servera] => {"msg": "用户存在"
}
PLAY RECAP **************************************************************************************************************************************
servera : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(2)var:打印指定的变量,一般是通过register注册了的变量
演示效果
[root@main ~]# cat iduser.yaml
---
- name: is su existhosts: serveratasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:var: su #打印前面已经注册了的“su”变量
[root@main ~]# ansible-playbook iduser.yaml
PLAY [is su exist] ******************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
TASK [test su] **********************************************************************************************************************************
changed: [servera]
TASK [echo it] **********************************************************************************************************************************
ok: [servera] => {"su": {"changed": true, "cmd": "id su", "delta": "0:00:00.002850", "end": "2023-10-19 14:12:43.406662", "failed": false, "rc": 0, "start": "2023-10-19 14:12:43.403812", "stderr": "", "stderr_lines": [], "stdout": "uid=1000(su) gid=1000(su) groups=1000(su)", "stdout_lines": ["uid=1000(su) gid=1000(su) groups=1000(su)"]}
}
PLAY RECAP **************************************************************************************************************************************
servera : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(3)verbosity:调试级别,默认是0表示全部显示
3.输出信息详解
以下面代码段为例:
"su":表示变量,在输出信息中它是一个字典类型
changed:根据此值来判断是否发生了状态改变
cmd:过程中调用的命令
failed:是否运行失败
rc:返回值,为0成功,非0失败或异常
stderr:出现异常时会在这显示错误信息
stderr_lines:以行分割的格式输出错误信息
stdout:运行成功会在此处输出返回结果
stdout_lines:以行分割的格式输出结果
ok: [servera] => {"su": {"changed": true, "cmd": "id su", "delta": "0:00:00.002850", "end": "2023-10-19 14:12:43.406662", "failed": false, "rc": 0, "start": "2023-10-19 14:12:43.403812", "stderr": "", "stderr_lines": [], "stdout": "uid=1000(su) gid=1000(su) groups=1000(su)", "stdout_lines": ["uid=1000(su) gid=1000(su) groups=1000(su)"]}
}
4.在debug中使用when做条件判断
(1)通过rc的结果做判断
[root@main ~]# cat iduser.yaml
---
- name: is su existhosts: serveratasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:msg: "用户存在"when: su.rc==0 #当返回值为0时才输出msg
(2)通过是否failed做判断
[root@main ~]# cat iduser.yaml
---
- name: is su existhosts: serveratasks:- name: test sushell: id suregister: suignore_errors: yes- name: echo itdebug:msg: "用户存在"#when: su.rc==0when: su is not failed #当su变量的结果不失败时才输出
[root@main ~]# ansible-playbook iduser.yaml
PLAY [is su exist] ******************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
TASK [test su] **********************************************************************************************************************************
changed: [servera]
TASK [echo it] **********************************************************************************************************************************
ok: [servera] => {"msg": "用户存在"
}
PLAY RECAP **************************************************************************************************************************************
servera : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
二.fact变量
setup用于获取受管节点的详细信息(硬盘、IP、cpu等信息),可以将信息作为变量在playbook中引用,setup依赖fact进行获取信息
EXAMPLES:
# Display facts from all hosts and store them indexed by I(hostname) at C(/tmp/facts).
# ansible all -m setup --tree /tmp/facts
# Display only facts regarding memory found by ansible on all hosts and output them.
# ansible all -m setup -a 'filter=ansible_*_mb'
# Display only facts returned by facter.
# ansible all -m setup -a 'filter=facter_*'
# Collect only facts returned by facter.
# ansible all -m setup -a 'gather_subset=!all,!any,facter'
- name: Collect only facts returned by factersetup:gather_subset:- '!all'- '!any'- facter
1.setup简单用法演示
(1)通过filter进行过滤
[root@main ~]# ansible servera -m setup -a 'filter=ansible_*_ipv4'
servera | SUCCESS => {"ansible_facts": {"ansible_default_ipv4": {"address": "192.168.2.131", "alias": "ens33", "broadcast": "192.168.2.255", "gateway": "192.168.2.1", "interface": "ens33", "macaddress": "00:0c:29:bc:03:89", "mtu": 1500, "netmask": "255.255.255.0", "network": "192.168.2.0", "type": "ether"}, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}
(2)--tree将信息输出到指定目录
[root@main ~]# ansible servera -m setup -a 'filter=ansible_*_mb' --tree /root/facts
[root@main ~]# cat facts/servera
{"ansible_facts": {"ansible_memfree_mb": 5327, "ansible_memory_mb": {"nocache": {"free": 5510, "used": 338}, "real": {"free": 5327, "total": 5848, "used": 521}, "swap": {"cached": 0, "free": 2047, "total": 2047, "used": 0}}, "ansible_memtotal_mb": 5848, "ansible_swapfree_mb": 2047, "ansible_swaptotal_mb": 2047, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false}
2.手动设置fact
可以为某写主机手动定制fact,称其为本地fact,将管理节点定义好的fact文件传输给需要定制fact的节点,定制的fact默认存放在受管节点的/etc/ansible/facts.d目录下,
示例:为server节点自定义一个fact,使用这个fact启动servera上的httpd服务,此示例主要用到三个文件(cus.fact、afact.yaml、useafact.yaml),都放在同一目录下
[root@main ~]# cat cus.fact #在管理节点定义好fact文件
[su]
mypkg=httpd
myser=httpd
state=started
[root@main ~]# cat afact.yaml
#定义yaml文件,在受管节点创建/etc/ansible/facts.d目录,将fact文件拷贝至这个目录
---
- hosts: serveravars:remote_dir: /etc/ansible/facts.dfacts_file: cus.facttasks:- name: create remote_dir in serverafile:state: directoryrecurse: yespath: "{{ remote_dir }}"- name: copy local cus.factcopy:src: "{{ facts_file }}"dest: "{{ remote_dir }}"
[root@main ~]# ansible servera -m setup -a 'filter="ansible_local"'
#成功在servera上过滤出本地fact
servera | SUCCESS => {"ansible_facts": {"ansible_local": {"cus": {"su": {"mypkg": "httpd", "myser": "httpd", "state": "started"}}}, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}
[root@main ~]# cat useafact.yaml #为servera定义yaml文件引用其下的fact进行启动httpd
---
- hosts: serveratasks:- name: using servera local fact to start httpdservice:name: "{{ ansible_facts.ansible_local.cus.su.myser }}"#引用方式较长(ansible的facts.本地的.fact文件.fact内的字段名)state: "{{ ansible_facts.ansible_local.cus.su.state }}"
[root@main ~]# ansible-playbook useafact.yaml
PLAY [servera] **********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
TASK [using servera local fact to start httpd] **************************************************************************************************
changed: [servera]
PLAY RECAP **************************************************************************************************************************************
servera : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@main ~]# ansible servera -m shell -a 'systemctl status httpd | grep Active'
#启动成功
servera | CHANGED | rc=0 >>Active: active (running) since Thu 2023-10-19 15:15:09 CST; 5s ago
3.使用set_fact模块定义变量
set_fact用于自定义facts,从而通过template或作为变量在playbook中被引用,set_fact定义的变量只能在此playbook中使用有效
EXAMPLES:
# Example setting host facts using key=value pairs, note that this always creates strings or booleans
- set_fact: one_fact="something" other_fact="{{ local_var }}"
# Example setting host facts using complex arguments
- set_fact:one_fact: somethingother_fact: "{{ local_var * 2 }}"another_fact: "{{ some_registered_var.results | map(attribute='ansible_facts.some_fact') | list }}"
# Example setting facts so that they will be persisted in the fact cache
- set_fact:one_fact: somethingother_fact: "{{ local_var * 2 }}"cacheable: yes
# As of Ansible 1.8, Ansible will convert boolean strings ('true', 'false', 'yes', 'no')
# to proper boolean values when using the key=value syntax, however it is still
# recommended that booleans be set using the complex argument style:
- set_fact:one_fact: yesother_fact: no
示例:通过set_fact计算进程使用内存的情况,这个计算结果也可以在playbook中引用
[root@main ~]# ansible servera -m setup -a 'filter="ansible_memtotal_mb"'
servera | SUCCESS => {"ansible_facts": {"ansible_memtotal_mb": 5848, #先过滤一下看参数是否存在"discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}
[root@main ~]# cat initfree.yaml
---
- hosts: serveratasks:- name: cal pool sizeset_fact: #定义一个变量为这个计算结果pool_size: "{{ ansible_memtotal_mb / 2 | int}}"- debug:var: pool_size #输出这个变量
[root@main ~]# ansible-playbook initfree.yaml
PLAY [servera] **********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
TASK [cal pool size] ****************************************************************************************************************************
ok: [servera]
TASK [debug] ************************************************************************************************************************************
ok: [servera] => {"pool_size": "2924.0"
}
PLAY RECAP **************************************************************************************************************************************
servera : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.手动采集变量
运行playbook时,ansible会先ssh到受管节点去采集fact,如果收集信息过多过大会影响执行速度和效率,可以选择关闭采集或先关闭采集完成任务再重新采集
#显式采集行为
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
示例:上述情况下,我们可以使用gather_facts显式关闭fact采集,然后执行完任务再重新采集facts
[root@main ~]# cat nogather.yaml
---
- hosts: serveragather_facts: falsetasks:- name: debug thisdebug: msg="hello"- name: wait for 10wait_for:timeout: 6- name: regather factssetup:gather_subset: all #参考EXAMPLES
[root@main ~]# ansible-playbook nogather.yaml
PLAY [servera] **********************************************************************************************************************************
TASK [debug this] *******************************************************************************************************************************
ok: [servera] => {"msg": "hello"
}
TASK [wait for 10] ******************************************************************************************************************************
ok: [servera]
TASK [regather facts] ***************************************************************************************************************************
ok: [servera]
PLAY RECAP **************************************************************************************************************************************
servera : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
三.fact缓存
在playbook中引入fact时可以设置fact缓存,目前以是json、redis、memcached三种方式,以下是需要修改的ansible.cfg的defaults部分参数
- gathering
是否开启fact支持三个选项:smart(默认采集facts,facts已存在时不采集,即缓存),implicit(默认采集facts,可以使用"gather_facts: false"来禁止采集),explicit(默认不采集,可以使用"gather_facts: true"来假期采集)
- fact_caching_timeout
缓存时间,秒为单位
- fact_caching
缓存方式,jsonfile,redis,memcached
- fact_caching_connection
指定fact缓存的json文件位置,若没有会自动创建
1.json方式
此方式下,ansible会将fact写入控制主机的文件中
#在ansible.cfg配置文件的defaults模块加这些参数
gathering=smart
fact_caching_timeout=86400
fact_caching=jsonfile
fact_caching_connection=/root/ansible_fact_cache
示例:
执行一个会采集fact的playbook,查看是否将fact缓存到指定的位置
[root@main ~]# cat ansible.cfg
[defaults]
......
gathering=smart
fact_caching_timeout=86400
fact_caching=jsonfile
fact_caching_connection=/root/ansible_fact_cache
......
[root@main ~]# ansible-playbook myhttpd.yaml
PLAY [stop servera httpd] ***********************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [servera]
TASK [stop it] **********************************************************************************************************************************
ok: [servera]
PLAY [install serverb mod_ssl] ******************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [serverb]
TASK [install it] *******************************************************************************************************************************
ok: [serverb]
PLAY RECAP **************************************************************************************************************************************
servera : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@main ~]# ll /root/ansible_fact_cache/ #查看
total 56
-rw-r--r-- 1 root root 25052 Oct 19 18:00 servera
-rw-r--r-- 1 root root 25071 Oct 19 18:00 serverb
2.redis方式
需要安装redis服务且保持运行,还需要安装python支持redis的相关包,更改ansible.cfg
fact_caching=redis #指定redis方式
fact_caching_connection=127.0.0.1:6379:0 #指定redis服务设备的IP和端口,使用0号数据库
[root@main ~]# yum install -y redis #安装redis
[root@main ~]# systemctl start redis
[root@main ~]# ps -ef | grep redis
redis 4278 1 0 17:50 ? 00:00:00 /usr/bin/redis-server 127.0.0.1:6379
root 4286 1485 0 17:51 pts/0 00:00:00 grep --color=auto redis
[root@main ~]# systemctl enable redis
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service.
[root@main ~]# python --version
Python 2.7.5
[root@main ~]# yum list | grep python2-redis
python2-redis.noarch 2.10.6-2.el7 epel
[root@main ~]# yum install -y python2-redis.noarch #安装对应python版本对应的redis支持包
[root@main ~]# ansible-playbook myhttpd.yaml #再执行一次
[root@main ~]# redis-cli #进入查看
127.0.0.1:6379> keys *
1) "ansible_factsservera"
2) "ansible_factsserverb"
3) "ansible_cache_keys"
127.0.0.1:6379> type "ansible_cache_keys"
zset
127.0.0.1:6379> type "ansible_factsservera" #前两个就是采集的facts
string
127.0.0.1:6379>