Add example of templating inline using copy module (#19752)
* Add example of templating inline using copy module The **copy** module documentation implies that `content:` only works for 'simple values' and for complex stuff you need the **template** module, but that is an understatement. You can use **copy** to template anything you desire. So I changed the wording, added an example, and also added a note to the template module that the **copy** module could be used for 'inline templating'. This fixes #19741.
This commit is contained in:
parent
4e8b28e404
commit
be1c517f4d
3 changed files with 75 additions and 70 deletions
|
@ -22,12 +22,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
|
|||
'status': ['stableinterface'],
|
||||
'supported_by': 'core'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: copy
|
||||
version_added: "historical"
|
||||
short_description: Copies files to remote locations.
|
||||
short_description: Copies files to remote locations
|
||||
description:
|
||||
- The C(copy) module copies a file from the local or remote machine to a location on the remote machine.
|
||||
Use the M(fetch) module to copy files from remote locations to the local box.
|
||||
|
@ -41,69 +40,58 @@ options:
|
|||
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.
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
content:
|
||||
version_added: "1.1"
|
||||
description:
|
||||
- When used instead of 'src', sets the contents of a file directly to the specified value.
|
||||
This is for simple values, for anything complex or with formatting please switch to the template module.
|
||||
required: false
|
||||
default: null
|
||||
For anything advanced or with formatting also look at the template module.
|
||||
version_added: "1.1"
|
||||
dest:
|
||||
description:
|
||||
- Remote absolute path where the file should be copied to. If src is a directory,
|
||||
- Remote absolute path where the file should be copied to. If C(src) is a directory,
|
||||
this must be a directory too.
|
||||
required: true
|
||||
default: null
|
||||
required: yes
|
||||
backup:
|
||||
description:
|
||||
- Create a backup file including the timestamp information so you can get
|
||||
the original file back if you somehow clobbered it incorrectly.
|
||||
type: bool
|
||||
default: 'no'
|
||||
version_added: "0.7"
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "no"
|
||||
force:
|
||||
description:
|
||||
- the default is C(yes), which will replace the remote file when contents
|
||||
are different than the source. If C(no), the file will only be transferred
|
||||
if the destination does not exist.
|
||||
version_added: "1.1"
|
||||
required: false
|
||||
choices: [ "yes", "no" ]
|
||||
default: "yes"
|
||||
type: bool
|
||||
default: 'yes'
|
||||
aliases: [ "thirsty" ]
|
||||
version_added: "1.1"
|
||||
directory_mode:
|
||||
description:
|
||||
- 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.
|
||||
required: false
|
||||
version_added: "1.5"
|
||||
remote_src:
|
||||
description:
|
||||
- If False, it will search for src at originating/master machine, if True it will go to the remote/target machine for the src. Default is False.
|
||||
- Currently remote_src does not support recursive copying.
|
||||
choices: [ "True", "False" ]
|
||||
required: false
|
||||
default: "False"
|
||||
- If C(no), it will search for src at originating/master machine.
|
||||
- If C(yes), it will go to the remote/target machine for the src. Default is False.
|
||||
- Currently C(remote_src) does not support recursive copying.
|
||||
type: bool
|
||||
default: 'no'
|
||||
version_added: "2.0"
|
||||
follow:
|
||||
required: false
|
||||
default: "no"
|
||||
choices: [ "yes", "no" ]
|
||||
description:
|
||||
- This flag indicates that filesystem links in the destination, if they exist, should be followed.
|
||||
type: bool
|
||||
default: 'no'
|
||||
version_added: "1.8"
|
||||
description:
|
||||
- 'This flag indicates that filesystem links in the destination, if they exist, should be followed.'
|
||||
local_follow:
|
||||
required: false
|
||||
default: "yes"
|
||||
choices: [ "yes", "no" ]
|
||||
version_added: "2.4"
|
||||
description:
|
||||
- 'This flag indicates that filesystem links in the source tree, if they exist, should be followed.'
|
||||
- This flag indicates that filesystem links in the source tree, if they exist, should be followed.
|
||||
type: bool
|
||||
default: 'yes'
|
||||
version_added: "2.4"
|
||||
extends_documentation_fragment:
|
||||
- files
|
||||
- validate
|
||||
|
@ -117,7 +105,7 @@ notes:
|
|||
- For Windows targets, use the M(win_copy) module instead.
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
EXAMPLES = r'''
|
||||
# Example from Ansible Playbooks
|
||||
- copy:
|
||||
src: /srv/myfiles/foo.conf
|
||||
|
@ -132,7 +120,7 @@ EXAMPLES = '''
|
|||
dest: /etc/foo.conf
|
||||
owner: foo
|
||||
group: foo
|
||||
mode: "u=rw,g=r,o=r"
|
||||
mode: u=rw,g=r,o=r
|
||||
|
||||
# Another symbolic mode example, adding some permissions and removing others
|
||||
- copy:
|
||||
|
@ -140,7 +128,7 @@ EXAMPLES = '''
|
|||
dest: /etc/foo.conf
|
||||
owner: foo
|
||||
group: foo
|
||||
mode: "u+rw,g-wx,o-rwx"
|
||||
mode: u+rw,g-wx,o-rwx
|
||||
|
||||
# Copy a new "ntp.conf file into place, backing up the original if it differs from the copied version
|
||||
- copy:
|
||||
|
@ -155,41 +143,57 @@ EXAMPLES = '''
|
|||
- copy:
|
||||
src: /mine/sudoers
|
||||
dest: /etc/sudoers
|
||||
validate: 'visudo -cf %s'
|
||||
validate: visudo -cf %s
|
||||
|
||||
# Copy a "sudoers" file on the remote machine for editing
|
||||
- copy:
|
||||
remote_src: true
|
||||
src: /etc/sudoers
|
||||
dest: /etc/sudoers.edit
|
||||
remote_src: yes
|
||||
validate: visudo -cf %s
|
||||
|
||||
# Create a CSV file from your complete inventory using an inline template
|
||||
- hosts: all
|
||||
tasks:
|
||||
- copy:
|
||||
content: |
|
||||
HOSTNAME;IPADDRESS;FQDN;OSNAME;OSVERSION;PROCESSOR;ARCHITECTURE;MEMORY;
|
||||
{% for host in hostvars %}
|
||||
{% set vars = hostvars[host|string] %}
|
||||
{{ vars.ansible_hostname }};{{ vars.remote_host }};{{ vars.ansible_fqdn }};{{ vars.ansible_distribution }};{{ vars.ansible_distribution_version }};{{ vars.ansible_processor[1] }};{{ vars.ansible_architecture }};{{ (vars.ansible_memtotal_mb/1024)|round|int }}; # NOQA
|
||||
{% endfor %}
|
||||
dest: /some/path/systems.csv
|
||||
backup: yes
|
||||
run_once: yes
|
||||
delegate_to: localhost
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
RETURN = r'''
|
||||
dest:
|
||||
description: destination file/path
|
||||
returned: success
|
||||
type: string
|
||||
sample: "/path/to/file.txt"
|
||||
sample: /path/to/file.txt
|
||||
src:
|
||||
description: source file used for the copy on the target machine
|
||||
returned: changed
|
||||
type: string
|
||||
sample: "/home/httpd/.ansible/tmp/ansible-tmp-1423796390.97-147729857856000/source"
|
||||
sample: /home/httpd/.ansible/tmp/ansible-tmp-1423796390.97-147729857856000/source
|
||||
md5sum:
|
||||
description: md5 checksum of the file after running copy
|
||||
returned: when supported
|
||||
type: string
|
||||
sample: "2a5aeecc61dc98c4d780b14b330e3282"
|
||||
sample: 2a5aeecc61dc98c4d780b14b330e3282
|
||||
checksum:
|
||||
description: sha1 checksum of the file after running copy
|
||||
returned: success
|
||||
type: string
|
||||
sample: "6e642bb8dd5c2e027bf21dd923337cbb4214f827"
|
||||
sample: 6e642bb8dd5c2e027bf21dd923337cbb4214f827
|
||||
backup_file:
|
||||
description: name of backup file created
|
||||
returned: changed and if backup=yes
|
||||
type: string
|
||||
sample: "/path/to/file.txt.2015-02-12@22:09~"
|
||||
sample: /path/to/file.txt.2015-02-12@22:09~
|
||||
gid:
|
||||
description: group id of the file, after execution
|
||||
returned: success
|
||||
|
@ -199,12 +203,12 @@ group:
|
|||
description: group of the file, after execution
|
||||
returned: success
|
||||
type: string
|
||||
sample: "httpd"
|
||||
sample: httpd
|
||||
owner:
|
||||
description: owner of the file, after execution
|
||||
returned: success
|
||||
type: string
|
||||
sample: "httpd"
|
||||
sample: httpd
|
||||
uid:
|
||||
description: owner id of the file, after execution
|
||||
returned: success
|
||||
|
@ -214,7 +218,7 @@ mode:
|
|||
description: permissions of the target, after execution
|
||||
returned: success
|
||||
type: string
|
||||
sample: "0644"
|
||||
sample: 0644
|
||||
size:
|
||||
description: size of the target, after execution
|
||||
returned: success
|
||||
|
@ -224,7 +228,7 @@ state:
|
|||
description: state of the target, after execution
|
||||
returned: success
|
||||
type: string
|
||||
sample: "file"
|
||||
sample: file
|
||||
'''
|
||||
|
||||
import os
|
||||
|
@ -270,17 +274,17 @@ def main():
|
|||
|
||||
module = AnsibleModule(
|
||||
# not checking because of daisy chain to file module
|
||||
argument_spec = dict(
|
||||
src = dict(required=False, type='path'),
|
||||
original_basename = dict(required=False), # used to handle 'dest is a directory' via template, a slight hack
|
||||
content = dict(required=False, no_log=True),
|
||||
dest = dict(required=True, type='path'),
|
||||
backup = dict(default=False, type='bool'),
|
||||
force = dict(default=True, aliases=['thirsty'], type='bool'),
|
||||
validate = dict(required=False, type='str'),
|
||||
directory_mode = dict(required=False, type='raw'),
|
||||
remote_src = dict(required=False, type='bool'),
|
||||
local_follow = dict(required=False, type='bool'),
|
||||
argument_spec=dict(
|
||||
src=dict(type='path'),
|
||||
original_basename=dict(type='str'), # used to handle 'dest is a directory' via template, a slight hack
|
||||
content=dict(type='str', no_log=True),
|
||||
dest=dict(type='path', required=True),
|
||||
backup=dict(type='bool', default=False),
|
||||
force=dict(type='bool', default=True, aliases=['thirsty']),
|
||||
validate=dict(type='str'),
|
||||
directory_mode=dict(type='raw'),
|
||||
remote_src=dict(type='bool'),
|
||||
local_follow=dict(type='bool'),
|
||||
),
|
||||
add_file_common_args=True,
|
||||
supports_check_mode=True,
|
||||
|
|
|
@ -19,12 +19,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
|
|||
'status': ['stableinterface'],
|
||||
'supported_by': 'core'}
|
||||
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: template
|
||||
version_added: historical
|
||||
short_description: Templates a file out to a remote server.
|
||||
short_description: Templates a file out to a remote server
|
||||
description:
|
||||
- Templates are processed by the Jinja2 templating language
|
||||
(U(http://jinja.pocoo.org/docs/)) - documentation on the template
|
||||
|
@ -51,8 +50,8 @@ options:
|
|||
description:
|
||||
- Create a backup file including the timestamp information so you can get
|
||||
the original file back if you somehow clobbered it incorrectly.
|
||||
choices: [ "yes", "no" ]
|
||||
default: "no"
|
||||
type: bool
|
||||
default: 'no'
|
||||
newline_sequence:
|
||||
description:
|
||||
- Specify the newline sequence to use for templating files.
|
||||
|
@ -82,15 +81,16 @@ options:
|
|||
trim_blocks:
|
||||
description:
|
||||
- If this is set to True the first newline after a block is removed (block, not variable tag!).
|
||||
default: "no"
|
||||
type: bool
|
||||
default: 'no'
|
||||
version_added: '2.4'
|
||||
force:
|
||||
description:
|
||||
- the default is C(yes), which will replace the remote file when contents
|
||||
are different than the source. If C(no), the file will only be transferred
|
||||
if the destination does not exist.
|
||||
choices: [ "yes", "no" ]
|
||||
default: "yes"
|
||||
type: bool
|
||||
default: 'yes'
|
||||
notes:
|
||||
- For Windows you can use M(win_template) which uses '\r\n' as C(newline_sequence).
|
||||
- Including a string that uses a date in the template will result in the template being marked 'changed' each time
|
||||
|
@ -100,6 +100,8 @@ notes:
|
|||
which changes the variable interpolation markers to [% var %] instead of {{ var }}.
|
||||
This is the best way to prevent evaluation of things that look like, but should not be Jinja2.
|
||||
raw/endraw in Jinja2 will not work as you expect because templates in Ansible are recursively evaluated."
|
||||
- You can use the C(copy) module with the C(content:) option if you prefer the template inline,
|
||||
as part of the playbook.
|
||||
author:
|
||||
- Ansible Core Team
|
||||
- Michael DeHaan
|
||||
|
|
|
@ -230,7 +230,6 @@ lib/ansible/modules/files/acl.py
|
|||
lib/ansible/modules/files/archive.py
|
||||
lib/ansible/modules/files/assemble.py
|
||||
lib/ansible/modules/files/blockinfile.py
|
||||
lib/ansible/modules/files/copy.py
|
||||
lib/ansible/modules/files/ini_file.py
|
||||
lib/ansible/modules/files/iso_extract.py
|
||||
lib/ansible/modules/files/replace.py
|
||||
|
|
Loading…
Reference in a new issue