目录
(2)var:打印指定的变量,一般是通过register注册了的变量
ansible上playbook的debug是一个常用的调试模块,主要用于在playbook执行(调试、引用变量)过程输出一些关键信息,并且可以对这些关键信息进行一定的格式化输出和条件判断
- 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/uptime
- register: result
-
- - debug:
- var: result
- verbosity: 2
-
- - name: Display all variables/facts known for a host
- debug:
- 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."
演示效果
- [root@main ~]# cat iduser.yaml
- ---
- - name: is su exist
- hosts: webservers
- tasks:
- - name: test su
- shell: id su
- register: su
- ignore_errors: yes
- - name: echo it
- debug:
- 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
演示效果
- [root@main ~]# cat iduser.yaml
- ---
- - name: is su exist
- hosts: servera
- tasks:
- - name: test su
- shell: id su
- register: su
- ignore_errors: yes
- - name: echo it
- debug:
- 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
以下面代码段为例:
"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)"
- ]
- }
- }
- [root@main ~]# cat iduser.yaml
- ---
- - name: is su exist
- hosts: servera
- tasks:
- - name: test su
- shell: id su
- register: su
- ignore_errors: yes
- - name: echo it
- debug:
- msg: "用户存在"
- when: su.rc==0 #当返回值为0时才输出msg
- [root@main ~]# cat iduser.yaml
- ---
- - name: is su exist
- hosts: servera
- tasks:
- - name: test su
- shell: id su
- register: su
- ignore_errors: yes
- - name: echo it
- debug:
- msg: "用户存在"
- #when: su.rc==0
- when: 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
-
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 facter
- setup:
- gather_subset:
- - '!all'
- - '!any'
- - facter
- [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
- }
- [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}
可以为某写主机手动定制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: servera
- vars:
- remote_dir: /etc/ansible/facts.d
- facts_file: cus.fact
- tasks:
- - name: create remote_dir in servera
- file:
- state: directory
- recurse: yes
- path: "{{ remote_dir }}"
- - name: copy local cus.fact
- copy:
- 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: servera
- tasks:
- - name: using servera local fact to start httpd
- service:
- 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
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: something
- other_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: something
- other_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: yes
- other_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: servera
- tasks:
- - name: cal pool size
- set_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
运行playbook时,ansible会先ssh到受管节点去采集fact,如果收集信息过多过大会影响执行速度和效率,可以选择关闭采集或先关闭采集完成任务再重新采集
- #显式采集行为
- TASK [Gathering Facts] **************************************************************************************************************************
- ok: [servera]
示例:上述情况下,我们可以使用gather_facts显式关闭fact采集,然后执行完任务再重新采集facts
- [root@main ~]# cat nogather.yaml
- ---
- - hosts: servera
- gather_facts: false
- tasks:
- - name: debug this
- debug: msg="hello"
- - name: wait for 10
- wait_for:
- timeout: 6
- - name: regather facts
- setup:
- 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
在playbook中引入fact时可以设置fact缓存,目前以是json、redis、memcached三种方式,以下是需要修改的ansible.cfg的defaults部分参数
是否开启fact支持三个选项:smart(默认采集facts,facts已存在时不采集,即缓存),implicit(默认采集facts,可以使用"gather_facts: false"来禁止采集),explicit(默认不采集,可以使用"gather_facts: true"来假期采集)
缓存时间,秒为单位
缓存方式,jsonfile,redis,memcached
指定fact缓存的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
需要安装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>
(1)作用
用于获取某台受管节点的相关变量,通过hostvars来指定受管节点和需要获取的信息,并将这整个语句作为一个变量
(2)基本格式
- "{{ hostvars['受管节点'].ansible_该节点网卡名称.ipv4.address }}"
- 示例:获取servera的IPV4地址,需要用到servera的网卡连接名称
-
- [root@main ~]# cat getserveraip.yaml
- ---
- - hosts: servera
- tasks:
- - name: get serveraip
- debug:
- var: "{{ hostvars['servera'].ansible_ens33.ipv4.address }}"
-
- [root@main ~]# ansible-playbook getserveraip.yaml
-
- PLAY [servera] **********************************************************************************************************************************
-
- TASK [get serveraip] ****************************************************************************************************************************
- ok: [servera] => {
- "192.168.2.131": "VARIABLE IS NOT DEFINED!"
- }
-
- PLAY RECAP **************************************************************************************************************************************
- servera : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(1)作用
用来识别正在运行的管理节点的主机名,若在inventory中定义过别名那么会识别别名,若是IP就会识别IP,其中若是别名较长,使用inventory_hostname_short可以只获取最前一个域
(2)示例
- [root@main ~]# cat myhosts
- 192.168.2.131
- serverb
- serverc.ex.com ansible_host=192.168.2.133
-
- [root@main ~]# ansible all -m debug -a 'msg="{{inventory_hostname}}"'
- 192.168.2.131 | SUCCESS => {
- "msg": "192.168.2.131"
- }
- serverb | SUCCESS => {
- "msg": "serverb"
- }
- serverc.ex.com | SUCCESS => {
- "msg": "serverc.ex.com"
- }
-
- [root@main ~]# ansible all -m debug -a 'msg="{{inventory_hostname_short}}"' #短获取
- 192.168.2.131 | SUCCESS => {
- "msg": "192"
- }
- serverb | SUCCESS => {
- "msg": "serverb"
- }
- serverc.ex.com | SUCCESS => {
- "msg": "serverc"
- }
-
- [root@main ~]# cat getserveraip.yaml #识别成功
- ---
- - hosts: all
- tasks:
- - name: get server
- debug:
- var: "{{ hostvars[inventory_hostname].ansible_ens33.ipv4.address }}"
-
- TASK [get server] *******************************************************************************************************************************
- ok: [192.168.2.131] => {
- "192.168.2.131": "VARIABLE IS NOT DEFINED!"
- }
- ok: [serverb] => {
- "192.168.2.132": "VARIABLE IS NOT DEFINED!"
- }
- ok: [serverc.ex.com] => {
- "192.168.2.133": "VARIABLE IS NOT DEFINED!"
- }
识别正在运行的管理节点的主机组
- [root@main ~]# cat myhosts
- [webservers]
- servera
- serverb
- [dbserver]
- serverc
- [webgroup:children]
- webservers
-
- [root@main ~]# ansible all -m debug -a 'msg="{{group_names}}"'
- serverc | SUCCESS => {
- "msg": [
- "dbserver"
- ]
- }
- servera | SUCCESS => {
- "msg": [
- "webgroup",
- "webservers"
- ]
- }
- serverb | SUCCESS => {
- "msg": [
- "webgroup",
- "webservers"
- ]
- }
识别inventory文件中所有主机组,并且可以枚举出其中的所有主机。
- [root@main ~]# cat myhosts
- [webservers]
- servera
- serverb
- [dbserver]
- serverc
- [webgroup:children]
- webservers
-
- [root@main ~]# ansible all -m debug -a 'msg="{{groups}}"'
- serverc | SUCCESS => {
- "msg": {
- "all": [
- "serverc",
- "servera",
- "serverb"
- ],
- "dbserver": [
- "serverc"
- ],
- "ungrouped": [],
- "webgroup": [
- "servera",
- "serverb"
- ],
- "webservers": [
- "servera",
- "serverb"
- ]
- }
- }
- servera | SUCCESS => {
- "msg": {
- "all": [
- "serverc",
- "servera",
- "serverb"
- ],
- "dbserver": [
- "serverc"
- ],
- "ungrouped": [],
- "webgroup": [
- "servera",
- "serverb"
- ],
- "webservers": [
- "servera",
- "serverb"
- ]
- }
- }
- serverb | SUCCESS => {
- "msg": {
- "all": [
- "serverc",
- "servera",
- "serverb"
- ],
- "dbserver": [
- "serverc"
- ],
- "ungrouped": [],
- "webgroup": [
- "servera",
- "serverb"
- ],
- "webservers": [
- "servera",
- "serverb"
- ]
- }
- }
当前的playbook将在哪些节点上运行
主机清单所在的目录
- [root@main ~]# ansible all -m debug -a 'msg="{{inventory_dir}}"'
- serverc | SUCCESS => {
- "msg": "/root"
- }
- servera | SUCCESS => {
- "msg": "/root"
- }
- serverb | SUCCESS => {
- "msg": "/root"
- }
哪个是主机清单文件
- [root@main ~]# ansible all -m debug -a 'msg="{{inventory_file}}"'
- serverc | SUCCESS => {
- "msg": "/root/myhosts"
- }
- servera | SUCCESS => {
- "msg": "/root/myhosts"
- }
- serverb | SUCCESS => {
- "msg": "/root/myhosts"
- }