ansible之所以功能强大,不是ansible本身,是因为它有众多的模块,前文我们介绍了ansible的基础介绍,系列命令的用法以及选项的说明,通过前文的学习我们知道了ansible是基于python语言编写,我们在执行一条ansible命令通常会指定一个模块,即便不指定它也有默认的模块,它的工作流程就是通过各种模块去完成对远程主机的管理、配置等操作。接下来我们来看看ansible的一些常用模块的使用。
1、ping模块:它的主要功能是尝试连接远端主机,并测试远端主机是否在线
常用参数说明:
data:指定返回的字符数据,默认是“pong”
我们在使用ping模块的时候,通常后边不用-a指定参数,当然我们可以指定返回的数据字符
[root@localhost ~]# ansible websers -m ping
192.168.0.218 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.0.99 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@localhost ~]# ansible websers -m ping -a "data=aaa"
192.168.0.218 | SUCCESS => {
"changed": false,
"ping": "aaa"
}
192.168.0.99 | SUCCESS => {
"changed": false,
"ping": "aaa"
}
[root@localhost ~]#
说明:以上命令是用ping模块去websers组里的所有主机是否在线,若在线返回字符“aaa”;若不指定data参数,则默认返回“pong”
2、command:此模块在帮助文档里的解释是,在远端节点主机上执行一条命令;这个模块在ansible里是一个默认的模块,即我们在使用ansible命令时不用-m指定模块时,ansible默认就是调用的此模块工作;
模块帮助:
[root@localhost ~]# ansible-doc -s command
- name: Executes a command on a remote node
command:
chdir: # Change into this directory before running the command.
creates: # A filename or (since 2.0) glob pattern, when it already exists, this
step will *not* be run.
free_form: # (required) The command module takes a free form command to run. There
is no parameter actually named 'free
form'. See the examples!
removes: # A filename or (since 2.0) glob pattern, when it does not exist, this
step will *not* be run.
stdin: # Set the stdin of the command directly to the specified value.
warn: # If command_warnings are on in ansible.cfg, do not warn about this
particular line if set to `no'.
[root@localhost ~]#
常用参数说明:
chdir:这个参数的作用是在执行命令之前切换到这个目录
[root@localhost ~]# ansible websers -m command -a 'chdir=/var/log/ pwd '
192.168.0.218 | SUCCESS | rc=0 >>
/var/log 192.168.0.99 | SUCCESS | rc=0 >>
/var/log [root@localhost ~]# ansible websers -m command -a ' pwd '
192.168.0.218 | SUCCESS | rc=0 >>
/root 192.168.0.99 | SUCCESS | rc=0 >>
/root [root@localhost ~]# ansible websers -m command -a 'chdir=/var/log/ pwd '
192.168.0.218 | SUCCESS | rc=0 >>
/var/log 192.168.0.99 | SUCCESS | rc=0 >>
/var/log [root@localhost ~]#
说明:在不指定chdir这个参数时,ansible默认执行路径是/root
creates:这个参数的作用是如果我们指定文件存在,则后续的操作将不再执行下去。
[root@localhost init.d]# ansible websers -a 'ls /etc/ansible/'
192.168.0.218 | FAILED | rc=2 >>
ls: cannot access /etc/ansible/: No such file or directorynon-zero return code 192.168.0.99 | SUCCESS | rc=0 >>
ansible.cfg
hosts
roles [root@localhost init.d]# ansible websers -a 'creates=/etc/ansible/ ip addr show '
192.168.0.218 | SUCCESS | rc=0 >>
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:e8:f6:7b brd ff:ff:ff:ff:ff:ff
inet 192.168.0.218/24 brd 192.168.0.255 scope global eth0
inet6 fe80::20c:29ff:fee8:f67b/64 scope link
valid_lft forever preferred_lft forever
3: pan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN
link/ether ba:01:d9:85:53:42 brd ff:ff:ff:ff:ff:ff 192.168.0.99 | SUCCESS | rc=0 >>
skipped, since /etc/ansible/ exists [root@localhost init.d]#
说明:以上命令的表示,如果/etc/ansible/ 这个文件不存在(当然目录也是文件,在Linux里一切皆文件),则执行后面的命令“ip addr show”,反之若/etc/ansible/这个文件存在,则跳过后续的任何操作。从上面命令返回结果可以看到,在218这台主机上是不存在/etc/ansible/这个目录的,所以后续的命令ip addr show 这条命令它会执行,当然99这台主机上有/etc/ansible/这个目录,所以它后续的ip addr show 这条命令不执行。
removes:这个参数和上面的creates这个参数的作用是相反的,它的作用是如果指定的文件不存在,则后续命令将不执行,反之,如果指定文件存在,则运行后续的命令
[root@localhost init.d]# ansible websers -a 'removes=/etc/ansible ip addr show '
192.168.0.218 | SUCCESS | rc=0 >>
skipped, since /etc/ansible does not exist 192.168.0.99 | SUCCESS | rc=0 >>
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:30:18:51:af:3c brd ff:ff:ff:ff:ff:ff
inet 192.168.0.99/24 brd 192.168.0.255 scope global noprefixroute enp2s0
valid_lft forever preferred_lft forever
inet6 fe80::33cf:fd76:e139:9e01/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: enp3s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 00:30:18:51:af:3d brd ff:ff:ff:ff:ff:ff
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:6c:6d:27:62 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever [root@localhost init.d]#
说明:在218上不存在/etc/ansible/这个目录,所以它后续命令,不执行,99上存在/etc/ansilbe/这个目录,则后续的命令会运行。看了以上的两个参数的示例,我们不难理解这来两个参数的作用就是判断指定文件是否存在,然后决定后续的动作是否运行。
以上是command模块的常用参数的使用和说明,这个模块可以执行Linux里的命令,并返回结果,但是它有个确定就是它不支持“| < > ; & $varname”等符号,也就是说一些复杂的Linux命令用command这个模块有点不合适,如果要实现支持这些符号,我们可以使用shell模块实现。下面来看看shell模块
3、shell:此模块和command相似,都是执行Linux里的一些命令的模块,此模块支持上面说的“| < > ; & $varname”这些符号。我们先来看看帮助文档里的说明吧
[root@localhost ~]# ansible-doc -s shell
- name: Execute commands in nodes.
shell:
chdir: # cd into this directory before running the command
creates: # a filename, when it already exists, this step will *not* be run.
executable: # change the shell used to execute the command. Should be an absolute
path to the executable.
free_form: # (required) The shell module takes a free form command to run, as a
string. There's not an actual option
named "free form". See the examples!
removes: # a filename, when it does not exist, this step will *not* be run.
stdin: # Set the stdin of the command directly to the specified value.
warn: # if command warnings are on in ansible.cfg, do not warn about this
particular line if set to no/false.
[root@localhost ~]#
说明:此模块的帮助说明和command模块的帮助说明书一样的,参数用法都是一样的,这里我们不再阐述其作用。
[root@localhost ~]# ansible websers -m shell -a 'cat /etc/passwd|wc -l'
192.168.0.218 | SUCCESS | rc=0 >>
36 192.168.0.99 | SUCCESS | rc=0 >>
36 [root@localhost ~]# ansible websers -m shell -a 'echo $HOSTNAME'
192.168.0.218 | SUCCESS | rc=0 >>
localhost.localdomain 192.168.0.99 | SUCCESS | rc=0 >>
docker [root@localhost ~]# ansible websers -m shell -a 'chdir=/var/log/ ls -l '
192.168.0.218 | SUCCESS | rc=0 >>
total 2740
-rw-------. 1 root root 2368 Nov 3 15:15 anaconda.ifcfg.log
-rw-------. 1 root root 21845 Nov 3 15:15 anaconda.log
-rw-------. 1 root root 36953 Nov 3 15:15 anaconda.program.log
-rw-------. 1 root root 114682 Nov 3 15:15 anaconda.storage.log
-rw-------. 1 root root 149438 Nov 3 15:15 anaconda.syslog
-rw-------. 1 root root 26433 Nov 3 15:15 anaconda.xlog
-rw-------. 1 root root 121830 Nov 3 15:15 anaconda.yum.log
drwxr-x---. 2 root root 4096 Nov 3 15:18 audit
-rw-r--r--. 1 root root 2682 Nov 11 13:02 boot.log
-rw-------. 1 root utmp 2304 Nov 8 23:37 btmp
drwxr-xr-x. 2 root root 4096 Nov 3 15:18 ConsoleKit
-rw-------. 1 root root 8097 Nov 11 13:50 cron
-rw-------. 1 root root 17451 Nov 10 15:13 cron-20191110
drwxr-xr-x. 2 lp sys 4096 Mar 22 2017 cups
-rw-r--r--. 1 root root 90191 Nov 11 13:01 dmesg
-rw-r--r--. 1 root root 90033 Nov 10 21:24 dmesg.old
-rw-r--r--. 1 root root 208625 Nov 3 15:14 dracut.log
drwxrwx--T. 2 root gdm 4096 Nov 11 13:02 gdm
drwx------. 2 root root 4096 Nov 3 21:13 httpd
-rw-r--r--. 1 root root 146584 Nov 11 13:54 lastlog
-rw-------. 1 root root 1274 Nov 11 13:02 maillog
-rw-------. 1 root root 2360 Nov 10 14:27 maillog-20191110
-rw-------. 1 root root 496810 Nov 11 13:54 messages
-rw-------. 1 root root 980290 Nov 10 14:55 messages-20191110
drwxr-xr-x. 2 ntp ntp 4096 Feb 6 2017 ntpstats
-rw-r--r--. 1 root root 89 Nov 11 13:02 pm-powersave.log
drwx------. 2 root root 4096 Mar 16 2015 ppp
drwxr-xr-x. 2 root root 4096 Nov 3 19:21 prelink
drwxr-xr-x. 2 root root 4096 Nov 11 00:00 sa
drwx------. 3 root root 4096 Nov 3 15:10 samba
-rw-------. 1 root root 17433 Nov 11 13:54 secure
-rw-------. 1 root root 48374 Nov 10 14:44 secure-20191110
-rw-------. 1 root root 0 Nov 3 15:19 spice-vdagent.log
-rw-------. 1 root root 0 Nov 10 15:13 spooler
-rw-------. 1 root root 0 Nov 3 15:10 spooler-20191110
drwxr-x---. 2 root root 4096 Mar 23 2017 sssd
-rw-------. 1 root root 0 Nov 3 15:08 tallylog
-rw-r--r--. 1 root root 0 Nov 3 15:19 wpa_supplicant.log
-rw-rw-r--. 1 root utmp 122880 Nov 11 13:54 wtmp
-rw-r--r--. 1 root root 36528 Nov 11 13:03 Xorg.0.log
-rw-r--r--. 1 root root 36528 Nov 10 21:25 Xorg.0.log.old
-rw-r--r--. 1 root root 22238 Nov 3 15:20 Xorg.9.log
-rw-------. 1 root root 2103 Nov 10 14:55 yum.log 192.168.0.99 | SUCCESS | rc=0 >>
total 1556
drwxr-xr-x. 2 root root 204 Jun 22 07:35 anaconda
drwx------. 2 root root 23 Oct 31 2018 audit
-rw-------. 1 root root 8730 Oct 31 21:03 boot.log
-rw------- 1 root root 17574 Sep 25 18:12 boot.log-20190925
-rw------- 1 root root 8982 Sep 26 03:39 boot.log-20190926
-rw------- 1 root root 8859 Oct 5 20:45 boot.log-20191005
-rw------- 1 root root 9012 Oct 6 20:09 boot.log-20191006
-rw------- 1 root root 9091 Oct 7 19:47 boot.log-20191007
-rw------- 1 root root 8767 Oct 13 12:24 boot.log-20191013
-rw------- 1 root root 8664 Oct 23 20:27 boot.log-20191023
-rw------- 1 root utmp 4608 Nov 10 21:40 btmp
-rw------- 1 root utmp 1152 Oct 28 02:23 btmp-21081212
drwxr-xr-x. 2 chrony chrony 6 Apr 13 2018 chrony
-rw------- 1 root root 82245 Nov 11 13:01 cron
-rw------- 1 root root 2778 Oct 13 12:24 cron-20191013
-rw------- 1 root root 2541 Oct 23 20:27 cron-20191023
-rw------- 1 root root 22808 Oct 27 03:49 cron-20191027
-rw------- 1 root root 18678 Nov 5 1972 cron-21081212
-rw-r--r-- 1 root root 70752 Oct 31 21:03 dmesg
-rw-r--r-- 1 root root 71716 Oct 23 19:23 dmesg.old
-rw-r--r--. 1 root root 2456 Jun 22 09:50 firewalld
-rw------- 1 root root 2588 Aug 4 20:34 grubby
-rw-r--r--. 1 root root 498 Jun 22 11:03 grubby_prune_debug
-rw-r--r--. 1 root root 294628 Nov 11 13:54 lastlog
drwxr-xr-x 2 lightdm lightdm 25 Nov 3 14:47 lightdm
-rw------- 1 root root 7794 Nov 11 03:13 maillog
-rw------- 1 root root 384 Oct 13 11:29 maillog-20191013
-rw------- 1 root root 192 Oct 23 19:24 maillog-20191023
-rw------- 1 root root 566 Oct 24 13:51 maillog-20191027
-rw------- 1 root root 568 Oct 29 21:52 maillog-21081212
-rw------- 1 root root 271736 Nov 11 13:54 messages
-rw------- 1 root root 207268 Oct 13 12:24 messages-20191013
-rw------- 1 root root 100944 Oct 23 20:27 messages-20191023
-rw------- 1 root root 17888 Oct 27 03:49 messages-20191027
-rw------- 1 root root 17987 Nov 5 1972 messages-21081212
drwx------ 2 nginx nginx 189 Aug 26 03:36 nginx
drwxr-xr-x 3 root root 18 Nov 3 14:31 pluto
drwx------ 2 root root 6 Jun 10 2014 ppp
drwxr-xr-x. 2 root root 6 Jun 22 07:35 rhsm
drwx------ 3 root root 17 Nov 3 14:26 samba
-rw------- 1 root root 43005 Nov 11 13:52 secure
-rw------- 1 root root 1096 Oct 13 11:29 secure-20191013
-rw------- 1 root root 514 Oct 23 19:24 secure-20191023
-rw------- 1 root root 6265 Oct 25 00:01 secure-20191027
-rw------- 1 root root 9615 Nov 5 1972 secure-21081212
-rw------- 1 root root 0 Nov 5 1972 spooler
-rw------- 1 root root 0 Oct 6 20:09 spooler-20191013
-rw------- 1 root root 0 Oct 13 12:24 spooler-20191023
-rw------- 1 root root 0 Oct 23 20:27 spooler-20191027
-rw------- 1 root root 0 Oct 27 03:49 spooler-21081212
-rw-------. 1 root root 0 Jun 22 07:20 tallylog
drwxrwxrwx 2 root root 60 Jul 28 20:04 taos
drwxr-xr-x. 2 root root 23 Jul 30 01:38 tuned
-rw-rw-r--. 1 root utmp 271104 Nov 11 13:54 wtmp
-rw------- 1 root root 54348 Nov 10 00:27 yum.log
-rw-------. 1 root root 23594 Sep 18 22:24 yum.log-21081212 [root@localhost ~]# ansible websers -m shell -a 'creates=/etc/ansible/ echo $HOSTNAME'
192.168.0.218 | SUCCESS | rc=0 >>
localhost.localdomain 192.168.0.99 | SUCCESS | rc=0 >>
skipped, since /etc/ansible/ exists [root@localhost ~]# ansible websers -m shell -a 'removes=/etc/ansible/ echo $HOSTNAME'
192.168.0.218 | SUCCESS | rc=0 >>
skipped, since /etc/ansible/ does not exist 192.168.0.99 | SUCCESS | rc=0 >>
docker [root@localhost ~]#
说明:以上是shell模块的参数演示用法,它的参数作用同commnd参数作用一致,这里不过多阐述,它俩的区别在于一个支持管道,shell变量 等符号,一个不支持。
4、script:此模块的主要作用是在远程节点上运行一个本地脚本
模块帮助:
[root@localhost ~]# ansible-doc -s script
- name: Runs a local script on a remote node after transferring it
script:
chdir: # cd into this directory on the remote node before running the script
creates: # a filename, when it already exists, this step will *not* be run.
decrypt: # This option controls the autodecryption of source files using vault.
free_form: # (required) Path to the local script file followed by optional
arguments. There is no parameter
actually named 'free form'; see the
examples!
removes: # a filename, when it does not exist, this step will *not* be run.
[root@localhost ~]#
说明:可以看到script模块也有chdir、creates、removes这些参数,看来这些参数很常用,这些参数的作用在上面的模块中有说明和示例,这里不做演示,我们来看看我们上面没有的参数decrypt
常用参数说明:
decrypt:此选项使用vault控制源文件的自动解密
[root@localhost scripts]# pwd
/root/scripts
[root@localhost scripts]# cat test.sh
$ANSIBLE_VAULT;1.1;AES256
30613535646235303532393038373431336365323463396334623062653563393964626533646561
3663666531616534636530336463633431363034613734330a336632343031383131646663316633
31653765656663613762356430323035376636666338363034386134303265336235353664356665
3731393363346632650a373434656438623361663734346133396537653239386636366161616438
38653962646336323031616635386430643339636666363761393536316234383630
[root@localhost scripts]# ansible websers -m script --ask-vault-pass -a '/root/scripts/test.sh decrypt=yes'
Vault password:
192.168.0.218 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.0.218 closed.\r\n",
"stdout": "localhost.localdomain\r\n",
"stdout_lines": [
"localhost.localdomain"
]
}
192.168.0.99 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.0.99 closed.\r\n",
"stdout": "docker\r\n",
"stdout_lines": [
"docker"
]
}
[root@localhost scripts]#
说明:这个参数默认是允许vault控制原文件解密,这里要说一下,如果我们要使用ansible-vault 加密过的文件,那么我需要加上参数 --ask-vault-pass ,有了这个参数我们才可以输入密码,才可以使用加密后的文件。
5、copy:此模块的主要功能是将本地文件复制到远端节点上
模块帮助:
[root@localhost ~]# ansible-doc -s copy
- name: Copies files to remote locations
copy:
attributes: # Attributes the file or directory should have. To get supported flags
look at the man page for `chattr' on
the target system. This string should
contain the attributes in the same
order as the one displayed by `lsattr'.
backup: # Create a backup file including the timestamp information so you can
get the original file back if you
somehow clobbered it incorrectly.
content: # When used instead of `src', sets the contents of a file directly to
the specified value. For anything
advanced or with formatting also look
at the template module.
decrypt: # This option controls the autodecryption of source files using vault.
dest: # (required) Remote absolute path where the file should be copied to. If
`src' is a directory, this must be a
directory too. If `dest' is a
nonexistent path and if either `dest'
ends with "/" or `src' is a directory,
`dest' is created. If `src' and `dest'
are files, the parent directory of
`dest' isn't created: the task fails if
it doesn't already exist.
directory_mode: # When doing a recursive copy set the mode for the directories. If this
is not set we will use the system
defaults. The mode is only set on
directories which are newly created,
and will not affect those that already
existed.
follow: # This flag indicates that filesystem links in the destination, if they
exist, should be followed.
force: # the default is `yes', which will replace the remote file when contents
are different than the source. If `no',
the file will only be transferred if
the destination does not exist.
group: # Name of the group that should own the file/directory, as would be fed
to `chown'.
local_follow: # This flag indicates that filesystem links in the source tree, if they
exist, should be followed.
mode: # Mode the file or directory should be. For those used to
`/usr/bin/chmod' remember that modes
are actually octal numbers (like 0644).
Leaving off the leading zero will
likely have unexpected results. As of
version 1.8, the mode may be specified
as a symbolic mode (for example,
`u+rwx' or `u=rw,g=r,o=r').
owner: # Name of the user that should own the file/directory, as would be fed
to `chown'.
remote_src: # If `no', it will search for `src' at originating/master machine. If
`yes' it will go to the remote/target
machine for the `src'. Default is `no'.
Currently `remote_src' does not support
recursive copying.
selevel: # Level part of the SELinux file context. This is the MLS/MCS attribute,
sometimes known as the `range'.
`_default' feature works as for
`seuser'.
serole: # Role part of SELinux file context, `_default' feature works as for
`seuser'.
setype: # Type part of SELinux file context, `_default' feature works as for
`seuser'.
seuser: # User part of SELinux file context. Will default to system policy, if
applicable. If set to `_default', it
will use the `user' portion of the
policy if available.
src: # Local path to a file to copy to the remote server; can be absolute or
relative. If path is a directory, it is
copied recursively. In this case, if
path ends with "/", only inside
contents of that directory are copied
to destination. Otherwise, if it does
not end with "/", the directory itself
with all contents is copied. This
behavior is similar to Rsync.
unsafe_writes: # Normally this module uses atomic operations to prevent data corruption
or inconsistent reads from the target
files, sometimes systems are configured
or just broken in ways that prevent
this. One example are docker mounted
files, they cannot be updated
atomically and can only be done in an
unsafe manner. This boolean option
allows ansible to fall back to unsafe
methods of updating files for those
cases in which you do not have any
other choice. Be aware that this is
subject to race conditions and can lead
to data corruption.
validate: # The validation command to run before copying into place. The path to
the file to validate is passed in via
'%s' which must be present as in the
example below. The command is passed
securely so shell features like
expansion and pipes won't work.
常用参数说明:
src:指定本地文件
dest:指定目标存放位置
attributes:设置特殊属性,参考chattr用法设置。
[root@localhost scripts]# ansible websers -m shell -a ' ls -l /root/'
192.168.0.218 | SUCCESS | rc=0 >>
total 4
-rw-r--r--. 1 root root 1329 Nov 10 15:03 centos7.cfg 192.168.0.99 | SUCCESS | rc=0 >>
total 0
drwxr-xr-x 2 root root 24 Aug 31 18:04 ansible
drwxr-xr-x 7 root root 95 Jul 11 11:21 docker-training
drwxr-xr-x 2 root root 42 Oct 24 21:51 scripts [root@localhost scripts]# ansible websers -m copy -a 'src=/root/scripts/test.sh dest=/root/abc.sh attributes=i'
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: Exception: Error while setting attributes: /usr/bin/chattr: Clearing extent flag not supported on /root/abc.sh
192.168.0.218 | FAILED! => {
"changed": false,
"checksum": "6881df2feb7905f64e082504920ddd5680a57004",
"details": "Error while setting attributes: /usr/bin/chattr: Clearing extent flag not supported on /root/abc.sh\n",
"gid": 0,
"group": "root",
"mode": "0644",
"msg": "chattr failed",
"owner": "root",
"path": "/root/abc.sh",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 22,
"state": "file",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"checksum": "6881df2feb7905f64e082504920ddd5680a57004",
"dest": "/root/abc.sh",
"gid": 0,
"group": "root",
"md5sum": "dff93f19a0413f60ffbd120633b4ee34",
"mode": "0644",
"owner": "root",
"size": 22,
"src": "/root/.ansible/tmp/ansible-tmp-1573468211.79-187329712764679/source",
"state": "file",
"uid": 0
}
[root@localhost scripts]# ansible websers -m shell -a ' lsattr /root/abc.sh'
192.168.0.218 | SUCCESS | rc=0 >>
-------------e- /root/abc.sh 192.168.0.99 | SUCCESS | rc=0 >>
----i----------- /root/abc.sh [root@localhost scripts]#
说明:attributes这个参数就是给复制过去的文件设置特殊属性。上面有一个主机失败了,从报错上看它说不支持,应该是不支持在上面设置属性吧
backup:如果远端节点文件存在是否创建备份文件(带时间戳的备份文件),默认是不创建备份文件
content:这个参数的作用就是把指定的内容重定向到目标文件(会清空原有内容),若目标文件不存在则创建,并把指定内容写进目标文件里
[root@localhost ~]# ansible websers -m shell -a 'ls -l /root/'
192.168.0.218 | SUCCESS | rc=0 >>
total 8
-rw-r--r--. 1 root root 22 Nov 11 18:30 abc.sh
-rw-r--r--. 1 root root 1329 Nov 10 15:03 centos7.cfg 192.168.0.99 | SUCCESS | rc=0 >>
total 4
-rw-r--r-- 1 root root 22 Nov 11 18:30 abc.sh
drwxr-xr-x 2 root root 24 Aug 31 18:04 ansible
drwxr-xr-x 7 root root 95 Jul 11 11:21 docker-training
drwxr-xr-x 2 root root 42 Oct 24 21:51 scripts [root@localhost ~]# ansible websers -m copy -a 'content="this is test code" dest=/root/xxx.sh'
192.168.0.218 | SUCCESS => {
"changed": true,
"checksum": "2d350be9905412a6aa4b4eef6a0cce1a530211fc",
"dest": "/root/xxx.sh",
"gid": 0,
"group": "root",
"md5sum": "96a3052d9482b4052476f936a8812197",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 17,
"src": "/root/.ansible/tmp/ansible-tmp-1573469143.3-271560421830999/source",
"state": "file",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"checksum": "2d350be9905412a6aa4b4eef6a0cce1a530211fc",
"dest": "/root/xxx.sh",
"gid": 0,
"group": "root",
"md5sum": "96a3052d9482b4052476f936a8812197",
"mode": "0644",
"owner": "root",
"size": 17,
"src": "/root/.ansible/tmp/ansible-tmp-1573469143.3-219990726355602/source",
"state": "file",
"uid": 0
}
[root@localhost ~]# ansible websers -m shell -a 'ls -l /root/'
192.168.0.218 | SUCCESS | rc=0 >>
total 12
-rw-r--r--. 1 root root 22 Nov 11 18:30 abc.sh
-rw-r--r--. 1 root root 1329 Nov 10 15:03 centos7.cfg
-rw-r--r--. 1 root root 17 Nov 11 18:45 xxx.sh 192.168.0.99 | SUCCESS | rc=0 >>
total 8
-rw-r--r-- 1 root root 22 Nov 11 18:30 abc.sh
drwxr-xr-x 2 root root 24 Aug 31 18:04 ansible
drwxr-xr-x 7 root root 95 Jul 11 11:21 docker-training
drwxr-xr-x 2 root root 42 Oct 24 21:51 scripts
-rw-r--r-- 1 root root 17 Nov 11 18:45 xxx.sh [root@localhost ~]# ansible websers -m shell -a 'cat /root/xxx.sh'
192.168.0.218 | SUCCESS | rc=0 >>
this is test code 192.168.0.99 | SUCCESS | rc=0 >>
this is test code [root@localhost ~]# ansible websers -m copy -a 'content="aaaaaabbbbcccc" dest=/root/xxx.sh'
192.168.0.218 | SUCCESS => {
"changed": true,
"checksum": "f9621459afd78104431857113fcb51a0de7fe4f6",
"dest": "/root/xxx.sh",
"gid": 0,
"group": "root",
"md5sum": "91fae9d1b9e046c172c0dc32e9e49927",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 14,
"src": "/root/.ansible/tmp/ansible-tmp-1573469184.92-91500106972487/source",
"state": "file",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"checksum": "f9621459afd78104431857113fcb51a0de7fe4f6",
"dest": "/root/xxx.sh",
"gid": 0,
"group": "root",
"md5sum": "91fae9d1b9e046c172c0dc32e9e49927",
"mode": "0644",
"owner": "root",
"size": 14,
"src": "/root/.ansible/tmp/ansible-tmp-1573469184.91-254315055600695/source",
"state": "file",
"uid": 0
}
[root@localhost ~]# ansible websers -m shell -a 'cat /root/xxx.sh'
192.168.0.218 | SUCCESS | rc=0 >>
aaaaaabbbbcccc 192.168.0.99 | SUCCESS | rc=0 >>
aaaaaabbbbcccc [root@localhost ~]#
说明:用content参数和src ,它俩不能并存。
force:当本地文件和远程节点文件内容不同时,是否强制替换远程节点上的文件,默认是yes
root@localhost ~]# echo "abcd" > xxx
[root@localhost ~]# cat xxx
abcd
[root@localhost ~]#
[root@localhost ~]# ansible websers -m copy -a 'src=/root/xxx dest=/root/ '
192.168.0.218 | SUCCESS => {
"changed": true,
"checksum": "3330b4373640f9e4604991e73c7e86bfd8da2dc3",
"dest": "/root/xxx",
"gid": 0,
"group": "root",
"md5sum": "f5ac8127b3b6b85cdc13f237c6005d80",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1573469866.04-139537054145957/source",
"state": "file",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"checksum": "3330b4373640f9e4604991e73c7e86bfd8da2dc3",
"dest": "/root/xxx",
"gid": 0,
"group": "root",
"md5sum": "f5ac8127b3b6b85cdc13f237c6005d80",
"mode": "0644",
"owner": "root",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1573469866.03-263193889732743/source",
"state": "file",
"uid": 0
}
[root@localhost ~]# ansible websers -m shell -a 'cat /root/xxx'
192.168.0.218 | SUCCESS | rc=0 >>
abcd 192.168.0.99 | SUCCESS | rc=0 >>
abcd [root@localhost ~]# echo "ffff" >> xxx
[root@localhost ~]# cat xxx
abcd
ffff
[root@localhost ~]# ansible websers -m copy -a 'src=/root/xxx dest=/root/ force=no'
192.168.0.218 | SUCCESS => {
"changed": false,
"dest": "/root/",
"src": "/root/xxx"
}
192.168.0.99 | SUCCESS => {
"changed": false,
"dest": "/root/",
"src": "/root/xxx"
}
[root@localhost ~]# ansible websers -m shell -a 'cat /root/xxx'
192.168.0.218 | SUCCESS | rc=0 >>
abcd 192.168.0.99 | SUCCESS | rc=0 >>
abcd [root@localhost ~]# ansible websers -m copy -a 'src=/root/xxx dest=/root/ force=yes'
192.168.0.218 | SUCCESS => {
"changed": true,
"checksum": "49cd3629c9a54aa81f1d45d99d2de3e80f12a149",
"dest": "/root/xxx",
"gid": 0,
"group": "root",
"md5sum": "4ec7669871a98be915dfc335eda01418",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 10,
"src": "/root/.ansible/tmp/ansible-tmp-1573469933.25-83137410532362/source",
"state": "file",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"checksum": "49cd3629c9a54aa81f1d45d99d2de3e80f12a149",
"dest": "/root/xxx",
"gid": 0,
"group": "root",
"md5sum": "4ec7669871a98be915dfc335eda01418",
"mode": "0644",
"owner": "root",
"size": 10,
"src": "/root/.ansible/tmp/ansible-tmp-1573469933.24-211729757258043/source",
"state": "file",
"uid": 0
}
[root@localhost ~]# ansible websers -m shell -a 'cat /root/xxx'
192.168.0.218 | SUCCESS | rc=0 >>
abcd
ffff 192.168.0.99 | SUCCESS | rc=0 >>
abcd
ffff [root@localhost ~]#
group:设置文件或目录的所属组
mode:设置文件或目录权限(权限支持数字表示法如0644,也支持u+rw,g-wx,o-rwx,也支持u=rw,g=r,o=r)
owner:设置文件或目录的属主和属组(若有group指定属组,则以group为准,若没有group指定则同属主同名的组)
[root@localhost ~]# ll
total 0
drwxr-xr-x. 2 root root 41 Nov 11 00:45 ansible
drwxr-xr-x. 2 root root 37 Nov 11 18:49 scripts
[root@localhost ~]# ll scripts/
total 8
-rw-------. 1 root root 22 Nov 11 18:22 test.sh
-rw-r--r--. 1 root root 8 Nov 11 18:49 test.txt
[root@localhost ~]# ansible websers -m copy -a 'src=/root/scripts dest=/root/ owner=qiuhom mode=0777 group=root'
192.168.0.218 | SUCCESS => {
"changed": true,
"dest": "/root/",
"src": "/root/scripts"
}
192.168.0.99 | SUCCESS => {
"changed": true,
"dest": "/root/",
"src": "/root/scripts"
}
[root@localhost ~]# ansible websers -m shell -a 'ls -l /root/'
192.168.0.218 | SUCCESS | rc=0 >>
total 4
drwxr-xr-x. 2 qiuhom root 4096 Nov 11 19:18 scripts 192.168.0.99 | SUCCESS | rc=0 >>
total 0
drwxr-xr-x 2 qiuhom root 37 Nov 11 19:18 scripts [root@localhost ~]# ansible websers -m shell -a 'ls -l /root/scripts/'
192.168.0.218 | SUCCESS | rc=0 >>
total 8
-rwxrwxrwx. 1 qiuhom root 22 Nov 11 19:18 test.sh
-rwxrwxrwx. 1 qiuhom root 8 Nov 11 19:18 test.txt 192.168.0.99 | SUCCESS | rc=0 >>
total 8
-rwxrwxrwx 1 qiuhom root 22 Nov 11 19:18 test.sh
-rwxrwxrwx 1 qiuhom root 8 Nov 11 19:18 test.txt [root@localhost ~]#
说明:我们在复制整个目录的时候,若目标节点没有该目录则复制过去的目录的属主、所属组同我们设定的一样,目录权限不会更改,但目录下的所有文件会改变为我们指定的权限属组和属主;若目标节点存在该目录,则目录的的属组和所属组权限都不会发生改变,且目录原下原有的文件也不会发生变化,变化的只是我们复制过去目录下的文件。这里还要说一点就是如果目录下还有目录,那么针对目录下的目录权限一般都是755不会发生变,权限的改变只是针对文件。总结一点,在我们复制目录时,权限的指定只有文件生效,目录不生效,属组和属主的指定,若目标节点存在,则不生效,若不存在则生效。
6、fetch:此模块的作用是从远端节点获取指定文件,并将保存至本地,按主机名组织,此模块的工作同copy模块类似,但是它们是相反的
模块帮助:
[root@localhost ~]# ansible-doc -s fetch
- name: Fetches a file from remote nodes
fetch:
dest: # (required) A directory to save the file into. For example, if the `dest' directory is `/backup' a `src'
file named `/etc/profile' on host `host.example.com', would be saved into
`/backup/host.example.com/etc/profile'
fail_on_missing: # When set to 'yes', the task will fail if the remote file cannot be read for any reason. Prior to
Ansible-2.4, setting this would only fail if the source file was missing.
The default was changed to "yes" in Ansible-2.4.
flat: # Allows you to override the default behavior of appending hostname/path/to/file to the destination. If
dest ends with '/', it will use the basename of the source file, similar
to the copy module. Obviously this is only handy if the filenames are
unique.
src: # (required) The file on the remote system to fetch. This `must' be a file, not a directory. Recursive
fetching may be supported in a later release.
validate_checksum: # Verify that the source and destination checksums match after the files are fetched.
[root@localhost ~]#
常用参数说明:
dest:指定保存本地到本地的目录
src:指定远端节点上的文件,必须是文件不能是目录,它暂时不支持目录递归拉取(如果是目录可以先打包成tar文件,然后再拉取)
flat:允许您覆盖将hostname/path/to/file附加到目标的默认行为。如果dest以'/'结尾,它将使用源文件的基本名,类似于copy模块。显然,这只有在文件名是惟一的情况下才有用
[root@localhost test]# ls
[root@localhost test]#
[root@localhost test]# ansible websers -m fetch -a 'src=/etc/fstab dest=/root/test/ flat=yes'
192.168.0.218 | SUCCESS => {
"changed": true,
"checksum": "7c3fe681918844ddaf6c94799731779e75c58a86",
"dest": "/root/test/fstab",
"md5sum": "192121480e9db76108c3ed80aa10e010",
"remote_checksum": "7c3fe681918844ddaf6c94799731779e75c58a86",
"remote_md5sum": null
}
192.168.0.99 | SUCCESS => {
"changed": true,
"checksum": "68765861c07a0674ef0838168ccf2e69c93529d4",
"dest": "/root/test/fstab",
"md5sum": "f377fd21c0038a2886fd3c096d706eae",
"remote_checksum": "68765861c07a0674ef0838168ccf2e69c93529d4",
"remote_md5sum": null
}
[root@localhost test]# ls
fstab
[root@localhost test]# ll
total 4
-rw-r--r--. 1 root root 552 Nov 11 19:55 fstab
[root@localhost test]# ansible websers -m fetch -a 'src=/etc/fstab dest=/root/test/ '
192.168.0.218 | SUCCESS => {
"changed": true,
"checksum": "7c3fe681918844ddaf6c94799731779e75c58a86",
"dest": "/root/test/192.168.0.218/etc/fstab",
"md5sum": "192121480e9db76108c3ed80aa10e010",
"remote_checksum": "7c3fe681918844ddaf6c94799731779e75c58a86",
"remote_md5sum": null
}
192.168.0.99 | SUCCESS => {
"changed": true,
"checksum": "68765861c07a0674ef0838168ccf2e69c93529d4",
"dest": "/root/test/192.168.0.99/etc/fstab",
"md5sum": "f377fd21c0038a2886fd3c096d706eae",
"remote_checksum": "68765861c07a0674ef0838168ccf2e69c93529d4",
"remote_md5sum": null
}
[root@localhost test]# ls
192.168.0.218 192.168.0.99 fstab
[root@localhost test]#
[root@localhost test]# ll
total 4
drwxr-xr-x. 3 root root 17 Nov 11 19:56 192.168.0.218
drwxr-xr-x. 3 root root 17 Nov 11 19:56 192.168.0.99
-rw-r--r--. 1 root root 552 Nov 11 19:55 fstab
[root@localhost test]# tree
.
├── 192.168.0.218
│ └── etc
│ └── fstab
├── 192.168.0.99
│ └── etc
│ └── fstab
└── fstab 4 directories, 3 files
[root@localhost test]#
7、file:此模块的作用是管理目标节点文件(新建、设置权限,删除文件操作)
模块帮助:
[root@localhost ~]# ansible-doc -s file
- name: Sets attributes of files
file:
attributes: # Attributes the file or directory should have. To get supported flags look at the man page for `chattr'
on the target system. This string should contain the attributes in the
same order as the one displayed by `lsattr'.
follow: # This flag indicates that filesystem links, if they exist, should be followed.
force: # force the creation of the symlinks in two cases: the source file does not exist (but will appear later);
the destination exists and is a file (so, we need to unlink the "path"
file and create symlink to the "src" file in place of it).
group: # Name of the group that should own the file/directory, as would be fed to `chown'.
mode: # Mode the file or directory should be. For those used to `/usr/bin/chmod' remember that modes are
actually octal numbers (like 0644). Leaving off the leading zero will
likely have unexpected results. As of version 1.8, the mode may be
specified as a symbolic mode (for example, `u+rwx' or `u=rw,g=r,o=r').
owner: # Name of the user that should own the file/directory, as would be fed to `chown'.
path: # (required) path to the file being managed. Aliases: `dest', `name'
recurse: # recursively set the specified file attributes (applies only to state=directory)
selevel: # Level part of the SELinux file context. This is the MLS/MCS attribute, sometimes known as the `range'.
`_default' feature works as for `seuser'.
serole: # Role part of SELinux file context, `_default' feature works as for `seuser'.
setype: # Type part of SELinux file context, `_default' feature works as for `seuser'.
seuser: # User part of SELinux file context. Will default to system policy, if applicable. If set to `_default',
it will use the `user' portion of the policy if available.
src: # path of the file to link to (applies only to `state=link'). Will accept absolute, relative and
nonexisting paths. Relative paths are not expanded.
state: # If `directory', all immediate subdirectories will be created if they do not exist, since 1.7 they will
be created with the supplied permissions. If `file', the file will NOT be
created if it does not exist, see the [copy] or [template] module if you
want that behavior. If `link', the symbolic link will be created or
changed. Use `hard' for hardlinks. If `absent', directories will be
recursively deleted, and files or symlinks will be unlinked. Note that
`absent' will not cause `file' to fail if the `path' does not exist as
the state did not change. If `touch' (new in 1.4), an empty file will be
created if the `path' does not exist, while an existing file or directory
will receive updated file access and modification times (similar to the
way `touch` works from the command line).
unsafe_writes: # Normally this module uses atomic operations to prevent data corruption or inconsistent reads from the
target files, sometimes systems are configured or just broken in ways
that prevent this. One example are docker mounted files, they cannot be
updated atomically and can only be done in an unsafe manner. This boolean
option allows ansible to fall back to unsafe methods of updating files
for those cases in which you do not have any other choice. Be aware that
this is subject to race conditions and can lead to data corruption.
[root@localhost ~]#
常用参数说明:
attributes:设置目标节点文件的特殊属性,特殊属性参考chattr命令
group:设置目标文件的属组
mode:设置目标文件的权限(权限支持数字表示法如0644,也支持u+rw,g-wx,o-rwx,也支持u=rw,g=r,o=r)
owner:设置目标文件的属组和属主(若有group指定属组,则以group为准,若没有group指定则同属主同名的组)
path:被管理文件的路径,别名(name、dest),也就被管理的文件我们可以用name指定,也可以用dest指定
src:要链接到的文件的路径(仅适用于' state=link'或者‘state=hard’)。
state:这个选项至关重要,它表示我们怎么管理文件,其中link表示创建软连接,hard或者hardlinks表示创建硬链接,touch表示创建空文件,directory表示创建目录(前提是目标不存在此目录),absent表示删除
1)新建文件
[root@localhost test]# ansible websers -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
total 8
drwxr-xr-x. 2 qiuhom root 4096 Nov 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 Nov 11 19:28 test 192.168.0.99 | SUCCESS | rc=0 >>
total 0
drwxr-xr-x 2 qiuhom root 37 Nov 11 19:18 scripts
drwxr-xr-x 3 qiuhom root 27 Nov 11 19:28 test [root@localhost test]# ansible websers -m file -a 'path=/root/f1 state=touch'
192.168.0.218 | SUCCESS => {
"changed": true,
"dest": "/root/f1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"dest": "/root/f1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
[root@localhost test]# ansible websers -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
total 8
-rw-r--r--. 1 root root 0 Nov 11 20:48 f1
drwxr-xr-x. 2 qiuhom root 4096 Nov 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 Nov 11 19:28 test 192.168.0.99 | SUCCESS | rc=0 >>
total 0
-rw-r--r-- 1 root root 0 Nov 11 20:48 f1
drwxr-xr-x 2 qiuhom root 37 Nov 11 19:18 scripts
drwxr-xr-x 3 qiuhom root 27 Nov 11 19:28 test [root@localhost test]#
说明:新建空文件的同时可以指定权限属主等信息,同copy模块设置权限属组属主用法一样,这里不再演示
2)新建目录
[root@localhost test]# ansible websers -m file -a 'path=/root/dir1 state=directory'
192.168.0.218 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/dir1",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 4096,
"state": "directory",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/dir1",
"size": 6,
"state": "directory",
"uid": 0
}
[root@localhost test]# ansible websers -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
total 12
drwxr-xr-x. 2 root root 4096 Nov 11 20:51 dir1
-rw-r--r--. 1 root root 0 Nov 11 20:48 f1
drwxr-xr-x. 2 qiuhom root 4096 Nov 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 Nov 11 19:28 test 192.168.0.99 | SUCCESS | rc=0 >>
total 0
drwxr-xr-x 2 root root 6 Nov 11 20:51 dir1
-rw-r--r-- 1 root root 0 Nov 11 20:48 f1
drwxr-xr-x 2 qiuhom root 37 Nov 11 19:18 scripts
drwxr-xr-x 3 qiuhom root 27 Nov 11 19:28 test [root@localhost test]#
3)新建软连接
[root@localhost test]# ansible websers -m file -a 'src=/root/f1 path=/root/f1.link state=link'
192.168.0.218 | SUCCESS => {
"changed": true,
"dest": "/root/f1.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 8,
"src": "/root/f1",
"state": "link",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"dest": "/root/f1.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 8,
"src": "/root/f1",
"state": "link",
"uid": 0
}
[root@localhost test]# ansible websers -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
total 12
drwxr-xr-x. 2 root root 4096 Nov 11 20:51 dir1
-rw-r--r--. 1 root root 0 Nov 11 20:48 f1
lrwxrwxrwx. 1 root root 8 Nov 11 20:52 f1.link -> /root/f1
drwxr-xr-x. 2 qiuhom root 4096 Nov 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 Nov 11 19:28 test 192.168.0.99 | SUCCESS | rc=0 >>
total 0
drwxr-xr-x 2 root root 6 Nov 11 20:51 dir1
-rw-r--r-- 1 root root 0 Nov 11 20:48 f1
lrwxrwxrwx 1 root root 8 Nov 11 20:52 f1.link -> /root/f1
drwxr-xr-x 2 qiuhom root 37 Nov 11 19:18 scripts
drwxr-xr-x 3 qiuhom root 27 Nov 11 19:28 test [root@localhost test]#
4)新建硬链接
[root@localhost test]# ansible websers -m file -a 'src=/root/f1 path=/root/f1.hard state=hard'
192.168.0.218 | SUCCESS => {
"changed": true,
"dest": "/root/f1.hard",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 0,
"src": "/root/f1",
"state": "hard",
"uid": 0
}
192.168.0.99 | SUCCESS => {
"changed": true,
"dest": "/root/f1.hard",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/f1",
"state": "hard",
"uid": 0
}
[root@localhost test]# ansible websers -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
total 12
drwxr-xr-x. 2 root root 4096 Nov 11 20:51 dir1
-rw-r--r--. 2 root root 0 Nov 11 20:48 f1
-rw-r--r--. 2 root root 0 Nov 11 20:48 f1.hard
lrwxrwxrwx. 1 root root 8 Nov 11 20:52 f1.link -> /root/f1
drwxr-xr-x. 2 qiuhom root 4096 Nov 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 Nov 11 19:28 test 192.168.0.99 | SUCCESS | rc=0 >>
total 0
drwxr-xr-x 2 root root 6 Nov 11 20:51 dir1
-rw-r--r-- 2 root root 0 Nov 11 20:48 f1
-rw-r--r-- 2 root root 0 Nov 11 20:48 f1.hard
lrwxrwxrwx 1 root root 8 Nov 11 20:52 f1.link -> /root/f1
drwxr-xr-x 2 qiuhom root 37 Nov 11 19:18 scripts
drwxr-xr-x 3 qiuhom root 27 Nov 11 19:28 test [root@localhost test]#
5)删除
root@localhost test]# ansible websers -m file -a 'path=/root/f1.hard state=absent'
192.168.0.218 | SUCCESS => {
"changed": true,
"path": "/root/f1.hard",
"state": "absent"
}
192.168.0.99 | SUCCESS => {
"changed": true,
"path": "/root/f1.hard",
"state": "absent"
}
[root@localhost test]# ansible websers -m file -a 'path=/root/f1.link state=absent'
192.168.0.218 | SUCCESS => {
"changed": true,
"path": "/root/f1.link",
"state": "absent"
}
192.168.0.99 | SUCCESS => {
"changed": true,
"path": "/root/f1.link",
"state": "absent"
}
[root@localhost test]# ansible websers -m file -a 'path=/root/f1 state=absent'
192.168.0.218 | SUCCESS => {
"changed": true,
"path": "/root/f1",
"state": "absent"
}
192.168.0.99 | SUCCESS => {
"changed": true,
"path": "/root/f1",
"state": "absent"
}
[root@localhost test]# ansible websers -m file -a 'path=/root/dir1 state=absent'
192.168.0.218 | SUCCESS => {
"changed": true,
"path": "/root/dir1",
"state": "absent"
}
192.168.0.99 | SUCCESS => {
"changed": true,
"path": "/root/dir1",
"state": "absent"
}
[root@localhost test]# ansible websers -m shell -a 'ls -l /root'
192.168.0.218 | SUCCESS | rc=0 >>
total 8
drwxr-xr-x. 2 qiuhom root 4096 Nov 11 19:18 scripts
drwxr-xr-x. 3 qiuhom root 4096 Nov 11 19:28 test 192.168.0.99 | SUCCESS | rc=0 >>
total 0
drwxr-xr-x 2 qiuhom root 37 Nov 11 19:18 scripts
drwxr-xr-x 3 qiuhom root 27 Nov 11 19:28 test [root@localhost test]#
说明:删除动作只需要给定state=absent就好,至于目标文件到底是什么我们不关心,我们指定目标文件是目录就删除目录,是文件就删除文件;这里需要说一下的是,如果指定目标目录是挂载点,指定的目录不能被删除,但是目录下的文件会被删除。