Common modules of Ansible
Ansible provides many modules for us by default. In Linux, we can view all modules currently supported by ansible through the ansible doc - L command, view the parameters in the help document through the ansible doc - S module name, and execute the command through the ansible managed host - m module name - a 'parameter'.
The difference between the shell command **raw * * of the ansible common module:
- The / bin/sh instruction called by the shell module executes
- The command module is not an instruction of the calling shell, so there is no bash environment variable
- Raw is similar to shell in many places. Shell and command modules are recommended in more places. However, if you are using the old version of python, you need to use raw, or if the client is a router, because the python module is not installed, you need to use raw
ping module
The ping module is used to check whether the specified node machine is connected. The usage is very simple and does not involve parameters. If the host is online, it will reply to pong
[root@localhost ansible]# ansible 192.168.100.42 -m ping 192.168.100.42 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "ping": "pong" } [root@localhost ansible]#
shell module
The shell module is used to execute scripts on the managed machine or execute commands directly on the managed machine.
The shell module supports pipeline and redirection
[root@localhost ansible]# ansible all -m shell -a 'ls -l /root' 192.168.100.42 | CHANGED | rc=0 >> total 1 -rwxr-xr-x. 1 root root 23 Jul 18 01:07 ll.sh [root@localhost ansible]# ansible all -m shell -a 'cat /root/ll.sh' 192.168.100.42 | CHANGED | rc=0 >> #!/bin/bash touch test [root@localhost ansible]# ansible all -m shell -a '/root/ll.sh' 192.168.100.42| CHANGED | rc=0 >> [root@localhost ansible]# ansible all -m shell -a 'ls /root' 192.168.100.42 | CHANGED | rc=0 >> ll.sh test [root@localhost ansible]#
command module
The command module is used to execute commands on the remote host. ansible uses the command module by default.
One drawback of the command module is that it cannot use pipeline characters and redirection functions
[root@localhost ansible]# ansible all -m command -a 'ls /tmp' 192.168.100.42 | CHANGED | rc=0 >> ansible_command_payload_5poztdyc hsperfdata_root ks-script-a85snvsm .... [root@localhost ansible]# ansible all -m command -a 'touch /tmp/abc' [WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 192.168.220.8 | CHANGED | rc=0 >> [root@localhost ansible]# ansible all -m command -a 'ls /tmp' #Check whether the abc file is created in the / tmp directory on the managed host 192.168.100.42 | CHANGED | rc=0 >> ansible_command_payload_9563eekh hsperfdata_root ks-script-a85snvsm abc [root@localhost ansible]# ansible all -m command -a 'echo "hello" > /tmp/tabc' 192.168.100.42 | CHANGED | rc=0 >> hello > /tmp/test [root@localhost ansible]# ansible all -m command -a 'cat /tmp/abc' 192.168.100.42 | CHANGED | rc=0 >> [root@localhost ansible]# ansible all -m command -a 'ps -aux | grep ssh' 192.168.100.42 | FAILED | rc=1 >> error: user name does not exist Usage: ps [options] Try 'ps --help <simple|list|output|threads|misc|all>' or 'ps --help <s|l|o|t|m|a>' for additional help text. For more details see ps(1).non-zero return code
raw module
The raw module is used to execute commands on the remote host and supports pipeline characters and redirection
Execute the original command instead of through the module subsystem. In any case, it is appropriate to use a shell or command module. Given the original parameters, it runs directly through the configured remote shell. You can return standard output, error output, and return code. This module does not have change handler support. This module does not require Python on the remote system, just like the script module. This module also supports Windows targets.
[root@localhost ansible]# ansible all -m raw -a 'echo "bbb" > /tmp/abc' 192.168.220.8 | CHANGED | rc=0 >> Shared connection to 192.168.100.42 closed. [root@localhost ansible]# ansible all -m raw -a 'cat /tmp/abc' 192.168.100.42 | CHANGED | rc=0 >> bbb Shared connection to 192.168.100.42 closed. [root@localhost ansible]# ansible all -m raw -a 'ps -aux|grep ssh' 192.168.100.42 | CHANGED | rc=0 >> root 940 0.0 0.4 92296 7808 ? Ss 04:44 0:00 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@open [root@localhost ansible]# ansible all -m raw -a 'cat /abc/test |grep bbb ' 192.168.100.42 | CHANGED | rc=0 >> bbb Shared connection to 192.168.100.42 closed.
user module
The user module is used to manage the user accounts of the managed host
[root@localhost ansible]# ansible all -m user -a 'name=tom uid=10101 system=yes create_home=no shell=/sbin/nologin' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "comment": "", "create_home": false, "group": 132, "home": "/home/tom", "name": "tom", "shell": "/sbin/nologin", "state": "present", "system": true, "uid": 10101 } [root@localhost ansible]# ansible all -m shell -a 'ls /home' 192.168.100.42 | CHANGED | rc=0 >> abc qqq tom top [root@localhost ansible]# ansible all -m user -a 'name=tom uid=10101 system=yes create_home=no shell=/sbin/nologin' 192.168.100.42 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "append": false, "changed": false, "comment": "", "group": 10003, "home": "/home/tom", "move_home": false, "name": "tom", "shell": "/sbin/nologin", "state": "present", "uid": 10101 } [root@localhost ansible]# [root@localhost ansible]# ansible all -m shell -a 'grep tom /etc/passwd' 192.168.100.42 | CHANGED | rc=0 >> tom:x:10101:10003::/home/tom:/sbin/nologin [root@localhost ansible]# ansible all -m user -a 'name=tom state=absent' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "force": false, "name": "tom", "remove": false, "state": "absent" } [root@localhost ansible]# ansible all -m shell -a 'grep tom /etc/passwd' 192.168.100.42 | FAILED | rc=1 >> non-zero return code [root@localhost ansible]#
group module
The group module is used to add or remove groups on managed hosts
[root@localhost ansible]# ansible all -m group -a 'name=abc gid=300' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "gid": 300, "name": "abc", "state": "present", "system": false } [root@localhost ansible]# ansible all -m shell -a 'grep abc /etc/group' 192.168.100.42 | CHANGED | rc=0 >> abc:x:300: [root@localhost ansible]# //Delete groups on managed hosts [root@localhost ansible]# ansible all -m group -a 'name=test state=absent' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "name": "abc", "state": "absent" } [root@localhost ansible]# ansible all -m shell -a 'grep test /etc/group' 192.168.100.42 | FAILED | rc=1 >> non-zero return code
service module
The service module is used to manage services on managed hosts
[root@localhost ansible]# ansible all -m shell -a 'systemctl is-active mariadb' 192.168.100.42 | FAILED | rc=3 >> inactivenon-zero return code [root@localhost ansible]# ansible all -m service -a 'name=mariadb state=started' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "name": "mariadb", "state": "started", "status": { [root@localhost ansible]# ansible all -m shell -a 'systemctl is-active mariadb' 192.168.100.42| CHANGED | rc=0 >> activ [root@localhost ansible]# ansible all -m shell -a 'systemctl is-enabled mariadb' 192.168.100.42 | FAILED | rc=1 >> disablednon-zero return code [root@localhost ansible]# ansible all -m service -a 'name=mariadb enabled=yes' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "enabled": true, "name": "mariadb", "status": { [root@localhost ansible]# ansible all -m shell -a 'systemctl is-enabled mariadb' 192.168.100.42 | CHANGED | rc=0 >> enabled root@localhost ansible]# ansible all -m service -a 'name=mariadb state=stopped' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "name": "mariadb", "state": "stopped", "status": { [root@localhost ansible]# ansible all -m shell -a 'systemctl is-active mariadb' 192.168.100.42 | FAILED | rc=3 >> inactivenon-zero return code [root@localhost ansible]# ansible all -m shell -a 'ss -antl' 192.168.100.42 | CHANGED | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:*
copy module
The copy module is used to copy files to a remote managed host
Ansible 172.16.103.129 - M copy - a 'SRC (source address) = path DeST (destination) = path'
Use the force parameter to control whether to force overrides
ansible managed host - m copy -a 'src = source path dest = destination path force=yes/no
From = No. if the target file already exists, the operation will not be performed; If the target file does not exist, it will be copied
From = yes if the target file already exists, it will be forcibly overwritten
Use the backup parameter to control whether files are backed up
ansible managed machine name - m copy -a 'src = original path dest = copy past path backup=yes owner= group= mode ='
backup=yes means that if the copied file content is different from the original content, a copy will be backed up
[root@localhost ansible]# ansible all -m command -a 'ls /root' 192.168.100.42 | CHANGED | rc=0 >> anaconda-ks.cfg initial-setup-ks.cfg [root@localhost ansible]# [root@localhost ansible]# ansible all -m copy -a 'src=/tmp/project dest=/root' 192.168.100.42 | CHANGED => { "changed": true, "dest": "/root/", "src": "/root/project" } [root@localhost ansible]# ansible all -m command -a 'ls /root' 192.168.100.42 | CHANGED | rc=0 >> anaconda-ks.cfg initial-setup-ks.cfg project
fetch module
The fetch module is similar to the copy module, but has the opposite effect. It is used to copy files from a remote machine to the local. Copying directories is not supported.
ansible managed machine name - m fetch -a 'src = original path dest = destination path‘
root@localhost ansible]# ansible all -m fetch -a 'src=/root/test1 dest=/root' 192.168.100.42 | CHANGED => { "changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/root/192.168.220.8/root/test1", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "remote_checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "remote_md5sum": null } [root@localhost ~]# ll drwxr-xr-x. 3 root root 18 7 April 15:46 192.168.100.42 [root@localhost ~]# ls 192.168.100.42/root/ test1
file module
The file module is mainly used for file operations on remote hosts. The file module contains the following options:
-
Force: you need to force the creation of soft links in two cases: one is when the source file does not exist but will be established later; The other is that the target soft link already exists. You need to cancel the previous soft link first, and then create a new soft link. There are two options: yes|no
-
Group: defines the group to which the file / directory belongs
-
mode: defines the permissions of the file / directory
-
Owner: defines the owner of the file / directory
-
Path: required; defines the path of the file / directory
-
recurse: recursively sets the attributes of the file. It is only valid for directories
-
src: the path of the source file to be linked. This only applies when state=link
-
dest: the path to which the link is linked. It only applies when state=link
-
state:
Directory: create a directory if it does not exist
File: even if the file does not exist, it will not be created
Link: create a soft link
Hard: create a hard link
touch: if the file does not exist, a new file will be created. If the file or directory already exists, its last modification time will be updated
absent: delete directories, files, or unlink files
[root@localhost ansible]# ansible all -m shell -a 'ls -l /root/' 192.168.220.8 | CHANGED | rc=0 >> total 4 -rw-------. 1 root root 1023 Jul 13 12:06 anaconda-ks.cfg -rw-r--r--. 1 root root 1445 7 June 13-16:23 initial-setup-ks.cfg drwxr-xr-x. 3 root root 17 Jul 17 07:22 project [root@localhost ansible]# ansible all -m file -a 'path=/root/project owner=harry group=harry mode=0644' 192.168.100.42| CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "gid": 1000, "group": "harry", "mode": "0644",f "owner": "harry", "path": "/root/project", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 17, "state": "directory", "uid": 1005 } [root@localhost ansible]# ansible all -m command -a 'ls -l /root/' 192.168.ansible all -m shell -a 'ls -l /root/' | CHANGED | rc=0 >> total 8 -rw-------. 1 root root 1023 Jul 13 12:06 anaconda-ks.cfg drw-r--r--. 3 harry harry 17 Jul 17 07:22 project [root@localhost ansible]# ansible all -m file -a 'path=/root/school state=touch owner=root group=harry mode=0644' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "dest": "/root/school", "gid": 1000, "group": "harry", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 0, "state": "file", "uid": 0 } [root@localhost ansible]# ansible all -m shell -a 'ls -l /root' 192.168.100.42 | CHANGED | rc=0 >> total 1 drwxrwxrwx. 3 root root 15 Jul 17 18:57 qq [root@localhost ansible]# ansible all -m file -a 'path=/root/qq mode=0644' 192.168.220.8 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/root/qq", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 15, "state": "directory", "uid": 0 } [root@localhost ansible]# ansible all -m shell -a 'ls -l /root' 192.168.100.42 | CHANGED | rc=0 >> total 1 drw-r--r--. 3 root root 15 Jul 17 18:57 qq [root@localhost ansible]# ansible all -m file -a 'path=/root/cd/d state=directory recurse=yes owner=harry' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "gid": 1000, "group": "root", "mode": "0755", "owner": "harry", "path": "/root/cd/d", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 6, "state": "directory", "uid": 1000 } [root@localhost ansible]# ansible all -m shell -a 'ls -l /root/cd/' 192.168.100.42 | CHANGED | rc=0 >> total 0 drwxr-xr-x. 2 harry root 6 Jul 17 19:03 d [root@localhost ansible]# ansible all -m file -a 'src=/root/school dest=/tmp/ss state=link' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "dest": "/tmp/ss", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "secontext": "unconfined_u:object_r:user_tmp_t:s0", "size": 12, "src": "/root/school", "state": "link", "uid": 0 } [root@localhost ansible]# ansible all -m shell -a 'ls -l /tmp' 192.168.100.42 | CHANGED | rc=0 >> total 4 drwx------. 2 root root 41 Jul 17 22:26 ansible_command_payload_i4oj3u65 drwxr-xr-x. 2 root root 19 Jul 17 03:40 hsperfdata_root -rwx------. 1 root root 701 Jul 13 12:06 ks-script-a85snvsm lrwxrwxrwx. 1 root root 12 Jul 17 22:25 ss -> /root/school [root@localhost ansible]# ansible all -m file -a 'src=/root/qqq dest=/tmp/qq state=hard'192.168.100.42| CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "dest": "/tmp/qq", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 0, "src": "/root/qqq", "state": "hard", "uid": 0 }
lineinfile module
Make sure that a specific line is in the file
[root@localhost ansible]# ansible all -m shell -a 'cat /etc/selinux/config' 192.168.100.42| CHANGED | rc=0 >> # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing [root@localhost ansible]# ansible all -m lineinfile -a 'path=/etc/selinux/config regexp="SELINUX=" line="SELINUX=disabled"' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "backup": "", "changed": true, "msg": "line replaced" } [root@localhost ansible]# ansible all -m shell -a 'cat /etc/selinux/config' 192.168.100.42 | CHANGED | rc=0 >> # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled [root@localhost ansible]# ansible all -m lineinfile -a 'path=/etc/selinux/config line=SELINUX=permissive' 192.168.220.8 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "backup": "", "changed": true, "msg": "line added" } [root@localhost ansible]# ansible all -m shell -a 'cat /etc/selinux/config' 192.168.100.42 | CHANGED | rc=0 >> # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled SELINUX=permissive [root@localhost ansible]# ansible all -m lineinfile -a 'path=/etc/selinux/config state=absent line=SELINUX=permissive' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "backup": "", "changed": true, "found": 1, "msg": "1 line(s) removed" } [root@localhost ansible]# ansible all -m shell -a 'cat /etc/selinux/config'192.168.220.8 | CHANGED | rc=0 >> # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled [root@localhost ansible]# ansible all -m shell -a 'ls -l /root' 192.168.220.8 | CHANGED | rc=0 >> total 1 -rw-r--r--. 1 root root 5 Jul 18 02:01 test [root@localhost ansible]# ansible all -m lineinfile -a 'path=/root/test owner=harry group=zzz line=jjyy state=present' 192.168.220.8 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "backup": "", "changed": true, "msg": "ownership, perms or SE linux context changed" } [root@localhost ansible]# ansible all -m shell -a 'ls -l /root' 192.168.220.8 | CHANGED | rc=0 >> total 1 -rw-r--r--. 1 harry zzz 5 Jul 18 02:01 test [root@localhost ansible]# ansible all -m shell -a 'cat /etc/selinux/config' 192.168.220.8 | CHANGED | rc=0 >> # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled [root@localhost ansible]# ansible all -m lineinfile -a 'path=/etc/selinux/config insertafter="SELINUX=disabled" line="SELINUX=permissive"' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "backup": "", "changed": true, "msg": "line added" } [root@localhost ansible]# ansible all -m shell -a 'cat /etc/selinux/config' 192.168.100.42 | CHANGED | rc=0 >> # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled SELINUX=permissive
yum module
The yum module is used to use the yum management software on the specified node machine. It supports two main parameters
- Name: package name to manage
- state: operation to be performed
Common state values:
- latest: install software
- installed: install the software
- present: install software
- removed: uninstall the software
- absent: uninstall software
If you want to use Yum to manage the software, please ensure that the yum source on the controlled machine is normal
[root@localhost ansible]# ansible all -m shell -a 'rpm -qa |grep vsftpd' [WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 192.168.100.42 | FAILED | rc=1 >> non-zero return code [root@localhost ansible]# ansible all -m yum -a 'name=vsftpd state=present' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "msg": "", "rc": 0, "results": [ "Installed: vsftpd-3.0.3-34.el8.x86_64" ] } [root@localhost ansible]# ansible all -m shell -a 'rpm -qa |grep vsftpd' [WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. 192.168.100.42 | CHANGED | rc=0 >> vsftpd-3.0.3-34.el8.x86_64
script module
The script module is used to execute scripts on the master on the managed host
ansible managed host-m Module-a 'script path'
[root@localhost ansible]# ls -l /root/ Total consumption 1 -rwxr-xr-x. 1 root root 23 7 July 17-21:43 a.sh [root@localhost ansible]# cat /root/a.sh #!/bin/bash touch test [root@localhost ansible]# ansible all -m script -a '/root/a.sh' 192.168.100.42| CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.220.8 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.220.8 closed." ], "stdout": "", "stdout_lines": [] } [root@localhost ansible]# ansible all -m shell -a 'ls -l /root' 192.168.100.42 | CHANGED | rc=0 >> total 0 -rw-r--r--. 1 root root 0 Jul 17 23:51 test
template module
The template module is used to generate a template and transfer it to a remote host
[root@localhost ~]# ls ansible.cfg [root@localhost ~]# cat ansible.cfg abcd [root@localhost ansible]# ansible all -m template -a 'src=~/ansible.cfg dest=/tmp/' 192.168.100.42 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "checksum": "dce58c1e5d0ee30acff9282898b28b54b27c4e0a", "dest": "/tmp/ansible.cfg", "gid": 0, "group": "root", "md5sum": "6b6804d918ecdf41b7363b7ee7027346", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 5, "src": "/root/.ansible/tmp/ansible-tmp-1626584618.565992-357179-252666804746292/source", "state": "file", "uid": 0 } [root@localhost ansible]# ansible all -m shell -a 'cat /tmp/ansible.cfg' 192.168.100.42 | CHANGED | rc=0 >> abcd