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'],
|
'status': ['stableinterface'],
|
||||||
'supported_by': 'core'}
|
'supported_by': 'core'}
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
DOCUMENTATION = '''
|
|
||||||
---
|
---
|
||||||
module: copy
|
module: copy
|
||||||
version_added: "historical"
|
version_added: "historical"
|
||||||
short_description: Copies files to remote locations.
|
short_description: Copies files to remote locations
|
||||||
description:
|
description:
|
||||||
- The C(copy) module copies a file from the local or remote machine to a location on the remote machine.
|
- 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.
|
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.
|
with "/", only inside contents of that directory are copied to destination.
|
||||||
Otherwise, if it does not end with "/", the directory itself with all contents
|
Otherwise, if it does not end with "/", the directory itself with all contents
|
||||||
is copied. This behavior is similar to Rsync.
|
is copied. This behavior is similar to Rsync.
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
content:
|
content:
|
||||||
version_added: "1.1"
|
|
||||||
description:
|
description:
|
||||||
- When used instead of 'src', sets the contents of a file directly to the specified value.
|
- 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.
|
For anything advanced or with formatting also look at the template module.
|
||||||
required: false
|
version_added: "1.1"
|
||||||
default: null
|
|
||||||
dest:
|
dest:
|
||||||
description:
|
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.
|
this must be a directory too.
|
||||||
required: true
|
required: yes
|
||||||
default: null
|
|
||||||
backup:
|
backup:
|
||||||
description:
|
description:
|
||||||
- Create a backup file including the timestamp information so you can get
|
- Create a backup file including the timestamp information so you can get
|
||||||
the original file back if you somehow clobbered it incorrectly.
|
the original file back if you somehow clobbered it incorrectly.
|
||||||
|
type: bool
|
||||||
|
default: 'no'
|
||||||
version_added: "0.7"
|
version_added: "0.7"
|
||||||
required: false
|
|
||||||
choices: [ "yes", "no" ]
|
|
||||||
default: "no"
|
|
||||||
force:
|
force:
|
||||||
description:
|
description:
|
||||||
- the default is C(yes), which will replace the remote file when contents
|
- 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
|
are different than the source. If C(no), the file will only be transferred
|
||||||
if the destination does not exist.
|
if the destination does not exist.
|
||||||
version_added: "1.1"
|
type: bool
|
||||||
required: false
|
default: 'yes'
|
||||||
choices: [ "yes", "no" ]
|
|
||||||
default: "yes"
|
|
||||||
aliases: [ "thirsty" ]
|
aliases: [ "thirsty" ]
|
||||||
|
version_added: "1.1"
|
||||||
directory_mode:
|
directory_mode:
|
||||||
description:
|
description:
|
||||||
- When doing a recursive copy set the mode for the directories. If this is not set we will use the system
|
- 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
|
defaults. The mode is only set on directories which are newly created, and will not affect those that
|
||||||
already existed.
|
already existed.
|
||||||
required: false
|
|
||||||
version_added: "1.5"
|
version_added: "1.5"
|
||||||
remote_src:
|
remote_src:
|
||||||
description:
|
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.
|
- If C(no), it will search for src at originating/master machine.
|
||||||
- Currently remote_src does not support recursive copying.
|
- If C(yes), it will go to the remote/target machine for the src. Default is False.
|
||||||
choices: [ "True", "False" ]
|
- Currently C(remote_src) does not support recursive copying.
|
||||||
required: false
|
type: bool
|
||||||
default: "False"
|
default: 'no'
|
||||||
version_added: "2.0"
|
version_added: "2.0"
|
||||||
follow:
|
follow:
|
||||||
required: false
|
description:
|
||||||
default: "no"
|
- This flag indicates that filesystem links in the destination, if they exist, should be followed.
|
||||||
choices: [ "yes", "no" ]
|
type: bool
|
||||||
|
default: 'no'
|
||||||
version_added: "1.8"
|
version_added: "1.8"
|
||||||
description:
|
|
||||||
- 'This flag indicates that filesystem links in the destination, if they exist, should be followed.'
|
|
||||||
local_follow:
|
local_follow:
|
||||||
required: false
|
|
||||||
default: "yes"
|
|
||||||
choices: [ "yes", "no" ]
|
|
||||||
version_added: "2.4"
|
|
||||||
description:
|
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:
|
extends_documentation_fragment:
|
||||||
- files
|
- files
|
||||||
- validate
|
- validate
|
||||||
|
@ -117,7 +105,7 @@ notes:
|
||||||
- For Windows targets, use the M(win_copy) module instead.
|
- For Windows targets, use the M(win_copy) module instead.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = r'''
|
||||||
# Example from Ansible Playbooks
|
# Example from Ansible Playbooks
|
||||||
- copy:
|
- copy:
|
||||||
src: /srv/myfiles/foo.conf
|
src: /srv/myfiles/foo.conf
|
||||||
|
@ -132,7 +120,7 @@ EXAMPLES = '''
|
||||||
dest: /etc/foo.conf
|
dest: /etc/foo.conf
|
||||||
owner: foo
|
owner: foo
|
||||||
group: 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
|
# Another symbolic mode example, adding some permissions and removing others
|
||||||
- copy:
|
- copy:
|
||||||
|
@ -140,7 +128,7 @@ EXAMPLES = '''
|
||||||
dest: /etc/foo.conf
|
dest: /etc/foo.conf
|
||||||
owner: foo
|
owner: foo
|
||||||
group: 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 a new "ntp.conf file into place, backing up the original if it differs from the copied version
|
||||||
- copy:
|
- copy:
|
||||||
|
@ -155,41 +143,57 @@ EXAMPLES = '''
|
||||||
- copy:
|
- copy:
|
||||||
src: /mine/sudoers
|
src: /mine/sudoers
|
||||||
dest: /etc/sudoers
|
dest: /etc/sudoers
|
||||||
validate: 'visudo -cf %s'
|
validate: visudo -cf %s
|
||||||
|
|
||||||
# Copy a "sudoers" file on the remote machine for editing
|
# Copy a "sudoers" file on the remote machine for editing
|
||||||
- copy:
|
- copy:
|
||||||
remote_src: true
|
|
||||||
src: /etc/sudoers
|
src: /etc/sudoers
|
||||||
dest: /etc/sudoers.edit
|
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:
|
dest:
|
||||||
description: destination file/path
|
description: destination file/path
|
||||||
returned: success
|
returned: success
|
||||||
type: string
|
type: string
|
||||||
sample: "/path/to/file.txt"
|
sample: /path/to/file.txt
|
||||||
src:
|
src:
|
||||||
description: source file used for the copy on the target machine
|
description: source file used for the copy on the target machine
|
||||||
returned: changed
|
returned: changed
|
||||||
type: string
|
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:
|
md5sum:
|
||||||
description: md5 checksum of the file after running copy
|
description: md5 checksum of the file after running copy
|
||||||
returned: when supported
|
returned: when supported
|
||||||
type: string
|
type: string
|
||||||
sample: "2a5aeecc61dc98c4d780b14b330e3282"
|
sample: 2a5aeecc61dc98c4d780b14b330e3282
|
||||||
checksum:
|
checksum:
|
||||||
description: sha1 checksum of the file after running copy
|
description: sha1 checksum of the file after running copy
|
||||||
returned: success
|
returned: success
|
||||||
type: string
|
type: string
|
||||||
sample: "6e642bb8dd5c2e027bf21dd923337cbb4214f827"
|
sample: 6e642bb8dd5c2e027bf21dd923337cbb4214f827
|
||||||
backup_file:
|
backup_file:
|
||||||
description: name of backup file created
|
description: name of backup file created
|
||||||
returned: changed and if backup=yes
|
returned: changed and if backup=yes
|
||||||
type: string
|
type: string
|
||||||
sample: "/path/to/file.txt.2015-02-12@22:09~"
|
sample: /path/to/file.txt.2015-02-12@22:09~
|
||||||
gid:
|
gid:
|
||||||
description: group id of the file, after execution
|
description: group id of the file, after execution
|
||||||
returned: success
|
returned: success
|
||||||
|
@ -199,12 +203,12 @@ group:
|
||||||
description: group of the file, after execution
|
description: group of the file, after execution
|
||||||
returned: success
|
returned: success
|
||||||
type: string
|
type: string
|
||||||
sample: "httpd"
|
sample: httpd
|
||||||
owner:
|
owner:
|
||||||
description: owner of the file, after execution
|
description: owner of the file, after execution
|
||||||
returned: success
|
returned: success
|
||||||
type: string
|
type: string
|
||||||
sample: "httpd"
|
sample: httpd
|
||||||
uid:
|
uid:
|
||||||
description: owner id of the file, after execution
|
description: owner id of the file, after execution
|
||||||
returned: success
|
returned: success
|
||||||
|
@ -214,7 +218,7 @@ mode:
|
||||||
description: permissions of the target, after execution
|
description: permissions of the target, after execution
|
||||||
returned: success
|
returned: success
|
||||||
type: string
|
type: string
|
||||||
sample: "0644"
|
sample: 0644
|
||||||
size:
|
size:
|
||||||
description: size of the target, after execution
|
description: size of the target, after execution
|
||||||
returned: success
|
returned: success
|
||||||
|
@ -224,7 +228,7 @@ state:
|
||||||
description: state of the target, after execution
|
description: state of the target, after execution
|
||||||
returned: success
|
returned: success
|
||||||
type: string
|
type: string
|
||||||
sample: "file"
|
sample: file
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -270,17 +274,17 @@ def main():
|
||||||
|
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
# not checking because of daisy chain to file module
|
# not checking because of daisy chain to file module
|
||||||
argument_spec = dict(
|
argument_spec=dict(
|
||||||
src = dict(required=False, type='path'),
|
src=dict(type='path'),
|
||||||
original_basename = dict(required=False), # used to handle 'dest is a directory' via template, a slight hack
|
original_basename=dict(type='str'), # used to handle 'dest is a directory' via template, a slight hack
|
||||||
content = dict(required=False, no_log=True),
|
content=dict(type='str', no_log=True),
|
||||||
dest = dict(required=True, type='path'),
|
dest=dict(type='path', required=True),
|
||||||
backup = dict(default=False, type='bool'),
|
backup=dict(type='bool', default=False),
|
||||||
force = dict(default=True, aliases=['thirsty'], type='bool'),
|
force=dict(type='bool', default=True, aliases=['thirsty']),
|
||||||
validate = dict(required=False, type='str'),
|
validate=dict(type='str'),
|
||||||
directory_mode = dict(required=False, type='raw'),
|
directory_mode=dict(type='raw'),
|
||||||
remote_src = dict(required=False, type='bool'),
|
remote_src=dict(type='bool'),
|
||||||
local_follow = dict(required=False, type='bool'),
|
local_follow=dict(type='bool'),
|
||||||
),
|
),
|
||||||
add_file_common_args=True,
|
add_file_common_args=True,
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
|
|
|
@ -19,12 +19,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
|
||||||
'status': ['stableinterface'],
|
'status': ['stableinterface'],
|
||||||
'supported_by': 'core'}
|
'supported_by': 'core'}
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = r'''
|
DOCUMENTATION = r'''
|
||||||
---
|
---
|
||||||
module: template
|
module: template
|
||||||
version_added: historical
|
version_added: historical
|
||||||
short_description: Templates a file out to a remote server.
|
short_description: Templates a file out to a remote server
|
||||||
description:
|
description:
|
||||||
- Templates are processed by the Jinja2 templating language
|
- Templates are processed by the Jinja2 templating language
|
||||||
(U(http://jinja.pocoo.org/docs/)) - documentation on the template
|
(U(http://jinja.pocoo.org/docs/)) - documentation on the template
|
||||||
|
@ -51,8 +50,8 @@ options:
|
||||||
description:
|
description:
|
||||||
- Create a backup file including the timestamp information so you can get
|
- Create a backup file including the timestamp information so you can get
|
||||||
the original file back if you somehow clobbered it incorrectly.
|
the original file back if you somehow clobbered it incorrectly.
|
||||||
choices: [ "yes", "no" ]
|
type: bool
|
||||||
default: "no"
|
default: 'no'
|
||||||
newline_sequence:
|
newline_sequence:
|
||||||
description:
|
description:
|
||||||
- Specify the newline sequence to use for templating files.
|
- Specify the newline sequence to use for templating files.
|
||||||
|
@ -82,15 +81,16 @@ options:
|
||||||
trim_blocks:
|
trim_blocks:
|
||||||
description:
|
description:
|
||||||
- If this is set to True the first newline after a block is removed (block, not variable tag!).
|
- 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'
|
version_added: '2.4'
|
||||||
force:
|
force:
|
||||||
description:
|
description:
|
||||||
- the default is C(yes), which will replace the remote file when contents
|
- 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
|
are different than the source. If C(no), the file will only be transferred
|
||||||
if the destination does not exist.
|
if the destination does not exist.
|
||||||
choices: [ "yes", "no" ]
|
type: bool
|
||||||
default: "yes"
|
default: 'yes'
|
||||||
notes:
|
notes:
|
||||||
- For Windows you can use M(win_template) which uses '\r\n' as C(newline_sequence).
|
- 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
|
- 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 }}.
|
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.
|
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."
|
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:
|
author:
|
||||||
- Ansible Core Team
|
- Ansible Core Team
|
||||||
- Michael DeHaan
|
- Michael DeHaan
|
||||||
|
|
|
@ -230,7 +230,6 @@ lib/ansible/modules/files/acl.py
|
||||||
lib/ansible/modules/files/archive.py
|
lib/ansible/modules/files/archive.py
|
||||||
lib/ansible/modules/files/assemble.py
|
lib/ansible/modules/files/assemble.py
|
||||||
lib/ansible/modules/files/blockinfile.py
|
lib/ansible/modules/files/blockinfile.py
|
||||||
lib/ansible/modules/files/copy.py
|
|
||||||
lib/ansible/modules/files/ini_file.py
|
lib/ansible/modules/files/ini_file.py
|
||||||
lib/ansible/modules/files/iso_extract.py
|
lib/ansible/modules/files/iso_extract.py
|
||||||
lib/ansible/modules/files/replace.py
|
lib/ansible/modules/files/replace.py
|
||||||
|
|
Loading…
Reference in a new issue