One: Why choose Ansible
Compared with puppet and saltstack, Ansible does not require a client and is more lightweight
Ansible does not even need to start services, just one Tools, which can easily implement distributed extensions
More powerful remote command execution operations
is not lost to other functions of puppet and saltstack
Two: Ansible Basic architecture
Three: Asible Basic composition
Core: ansible
Core Modules: These are the modules that come with ansible
Custom Modules: If the core The module is not enough to complete a certain function,
can add extension module plug-ins (Plugins): complete the supplement of the module function
playbooks (Playbooks): ansible task configuration files, multiple Tasks are defined in the script and executed automatically by ansible
Connectior Plugins: Ansible connects to each host based on the connection plug-in. Although Ansible uses ssh to connect to each host, it also supports other Connection method, so you need a connection plug-in
Host Inventory: Define the host managed by ansible
Four: Ansible working principle
< h2>Five: Ansible installation
There are many ways to install Ansible, the commonly used installation method is based on yum or source code, if it is based on yum installation, you need to configure the epel source, and then directly execute yum -y install ansible That’s it. The source code installation configuration is as follows:
Resolve dependencies:
yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
download ansible:
#wget https://github.com/ansible/ansible/archive/release1.6.1.zip
unzip and install
unzip release1.6.1 cd ansible-release1.6.1 python setup.py build python setup.py install mkdir /etc/ansible cp -r examples/* /etc/ansible
6: Host list
6.1 Simple hosts and groups
The name in brackets On behalf of the group name, you can divide the huge host into groups with identification according to your needs, such as the two groups webservers and dbservers groups above;
Hosts can use domain names, host names, IP address representation; of course, when using the first two, the host also needs to be able to reversely resolve to the corresponding IP address. Generally, IP addresses are used in this type of configuration;
mail.yanruogu.com [webservers] web1.yanruogu.com web2.yanruogu.com [dbservers] db1.yanruogu.com db2.yanruogu.com
6.2 Port and Alias
If the SSH of some hosts is running on a custom port, ansible will not use your SSH configuration when using Paramiko for ssh connection The port listed in the file, but if you modify ansible to use openssh for ssh connection, it will be used:
192.168. 1.1:3091
If you want to set some aliases for some static IP, you can do this:
web1 ansible_ssh_port = 3333 ansible_ssh_host = 192.168.1.2
The web1 alias above refers to the host whose IP is 192.168.1.2 and the ssh connection port is 3333.
6.3 Specify the host range
[webservers] www[01:50].yanruogu.com [databases] db-[a:f].yanruogu.com
The above specifies a total of 50 hosts in the webservers group from web1 to web50; the databases group has a total of 6 hosts from db-a to db-f.
6.4 Use host variables
The following are the frequently used variables in the Hosts section:
ansible_ssh_host #Used to specify the real IP of the managed host ansible_ssh_port #Used to specify the ssh port number connected to the managed host, the default is 22 ansible_ssh_user #User name used by default when ssh connects ansible_ssh_pass #ssh connection password ansible_sudo_pass #Use sudo to connect to the user's password ansible_sudo_exec #If the sudo command is not in the default path, you need to specify the sudo command path ansible_ssh_private_key_file #Secret key file path, if you don’t want to use ssh-agent management, you can use this option ansible_shell_type #The type of shell of the target system, default sh ansible_connection #SSH connection type: local, ssh, paramiko, the default is paramiko before ansible 1.2, and then intelligently select, preferentially use ControlPersist-based ssh (prerequisite for support) ansible_python_interpreter #Used to specify the path of the python interpreter, the default is /usr/bin/python You can also specify the path of ruby and perl ansible_*_interpreter #Other interpreter path, usage is similar to ansible_python_interpreter, where "*" can be ruby or perl and other languages
Examples are as follows:
[test] 192.168.1.1 ansible_ssh_user=root ansible_ssh_pass=‘[email protected]’ 192.168.1.2 ansible_ssh_user=breeze ansible_ssh_pass=‘123456’ 192.168.1.3 ansible_ssh_user=bernie ansible_ssh_port=3055 ansible_ssh_pass=‘456789’
In the above example, three hosts are specified. The passwords for the three hosts are [emailprotected], 123456, 45789, and the specified ssh connection The user names are root, breeze, bernie, and the ssh ports are 22, 22, and 3055, so that there is no need to instruct the user and password when the ansible command is executed.
6.5 Variables in the group
Variables can also be applied to all members of the group by group name:
[test] host1 host2 [test:vars] ntp_server=192.168.1.10 proxy=192.168.1.20
The above test group contains two hosts. By assigning vars to the test group, the corresponding host1 and host2 are equivalent to the corresponding ntp_server and proxy variables. The parameter value.
6.6 Group inclusion and group variables
In the above example, the Wuhan group has web1 and web2; the Suizhou group has web3 and web4 hosts; and a Hubei group is specified , Including both Wuhan and Suizhou; 2 vars variables are specified for all hosts in the group at the same time. A group of China is set up, including Hubei and Hunan.
Note: The vars variable is basically not used in the ansible ad-hoc part, and is mainly used in ansible-playbook.
[wuhan] web1 web2 [suizhou] web4 web3 [hubei:children] wuhan suizhou [hubei:vars] ntp_server=192.168.1.10 zabbix_server=192.168.1.10 [china:children] hubei hunan
6.7Patterns (host and group regular matching part)
directly understand Patterns The regularity is actually not completely accurate. The normal understanding of patterns means which hosts are managed in ansible, and it can also be understood as which hosts to communicate with. Before discussing this issue, let’s take a look at the usage of ansible:
ansible-m - a
directly previous example:
ansible webservers- m service -a "name=httpd state=restarted"
Here is to restart the httpd service for the webservers group or host, where webservers is the Pattern part. The reason why Pattern (pattern) can be understood as regular is mainly for the frequently used usage below.
1, means that all hosts can use all or *
2, wildcard and logical OR
Using wildcards, you can also specify a group of hosts with regular characteristics Or host name, colon means or-logical or
web1.yanruogu.com web1.yanruogu.com:web2.yanruogu.com 192.168.1.1 192.168.1.*
Of course, the * wildcard here can also be used in front, such as:
*.yanruogu.com *.com webservers1[0] #means matching the first host of the webservers1 group webservers1[0:25] #means matching the 1st to 25th hosts of the webservers1 group (the official website document is ":" means the range, the test finds that it should be used"- ", be careful not to confuse with matching multiple host groups)
The above usage is also applicable between multiple groups, such as:
webservers webservers:dbservers #represents all hosts in the two groups
3, logical negation and logical and
Not expressions, for example, the target host must be in the group webservers but not in the phoenix group
webserver:!phoenix
Intersection expression, for example, the target host must be in the group webservers and in the group staging
webservers:&staging
A more complex example:
webserver:dbservers:&staging:!phoenix
The target host expressed by the above complex expression must meet: in the webservers or dbservers group, it must still exist in the staging group, but not in phoenix Group.
4. Hybrid advanced usage
*.yanruogu.com:*.org
You can also use “~” at the beginning to indicate that this is a regular expression:
~(web|db).*\.yanruogu\.com
Give two specific possible usages in ansible-playbook:
a. In the ansible-palybook command, you can also Use variables to compose such an expression, but you must use the “-e” option to specify this expression (usually we don’t use this):
ansible-palybook -e webservers:!`excluded`:&`required`
b. In ansible and ansible-playbook, you can also pass a parameter “–limit” to explicitly specify to exclude certain hosts or groups: p>
ansible-playbook site.yml --limit datacenter2
c. Starting from Ansible1.2, if you want to exclude hosts in a file, you can use "@":
ansible-playbook site.yml --limit @retry_hosts.txt
Seven: Ansible.cfg configuration instructions
There is a configuration file /etc/ansible/ansible.cfg after Ansible is installed by default. The configuration file defines the default configuration part of the ansible host. For example, the default is whether a password is required, whether to enable sudo authentication, the location of the action_plugins plug-in, the location of the hosts host group, Whether to enable log function, default port, key file location and so on.
The details are as follows:
[defaults] # some basic default values... hostfile = /etc/ansible/hosts \\ Specify the location of the default hosts configuration # library_path = /usr/share/my_modules/ remote_tmp = $HOME/.ansible/tmp pattern = * forks = 5 poll_interval = 15 sudo_user = root\\remote sudo user #ask_sudo_pass = True \\Whether to ask for ssh password every time the ansible command is executed #ask_pass = True \\Whether to ask the sudo password every time the ansible command is executed transport = smart remote_port = 22 module_lang = C gathering = implicit host_key_checking = False \\Close the first use of ansible to connect to the client is to enter the command prompt log_path = /var/log/ansible.log \\You can add it yourself when needed. chown -R root:root ansible.log system_warnings = False \\Turn off the system prompt message when running ansible, generally it is a prompt to upgrade # set plugin path directories here, separate with colons action_plugins = /usr/share/ansible_plugins/action_plugins callback_plugins = /usr/share/ansible_plugins/callback_plugins connection_plugins = /usr/share/ansible_plugins/connection_plugins lookup_plugins = /usr/share/ansible_plugins/lookup_plugins vars_plugins = /usr/share/ansible_plugins/vars_plugins filter_plugins = /usr/share/ansible_plugins/filter_plugins fact_caching = memory [accelerate] accelerate_port = 5099 accelerate_timeout = 30 accelerate_connect_timeout = 5.0 # The daemon timeout is measured in minutes. This time is measured # from the last activity to the accelerate daemon. accelerate_daemon_timeout = 30
If the following error is reported when connecting to a previously unconnected host:
ansible test -a'uptime' 192.168.1.1| FAILED =>Using a SSH password instead of a key is not possible because HostKeychecking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host. 192.168.1.2 | FAILED => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host‘s fingerprint to your known_hosts file to manage this host.
is because there is a fingerprint key string in the ~/.ssh/known_hosts file of this machine, the first time ssh is connected, it will usually prompt to enter yes The confirmation is to add the key string to the ~/.ssh/known_hosts file.
Method 1:
When making an ssh connection, you can use the -o parameter to set StrictHostKeyChecking to no. When using ssh to connect, avoid the prompt to enter the yes/no part when connecting for the first time . By looking at the ansible.cfg configuration file, I found the following line:
[ssh_connection]
# ssh arguments to use
# Leaving off ControlPersist will result in poor performance, so use
# paramiko on older platforms rather than removing it
#ssh_args = -o ControlMaster=auto -o ControlPersist=60s
You can enable the ssh_args part and use the following configuration to avoid the above errors:
ssh_args=-o ControlMaster=auto-o ControlPersist=60s-o StrictHostKeyChecking=no
Method 2:
In the ansible.cfg configuration file, you will also find the following configuration :
# uncomment this to disable SSH key host checking host_key_checking = False
The host_key_checking part is commented by default. By opening the comment of this line, you can also skip the ssh first connection prompt verification part. But in the actual test, it seems to have no effect. It is recommended to use method 1.
Other parts
When ansible is executed by default, the log will not be output to a file, but in ansible. The cfg configuration file has the following line:
log_path = /var/log/ansible.log
The log_path line is commented by default. Turn on the comment of this line. After all commands are executed, the log will be output to /var/log/ansible. log file.
Eight: Ad-hoc and command execution module
Ad-Hoc refers to a command that is temporarily executed under ansible and does not need to be saved. For complex commands, playbooks are used . The execution of Ad-hoc depends on modules, and ansible officially provides a large number of modules. Such as: command, raw, shell, file, cron, etc., which can be checked through ansible-doc -l. You can use ansible-doc -s module to view the parameters of a module, or use ansible-doc help module to view more detailed information about the module.
8.1Ad-hoc
1. Command description
The execution of an ad-hoc command needs to be executed in the following format:
Ansible host or group-m module name-a'module parameter' ansible parameter
-
host and group are in /etc/ansible/ The specified part in hosts, of course, the dynamic inventory uses the host obtained by the script from the external application;
-
The module name, you can check the currently installed module through ansible-doc -l Module, when it is not specified by default, the command module is used. You can check the “#module_name = command” part of /etc/ansible/ansible.cfg for details. The default module can be modified in the configuration file;
li>
-
Module parameters, you can check the specific usage and the following parameters through “ansible-doc -s module name”;
-
Ansible parameters, you can pass As you can see in the help information of the ansible command, there are many parameters to choose from, such as whether to enter a password, whether to sudo, etc.
2, background execution
When the command execution time is relatively long, it can also be executed in the background, using the -B and -P parameters, as follows :
Ansible all -B 3600-a "/usr/bin/long_running_operation --do-stuff" #Background execution command 3600s, -B indicates the time of background execution
ansible all -m async_status -a "jid=123456789" #Check the status of the task
ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do -stuff" #The maximum time to execute a command in the background is 1800s, which is 30 minutes, -P checks the status every 60s, the default is 15s
8.2 command execution module
The command execution module contains the following four modules:
-
command module: This module can be executed directly by following the command to be executed by -a, but If there are parts with the following characters in the command, the execution will be unsuccessful. “”<", ">“, “|”, “&”;
-
Shell module: basic usage and The command is the same, but it is executed through /bin/sh, so the shell module can execute any command, just like executing it on the machine;
-
raw module: usage and shell Like the module, it can also execute any command, just like it is executed on the local machine;
-
Script module: It executes the shell of the management side on the managed host. The principle is It is to copy the shell to the remote host first, and then execute it on the remote host. The principle is similar to the raw module.
Note: The raw module is different from the comand and shell modules. There is no chdir, creates, and removes parameters. The function of the chdir parameter is to first cut to the directory specified by chdir, and then execute the following commands, which will be included in many modules later.
The command module contains the following Options:
-
creates: a file name, when the file exists, the command will not be executed
-
free_form: linux command to be executed
p>
-
chdir: switch to the specified directory before executing the command
-
removes: a file name, when the file is not If it exists, the option will not be executed
-
executable: switch shell to execute the command, the execution path must be an absolute path
< p>
Example of using chdir:
ansible 192.168.1.1 -m command -a'chdir=/tmp/test.txt touch test.file '
ansible 192.168.1.1 -m shell -a'chdir=/tmp/test.txt touch test2.file'
ansible 192.168.1.1 -m raw -a'chdir=/tmp/text.txt touch test3 .file'
All three commands will return the status of successful execution. But actually only the first two files will be created successfully. The result file of the execution using the raw module is actually created normally, but not in the directory specified by chdir, but in the home directory of the currently executing user.
Examples of creates and removes:
ansible 192.168.1.1 -a’creates=/tmp/server.txt uptime’ #当/tmp/server. When the txt file exists, the uptime command will not be executed
ansible 192.168.1.1 -a’removes=/tmp/server.txt uptime’ #When the /tmp/server.txt file does not exist, it will not be executed uptime instruction
Example of script module:
The content of the script file script.sh to be executed is as follows:
< pre>#/bin/bash
ifconfig
df -hT
Execute ansible command: ansible 10.212.52.252 -m script -a'script.sh'|egrep'>>|stdout'
9: ansible Common modules
file: used to configure file attributes
yum: used to install software packages
cron: configure scheduled tasks
copy : Copy files to the remote host
command: execute commands on the remote host
raw: similar to the command module, support pipes
user: configure user group: Configure user groups
service: used to manage services
ping: used to detect whether the remote host is alive
setup: view the basic information of the remote host
mount: Configure mount point
Show all modules
ansible-doc -l
View related parameters of a module
ansible-doc -s user
Invoke a certain module, a certain parameter
#-m call A module #-a Call a parameter under the module ansible all -m command -a ‘ls /home’
6.1setup module
View the basic information of the remote host
The setup module is mainly used to obtain host information. It is often used in playbooks One of the parameters gathered_facts is related to the module. A parameter often used in the setup module is the filter parameter. The specific usage example is as follows:
ansible 10.212.52.252 -m setup -a'filter=ansible_*_mb' //View host memory information ansible 10.212.52.252 -m setup -a ‘filter=ansible_eth[0-2]‘ //View the information of the network card whose ground interface is eth0-2 ansible all -m setup --tree /tmp/facts //Enter the information of all hosts into the /tmp/facts directory, and enter the information of each host into the hostname file (hostname in /etc/ansible/hosts )
6.2ping
Test whether the host is connected, the usage is very simple, no parameters are involved:
ansible test -m ping
6.3file
The file module is mainly used for file operations on the remote host. The file module contains the following options:
-
force: It is necessary to force the creation of a soft link in two cases, one is when the source file does not exist but will be established later; the other is when the target soft link already exists and needs to be created first. Cancel the previous soft link, and then create a new soft link. There are two options: yes|no
-
group: Define the group of files/directories
li>
-
mode: Define the permissions of the file/directory
-
owner: Define the owner of the file/directory
-
path: a required option, which defines the path of the file/directory
-
recurse: recursively set the attributes of the file, only valid for the directory
-
dest: The path to be linked to, only used in state =link situation
-
state:
-
directory: If the directory does not exist, create Directory
-
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 , Then update its last modification time
-
absent: delete directories, files or unlink files
-
< li>
src: The path of the source file to be linked, only used when state=link
Example of use:
ansible test -m file -a "src=/etc/fstab dest= /tmp/fstab state=link" ansible test -m file -a "path=/tmp/fstab state=absent" ansible test -m file -a "path=/tmp/test state=touch"
6.4copy module
Copy files to remote host, copy module Contains the following options:
-
backup: Back up the original file before overwriting. The backup file contains time information. There are two options: yes|no
-
content: used to replace “src”, you can directly set the value of the specified file
-
dest: Required. The absolute path of the remote host to copy the source file to. If the source file is a directory, then the path must also be a directory
-
directory_mode: recursively set directory permissions , The default is the system default permissions
-
force: If the target host contains the file, but the content is different, if it is set to yes, it will be overwritten by force. If it is no, it will only be The file is copied only when the target location of the host does not exist. The default is yes
-
others: all options in the file module can be used here
-
src: to be copied to The local address of the file on the remote host can be an absolute path or a relative path. If the path is a directory, it will be copied recursively. In this case, if the path ends with “/”, only the contents of the directory will be copied. If the “/” is not used at the end, then the contents including the directory The entire content is copied, similar to rsync.
-
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 visudo example below.
The example is as follows:
ansible test- m copy -a "src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644" ansible test -m copy -a "src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes" ansible test -m copy -a "src=/mine/sudoers dest=/etc/sudoers validate=‘visudo -cf %s’"
#wget https://github.com/ansible/ansible/archive/release1.6.1. zip
unzip release1.6.1 cd ansible-release1.6.1 python setup.py build python setup.py install mkdir /etc/ansible cp -r examples/* /etc/ansible
mail.yanruogu.com [webservers] web1.yanruogu.com web2.yanruogu.com [dbservers] db1.yanruogu.com db2.yanruogu.com
192.168.1.1:3091
web1 ansible_ssh_port = 3333 ansible_ssh_host = 192.168.1.2
[webservers] www[01:50].yanruogu.com [databases] db-[a:f].yanruogu.com
ansible_ssh_host #Used to specify the real IP of the managed host ansible_ssh_port #Used to specify the ssh port number connected to the managed host, the default is 22 ansible_ssh_user #User name used by default when ssh connects ansible_ssh_pass #ssh connection password ansible_sudo_pass #Use sudo to connect to the user's password ansible_sudo_exec #If the sudo command is not in the default path, you need to specify the sudo command path ansible_ssh_private_key_file #Secret key file path, if you don’t want to use ssh-agent management, you can use this option ansible_shell_type #The type of shell of the target system, default sh ansible_connection #SSH connection type: local, ssh, paramiko, the default is paramiko before ansible 1.2, and then intelligently select, preferentially use ControlPersist-based ssh (prerequisite for support) ansible_python_interpreter #Used to specify the path of the python interpreter, the default is /usr/bin/python You can also specify the path of ruby and perl ansible_*_interpreter #Other interpreter path, usage is similar to ansible_python_interpreter, where "*" can be ruby or perl and other languages
[test] 192.168.1.1 ansible_ssh_user=root ansible_ssh_pass=‘[email protected]’ 192.168.1.2 ansible_ssh_user=breeze ansible_ssh_pass=‘123456’ 192.168.1.3 ansible_ssh_user=bernie ansible_ssh_port=3055 ansible_ssh_pass=‘456789’
[test] host1 host2 [test:vars] ntp_server=192.168.1.10 proxy=192.168.1.20
[wuhan] web1 web2 [suizhou] web4 web3 [hubei:children] wuhan suizhou [hubei:vars] ntp_server=192.168.1.10 zabbix_server=192.168.1.10 [china:children] hubei hunan
ansible-m -a
ansible webservers -m service -a "name=httpd state=restarted"
web1.yanruogu.com web1.yanruogu.com:web2.yanruogu.com 192.168.1.1 192.168.1.*
*.yanruogu.com *.com webservers1[0] #means matching the first host of the webservers1 group webservers1[0:25] #means matching the 1st to 25th hosts of the webservers1 group (the official website document is ":" means the range, the test finds that it should be used"- ", be careful not to confuse with matching multiple host groups)
webservers webservers:dbservers #represents all hosts in the two groups
webserver:!phoenix
webservers:&staging
webserver:dbservers:&staging:!phoenix
*.yanruogu.com:*.org
~(web|db).*\.yanruogu\.com
ansible-palybook -e webservers:!`excluded`:&`required`
ansible-playbook site.yml --limit datacenter2
ansible-playbook site.yml --limit @retry_hosts.txt
[defaults] # some basic default values... hostfile = /etc/ansible/hosts \\ Specify the location of the default hosts configuration # library_path = /usr/share/my_modules/ remote_tmp = $HOME/.ansible/tmp pattern = * forks = 5 poll_interval = 15 sudo_user = root\\remote sudo user #ask_sudo_pass = True \\Whether to ask for ssh password every time the ansible command is executed #ask_pass = True \\Whether to ask the sudo password every time the ansible command is executed transport = smart remote_port = 22 module_lang = C gathering = implicit host_key_checking = False \\Close the first use of ansible to connect to the client is to enter the command prompt log_path = /var/log/ansible.log \\You can add it yourself when needed. chown -R root:root ansible.log system_warnings = False \\Turn off the system prompt message when running ansible, generally it is a prompt to upgrade # set plugin path directories here, separate with colons action_plugins = /usr/share/ansible_plugins/action_plugins callback_plugins = /usr/share/ansible_plugins/callback_plugins connection_plugins = /usr/share/ansible_plugins/connection_plugins lookup_plugins = /usr/share/ansible_plugins/lookup_plugins vars_plugins = /usr/share/ansible_plugins/vars_plugins filter_plugins = /usr/share/ansible_plugins/filter_plugins fact_caching = memory [accelerate] accelerate_port = 5099 accelerate_timeout = 30 accelerate_connect_timeout = 5.0 # The daemon timeout is measured in minutes. This time is measured # from the last activity to the accelerate daemon. accelerate_daemon_timeout = 30
ansible test -a ‘uptime‘ 192.168.1.1| FAILED =>Using a SSH password instead of a key is not possible because HostKeychecking is enabled and sshpass does not support this.Please add this host‘s fingerprint to your known_hosts file to manage this host. 192.168.1.2 | FAILED => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host‘s fingerprint to your known_hosts file to manage this host.
# uncomment this to disable SSH key host checking host_key_checking = False
log_path = /var/log/ansible.log
ansible-doc -l
ansible-doc -s user
#-m调用某个模块 #-a调用该模块下某个参数 ansible all -m command -a ‘ls /home‘
ansible 10.212.52.252 -m setup -a ‘filter=ansible_*_mb‘ //查看主机内存信息 ansible 10.212.52.252 -m setup -a ‘filter=ansible_eth[0-2]‘ //查看地接口为eth0-2的网卡信息 ansible all -m setup --tree /tmp/facts //将所有主机的信息输入到/tmp/facts目录下,每台主机的信息输入到主机名文件中(/etc/ansible/hosts里的主机名)
ansible test -m ping
ansible test -m file -a "src=/etc/fstab dest=/tmp/fstab state=link" ansible test -m file -a "path=/tmp/fstab state=absent" ansible test -m file -a "path=/tmp/test state=touch"
ansible test -m copy -a "src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644" ansible test -m copy -a "src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes" ansible test -m copy -a "src=/mine/sudoers dest=/etc/sudoers validate=‘visudo -cf %s‘"