1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
This commit is contained in:
Michael DeHaan 2012-05-02 00:55:54 -04:00
parent 0dcbffe784
commit eadc78549f
10 changed files with 71 additions and 69 deletions

View file

@ -263,7 +263,7 @@ command line tools <tt class="docutils literal"><span class="pre">ansible</span>
<p>Often a user of a configuration management system will want to keep inventory <p>Often a user of a configuration management system will want to keep inventory
in a different system. Frequent examples include LDAP, <a class="reference external" href="http://cobbler.github.com">Cobbler</a>, in a different system. Frequent examples include LDAP, <a class="reference external" href="http://cobbler.github.com">Cobbler</a>,
or a piece of expensive enterprisey CMDB software. Ansible easily supports all or a piece of expensive enterprisey CMDB software. Ansible easily supports all
of these options via an external interventory system.</p> of these options via an external inventory system.</p>
<p>If you have a data store system where an Ansible external inventory script doesn&#8217;t already exist, this may require a little coding, but we have a <a class="reference external" href="https://github.com/ansible/ansible/blob/master/examples/scripts/cobbler_external_inventory.py">Cobbler example</a> in the main source tree &#8211; but it&#8217;s pretty simple, as we&#8217;ll explain below &#8211; that would provide a good starting point. Like with modules, it&#8217;s possible to build an external inventory script in any language, as long as it returns JSON.</p> <p>If you have a data store system where an Ansible external inventory script doesn&#8217;t already exist, this may require a little coding, but we have a <a class="reference external" href="https://github.com/ansible/ansible/blob/master/examples/scripts/cobbler_external_inventory.py">Cobbler example</a> in the main source tree &#8211; but it&#8217;s pretty simple, as we&#8217;ll explain below &#8211; that would provide a good starting point. Like with modules, it&#8217;s possible to build an external inventory script in any language, as long as it returns JSON.</p>
<p>If you are familiar with Puppet terminology, this concept is basically the same as &#8216;external nodes&#8217;, with the slight difference that it also defines which hosts are managed.</p> <p>If you are familiar with Puppet terminology, this concept is basically the same as &#8216;external nodes&#8217;, with the slight difference that it also defines which hosts are managed.</p>
<div class="section" id="script-conventions"> <div class="section" id="script-conventions">
@ -325,7 +325,7 @@ override any that have the same name.</p>
<div class="highlight-python"><pre>ansible webserver -m shell -a "echo {{ a }}"</pre> <div class="highlight-python"><pre>ansible webserver -m shell -a "echo {{ a }}"</pre>
</div> </div>
<p>So in other words, you can use those variables in arguments/actions as well. You might use this to name <p>So in other words, you can use those variables in arguments/actions as well. You might use this to name
a conf.d file appropriately or something similar. Who knows.</p> a conf.d file appropriately or something similar. Who knows?</p>
<p>So that&#8217;s the Cobbler integration support &#8211; using the cobbler script as an example, it should be trivial to adapt Ansible to pull inventory, as well as variable information, from any data source. If you create anything interesting, please share with the mailing list, and we can keep it in the source code tree for others to use.</p> <p>So that&#8217;s the Cobbler integration support &#8211; using the cobbler script as an example, it should be trivial to adapt Ansible to pull inventory, as well as variable information, from any data source. If you create anything interesting, please share with the mailing list, and we can keep it in the source code tree for others to use.</p>
<div class="admonition-see-also admonition seealso"> <div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p> <p class="first admonition-title">See also</p>

View file

@ -201,8 +201,8 @@ ssh-add ~/.ssh/id_rsa.pub</pre>
<div class="highlight-python"><pre>ansible atlanta -a "/usr/bin/foo" -u yourname</pre> <div class="highlight-python"><pre>ansible atlanta -a "/usr/bin/foo" -u yourname</pre>
</div> </div>
<p>If you want to run commands through sudo:</p> <p>If you want to run commands through sudo:</p>
<blockquote> <div class="highlight-python"><pre>ansible atlanta -a "/usr/bin/foo" -u yourname --sudo [--ask-sudo-pass]</pre>
<div>ansible atlanta -a &#8220;/usr/bin/foo&#8221; -u yourname &#8211;sudo [&#8211;ask-sudo-pass]</div></blockquote> </div>
<p>Use &#8211;ask-sudo-pass (-K) if you are not using passwordless sudo.</p> <p>Use &#8211;ask-sudo-pass (-K) if you are not using passwordless sudo.</p>
<p>Ok, so those are basics. If you didn&#8217;t read about patterns and groups yet, go back and read <a class="reference internal" href="patterns.html"><em>The Inventory File, Patterns, and Groups</em></a>.</p> <p>Ok, so those are basics. If you didn&#8217;t read about patterns and groups yet, go back and read <a class="reference internal" href="patterns.html"><em>The Inventory File, Patterns, and Groups</em></a>.</p>
<p>The -f 10 in the above specifies the usage of 10 simultaneous processes. Normally commands also take <p>The -f 10 in the above specifies the usage of 10 simultaneous processes. Normally commands also take
@ -215,25 +215,26 @@ module looks like this:</p>
<div class="highlight-python"><pre>ansible raleigh -m shell -a 'echo $TERM'</pre> <div class="highlight-python"><pre>ansible raleigh -m shell -a 'echo $TERM'</pre>
</div> </div>
<p>When running any command with the ansible &#8220;ad hoc&#8221; CLI (as opposed to playbooks), pay particular attention <p>When running any command with the ansible &#8220;ad hoc&#8221; CLI (as opposed to playbooks), pay particular attention
to shell quoting rules, so the shell doesn&#8217;t eat a variable before it gets passed to Ansible. For example, u to shell quoting rules, so the shell doesn&#8217;t eat a variable before it gets passed to Ansible. For example,
using double vs single quotes would evaluate the variable on the box you were on.</p> using double vs single quotes in the above example would evaluate the variable on the box you were on.</p>
<p>So far we&#8217;ve been demoing simple command execution, but most ansible modules usually do not work like <p>So far we&#8217;ve been demoing simple command execution, but most ansible modules usually do not work like
simple scripts. They make the remote system look like you state, and run the commands necessary to simple scripts. They make the remote system look like you state, and run the commands necessary to
get it there. This is commonly referred to as &#8216;idempotence&#8217;, and is a core design goal of ansible. get it there. This is commonly referred to as &#8216;idempotence&#8217;, and is a core design goal of ansible.
However, we also recognize that running ad-hoc commands is equally imporant, so Ansible easily supports both.</p> However, we also recognize that running ad-hoc commands is equally important, so Ansible easily supports both.</p>
</div> </div>
<div class="section" id="file-transfer-templating"> <div class="section" id="file-transfer-templating">
<h2>File Transfer &amp; Templating<a class="headerlink" href="#file-transfer-templating" title="Permalink to this headline"></a></h2> <h2>File Transfer &amp; Templating<a class="headerlink" href="#file-transfer-templating" title="Permalink to this headline"></a></h2>
<p>Here&#8217;s another use case for the <cite>/usr/bin/ansible</cite> command line.</p> <p>Here&#8217;s another use case for the <cite>/usr/bin/ansible</cite> command line.</p>
<p>Ansible can SCP lots of files to multiple machines in parallel, and <p>Ansible can SCP lots of files to multiple machines in parallel, and
optionally use them as template sources.</p> optionally use them as template sources.</p>
<p>To just transfer a file directly to many different servers:</p> <p>To transfer a file directly to many different servers:</p>
<div class="highlight-python"><pre>ansible atlanta -m copy -a "src=/etc/hosts dest=/tmp/hosts"</pre> <div class="highlight-python"><pre>ansible atlanta -m copy -a "src=/etc/hosts dest=/tmp/hosts"</pre>
</div> </div>
<p>To use templating, first run the setup module to put the template <p>To use templating, first run the setup module to put the template
variables you would like to use on the remote host. Then use the variables you would like to use on the remote host. Then use the
template module to write the files using those templates.</p> template module to write the files using those templates.</p>
<p>Templates are written in Jinja2 format. Playbooks (covered elsewhere in the <p>Templates are written in <a class="reference external" href="http://jinja.pocoo.org/docs/">Jinja2</a> format.
Playbooks (covered elsewhere in the
documentation) will run the setup module for you, making this even documentation) will run the setup module for you, making this even
simpler:</p> simpler:</p>
<div class="highlight-python"><pre>ansible webservers -m setup -a "favcolor=red ntp_server=192.168.1.1" <div class="highlight-python"><pre>ansible webservers -m setup -a "favcolor=red ntp_server=192.168.1.1"
@ -281,7 +282,7 @@ ansible webservers -m file -a "dest=/srv/foo/b.txt mode=600 owner=mdehaan group=
<p>Ensure a package is not installed:</p> <p>Ensure a package is not installed:</p>
<div class="highlight-python"><pre>ansible-webservers -m yum -a "pkg=acme state=removed"</pre> <div class="highlight-python"><pre>ansible-webservers -m yum -a "pkg=acme state=removed"</pre>
</div> </div>
<p>Currently Ansible only has a module for managing packages with yum. You can install <p>Currently Ansible only has modules for managing packages with yum and apt. You can install
for other packages for now using the command module or (better!) contribute a module for other packages for now using the command module or (better!) contribute a module
for other package managers. Stop by the mailing list for info/details.</p> for other package managers. Stop by the mailing list for info/details.</p>
</div> </div>

View file

@ -259,7 +259,7 @@ $ sudo rpm -Uvh ~/rpmbuild/RPMS/noarch/ansible-*.noarch.rpm</pre>
</div> </div>
<p>Note that if you are tracking the upstream source (i.e. git), the RPM revision will not be <p>Note that if you are tracking the upstream source (i.e. git), the RPM revision will not be
bumped with every source code change. To get around this, you can use bumped with every source code change. To get around this, you can use
rpm <cite>-Uvh</cite> with <cite>&#8211;force</cite> when RPM tells you the package is still at the <tt class="docutils literal"><span class="pre">rpm</span> <span class="pre">-Uvh</span></tt> with <tt class="docutils literal"><span class="pre">--force</span></tt> when RPM tells you the package is still at the
same version. This is perfectly safe to do.</p> same version. This is perfectly safe to do.</p>
</div> </div>
<div class="section" id="debian-gentoo-arch-others"> <div class="section" id="debian-gentoo-arch-others">

View file

@ -207,8 +207,7 @@ server and daemonless, scaling potential is unlimited, and no resources are wast
</div> </div>
<div class="section" id="deployment-and-configuration-unified"> <div class="section" id="deployment-and-configuration-unified">
<h1>Deployment and Configuration, Unified<a class="headerlink" href="#deployment-and-configuration-unified" title="Permalink to this headline"></a></h1> <h1>Deployment and Configuration, Unified<a class="headerlink" href="#deployment-and-configuration-unified" title="Permalink to this headline"></a></h1>
<p>Other deployment (compared to config) oriented frameworks similarly cover deployment well but lack a strongly defined resource model and devolve into glorified remote scripts. Ansible playbooks &#8211; having been designed with this problem in mind &#8211; are good at both deployment &amp; idempotent configuration, meaning you don&#8217;t have to spread your infrastructure management out between different tools (Puppet+Capistrano, Chef+Fabric, etc), and performing ordered steps between different classes of machines is no problem, yet our modules affect system state only when required &#8211; while avoiding the problem of fragile scripting that assumes certain starting <p>Other deployment (compared to config) oriented frameworks similarly cover deployment well but lack a strongly defined resource model and devolve into glorified remote scripts. Ansible playbooks &#8211; having been designed with this problem in mind &#8211; are good at both deployment &amp; idempotent configuration, meaning you don&#8217;t have to spread your infrastructure management out between different tools (Puppet+Capistrano, Chef+Fabric, etc). Performing ordered steps between different classes of machines is no problem, yet our modules affect system state only when required &#8211; while avoiding the problem of fragile scripting that assumes certain starting or ending states.</p>
or ending states.</p>
<p>Ansible is also unique in other ways. Extending ansible does not require programming in any particular language &#8211; you can write <a class="reference internal" href="modules.html"><em>Ansible Modules</em></a> as idempotent scripts or programs that return simple JSON. Ansible is also pragmatic, so when you need to, it&#8217;s also trivially easy to just execute useful shell commands.</p> <p>Ansible is also unique in other ways. Extending ansible does not require programming in any particular language &#8211; you can write <a class="reference internal" href="modules.html"><em>Ansible Modules</em></a> as idempotent scripts or programs that return simple JSON. Ansible is also pragmatic, so when you need to, it&#8217;s also trivially easy to just execute useful shell commands.</p>
<p>Why use Ansible versus other configuration management tools? (Puppet, Chef, etc?) Ansible will have far <p>Why use Ansible versus other configuration management tools? (Puppet, Chef, etc?) Ansible will have far
less code, it will be (by extension) more correct, and it will be the less code, it will be (by extension) more correct, and it will be the
@ -345,7 +344,7 @@ Email: <input type=text name=email>&nbsp;&nbsp;<input type=submit name="sub" val
<li class="toctree-l2"><a class="reference internal" href="playbooks.html#power-tricks">Power Tricks</a><ul> <li class="toctree-l2"><a class="reference internal" href="playbooks.html#power-tricks">Power Tricks</a><ul>
<li class="toctree-l3"><a class="reference internal" href="playbooks.html#local-playbooks">Local Playbooks</a></li> <li class="toctree-l3"><a class="reference internal" href="playbooks.html#local-playbooks">Local Playbooks</a></li>
<li class="toctree-l3"><a class="reference internal" href="playbooks.html#variables-from-other-hosts">Variables From Other Hosts</a></li> <li class="toctree-l3"><a class="reference internal" href="playbooks.html#variables-from-other-hosts">Variables From Other Hosts</a></li>
<li class="toctree-l3"><a class="reference internal" href="playbooks.html#external-variables-and-prompted-or-sensitive-data">External Variables And Prompted or Sensitive Data</a></li> <li class="toctree-l3"><a class="reference internal" href="playbooks.html#external-variables-and-prompted-or-sensitive-data">External Variables and Prompted or Sensitive Data</a></li>
<li class="toctree-l3"><a class="reference internal" href="playbooks.html#conditional-execution">Conditional Execution</a></li> <li class="toctree-l3"><a class="reference internal" href="playbooks.html#conditional-execution">Conditional Execution</a></li>
<li class="toctree-l3"><a class="reference internal" href="playbooks.html#conditional-imports">Conditional Imports</a></li> <li class="toctree-l3"><a class="reference internal" href="playbooks.html#conditional-imports">Conditional Imports</a></li>
<li class="toctree-l3"><a class="reference internal" href="playbooks.html#include-files-and-reuse">Include Files And Reuse</a></li> <li class="toctree-l3"><a class="reference internal" href="playbooks.html#include-files-and-reuse">Include Files And Reuse</a></li>
@ -412,7 +411,7 @@ internet infrastructure, finance, chip design, and more. Michael also
helped co-author <a class="reference external" href="http://fedorahosted.org/func/">Func</a>, a precursor to Ansible, which is used to helped co-author <a class="reference external" href="http://fedorahosted.org/func/">Func</a>, a precursor to Ansible, which is used to
orchestrate systems in lots of diverse places. He&#8217;s worked on systems orchestrate systems in lots of diverse places. He&#8217;s worked on systems
software for IBM, Motorola, Red Hat&#8217;s Emerging Technologies Group, software for IBM, Motorola, Red Hat&#8217;s Emerging Technologies Group,
Puppet Labs, and is now with <a class="reference external" href="http://rpath.com">rPath</a> Reach Michael by email <a class="reference external" href="mailto:michael&#46;dehaan&#37;&#52;&#48;gmail&#46;com">here</a>.</p> Puppet Labs, and is now with <a class="reference external" href="http://rpath.com">rPath</a>. Reach Michael by email <a class="reference external" href="mailto:michael&#46;dehaan&#37;&#52;&#48;gmail&#46;com">here</a>.</p>
</div> </div>

View file

@ -186,7 +186,7 @@ s.parentNode.insertBefore(ga, s);
<p>Ansible modules are reusable units of magic that can be used by the Ansible API, <p>Ansible modules are reusable units of magic that can be used by the Ansible API,
or by the <cite>ansible</cite> or <cite>ansible-playbook</cite> programs.</p> or by the <cite>ansible</cite> or <cite>ansible-playbook</cite> programs.</p>
<p>Modules can be written in any language and are found in the path specified <p>Modules can be written in any language and are found in the path specified
by <cite>ANSIBLE_LIBRARY_PATH</cite> or the <cite>&#8211;module-path</cite> command line option.</p> by <cite>ANSIBLE_LIBRARY_PATH</cite> or the <tt class="docutils literal"><span class="pre">--module-path</span></tt> command line option.</p>
<div class="section" id="tutorial"> <div class="section" id="tutorial">
<h2>Tutorial<a class="headerlink" href="#tutorial" title="Permalink to this headline"></a></h2> <h2>Tutorial<a class="headerlink" href="#tutorial" title="Permalink to this headline"></a></h2>
<p>Let&#8217;s build a module to get and set the system time. For starters, let&#8217;s build <p>Let&#8217;s build a module to get and set the system time. For starters, let&#8217;s build
@ -226,7 +226,7 @@ chmod +x ansible/hacking/test-module</pre>
<div class="highlight-python"><div class="highlight"><pre><span class="p">{</span><span class="s">u&#39;time&#39;</span><span class="p">:</span> <span class="s">u&#39;2012-03-14 22:13:48.539183&#39;</span><span class="p">}</span> <div class="highlight-python"><div class="highlight"><pre><span class="p">{</span><span class="s">u&#39;time&#39;</span><span class="p">:</span> <span class="s">u&#39;2012-03-14 22:13:48.539183&#39;</span><span class="p">}</span>
</pre></div> </pre></div>
</div> </div>
<p>If you did not, you might have a typo in your module, so recheck it and try again</p> <p>If you did not, you might have a typo in your module, so recheck it and try again.</p>
</div> </div>
<div class="section" id="reading-input"> <div class="section" id="reading-input">
<h2>Reading Input<a class="headerlink" href="#reading-input" title="Permalink to this headline"></a></h2> <h2>Reading Input<a class="headerlink" href="#reading-input" title="Permalink to this headline"></a></h2>
@ -240,7 +240,7 @@ Here we&#8217;ll do some basic parsing to treat the input as key=value.</p>
</div> </div>
<p>If no time parameter is set, we&#8217;ll just leave the time as is and return the current time.</p> <p>If no time parameter is set, we&#8217;ll just leave the time as is and return the current time.</p>
<p>Let&#8217;s look at the code. Read the comments as we&#8217;ll explain as we go. Note that this <p>Let&#8217;s look at the code. Read the comments as we&#8217;ll explain as we go. Note that this
highly verbose because it&#8217;s intended as an educational example. You can write modules is highly verbose because it&#8217;s intended as an educational example. You can write modules
a lot shorter than this:</p> a lot shorter than this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span> <div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
@ -349,10 +349,12 @@ json isn&#8217;t in the Python standard library until 2.5.:</p>
</div> </div>
<p>Because the output is supposed to be valid JSON. Except that&#8217;s not quite true, <p>Because the output is supposed to be valid JSON. Except that&#8217;s not quite true,
but we&#8217;ll get to that later.</p> but we&#8217;ll get to that later.</p>
<p>Further, modules must not output anything on stderr, even if the JSON returned <p>Modules must not output anything on standard error, because the system will merge
out stdout is valid. This is due to the internals of our SSH library, more or less.</p> standard out with standard error and prevent the JSON from parsing. Capturing standard
error and returning it as a variable in the JSON on standard out is fine, and is, in fact,
how the command module is implemented.</p>
<p>If a module returns stderr or otherwise fails to produce valid JSON, the actual output <p>If a module returns stderr or otherwise fails to produce valid JSON, the actual output
will still be shown in Ansible, however, but the command will not succeed.</p> will still be shown in Ansible, but the command will not succeed.</p>
<p>Always use the hacking/test-module script when developing modules and it will warn <p>Always use the hacking/test-module script when developing modules and it will warn
you about these kind of things.</p> you about these kind of things.</p>
</div> </div>
@ -361,7 +363,7 @@ you about these kind of things.</p>
<p>As a reminder from the example code above, here are some basic conventions <p>As a reminder from the example code above, here are some basic conventions
and guidelines:</p> and guidelines:</p>
<ul class="simple"> <ul class="simple">
<li>Include a minimum of dependencies if possible. If there are dependencies, document them at the top of the module file</li> <li>Include a minimum of dependencies if possible. If there are dependencies, document them at the top of the module file.</li>
<li>Modules must be self contained in one file to be auto-transferred by ansible</li> <li>Modules must be self contained in one file to be auto-transferred by ansible</li>
<li>If packaging modules in an RPM, they only need to be installed on the control machine and should be dropped into /usr/share/ansible. This is entirely optional.</li> <li>If packaging modules in an RPM, they only need to be installed on the control machine and should be dropped into /usr/share/ansible. This is entirely optional.</li>
<li>Modules should return JSON or key=value results all on one line. JSON is best if you can do JSON. All return types must be hashes (dictionaries) although they can be nested.</li> <li>Modules should return JSON or key=value results all on one line. JSON is best if you can do JSON. All return types must be hashes (dictionaries) although they can be nested.</li>

View file

@ -214,7 +214,7 @@ of the command you want to run.</p>
<p>All modules technically return JSON format data, though if you are using the <p>All modules technically return JSON format data, though if you are using the
command line or playbooks, you don&#8217;t really need to know much about command line or playbooks, you don&#8217;t really need to know much about
that. If you&#8217;re writing your own module, you care, and this means you do that. If you&#8217;re writing your own module, you care, and this means you do
not have to write modules in any particular language &#8211; you get tho choose.</p> not have to write modules in any particular language &#8211; you get to choose.</p>
<p>Most modules other than command are <cite>idempotent</cite>, meaning they will seek <p>Most modules other than command are <cite>idempotent</cite>, meaning they will seek
to avoid changes to the system unless a change needs to be made. When using Ansible to avoid changes to the system unless a change needs to be made. When using Ansible
playbooks, these modules can trigger &#8216;change events&#8217;. Unless otherwise playbooks, these modules can trigger &#8216;change events&#8217;. Unless otherwise
@ -233,7 +233,7 @@ noted, any given module does support change hooks.</p>
</ul> </ul>
<p><em>update-cache</em>:</p> <p><em>update-cache</em>:</p>
<ul class="simple"> <ul class="simple">
<li>Whether apt cache must be updated prior operation. Optional, and can be <li>Whether the apt cache must be updated prior to operation. Optional, and can be
&#8216;yes&#8217;, or &#8216;no&#8217;. The default is &#8216;no&#8217;. This can be done as the part of a &#8216;yes&#8217;, or &#8216;no&#8217;. The default is &#8216;no&#8217;. This can be done as the part of a
package operation or as a seperate step.</li> package operation or as a seperate step.</li>
</ul> </ul>
@ -269,7 +269,7 @@ operations like &#8220;&lt;&#8221;, &#8220;&gt;&#8221;, &#8220;|&#8221;, and &#8
paths to commands must be fully qualified.</p> paths to commands must be fully qualified.</p>
<p>This module does not support change hooks and returns the return code <p>This module does not support change hooks and returns the return code
from the program as well as timing information about how long the from the program as well as timing information about how long the
command was running for.</p> command was running.</p>
<p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p> <p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p>
<div class="highlight-python"><pre>command /sbin/shutdown -t now</pre> <div class="highlight-python"><pre>command /sbin/shutdown -t now</pre>
</div> </div>
@ -334,7 +334,7 @@ All parameters available to the file module are also available when running the
<cite>template</cite> modules.</p> <cite>template</cite> modules.</p>
<p><em>dest</em>:</p> <p><em>dest</em>:</p>
<ul class="simple"> <ul class="simple">
<li>absolute path to a file on the filesystem.</li> <li>alias for &#8216;path&#8217;. Sets an absolute path to a file on the filesystem when used with &#8216;state=file&#8217;. When used with &#8216;state=link&#8217;, sets the destination to create a symbolic link defined by &#8216;src&#8217; key.</li>
</ul> </ul>
<p><em>state</em>:</p> <p><em>state</em>:</p>
<ul class="simple"> <ul class="simple">
@ -346,7 +346,7 @@ All parameters available to the file module are also available when running the
</ul> </ul>
<p><em>owner</em>:</p> <p><em>owner</em>:</p>
<ul class="simple"> <ul class="simple">
<li>name of user that should own the file or directory, as would be given to <cite>chown</cite>.</li> <li>name of user that should own the file or directory, as would be given to <cite>chown</cite></li>
</ul> </ul>
<p><em>group</em>:</p> <p><em>group</em>:</p>
<ul class="simple"> <ul class="simple">
@ -356,10 +356,6 @@ All parameters available to the file module are also available when running the
<ul class="simple"> <ul class="simple">
<li>path of the file to link to (applies only to &#8216;link&#8217; state)</li> <li>path of the file to link to (applies only to &#8216;link&#8217; state)</li>
</ul> </ul>
<p><em>dest</em>:</p>
<ul class="simple">
<li>location where the symlink will be created for &#8216;link&#8217; state, also an alias for &#8216;path&#8217;.</li>
</ul>
<p><em>seuser</em>:</p> <p><em>seuser</em>:</p>
<ul class="simple"> <ul class="simple">
<li>&#8216;user&#8217; part of SELinux file context. Will default to what is provided by system policy, if available. Only used on systems with SELinux present. If you specify &#8216;_default&#8217;, it will use the &#8216;user&#8217; portion of default context from the policy if available.</li> <li>&#8216;user&#8217; part of SELinux file context. Will default to what is provided by system policy, if available. Only used on systems with SELinux present. If you specify &#8216;_default&#8217;, it will use the &#8216;user&#8217; portion of default context from the policy if available.</li>
@ -378,7 +374,7 @@ All parameters available to the file module are also available when running the
</ul> </ul>
<p><em>context</em>:</p> <p><em>context</em>:</p>
<ul class="simple"> <ul class="simple">
<li>accepts only &#8216;default&#8217; as value. This will restore a file&#8217;s selinux context to the default context in the policy. Does nothing if no default is available.</li> <li>accepts only &#8216;default&#8217; as value. This will restore a file&#8217;s selinux context to the default context in the policy. Does nothing if no default is available. Only used on hosts with SELinux present.</li>
</ul> </ul>
<p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p> <p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p>
<div class="highlight-python"><pre>file path=/etc/foo.conf owner=foo group=foo mode=0644 <div class="highlight-python"><pre>file path=/etc/foo.conf owner=foo group=foo mode=0644
@ -473,7 +469,7 @@ Call this once before using the <a class="reference internal" href="#template"><
will execute this module automatically as the first step in each play will execute this module automatically as the first step in each play
using the variables section, so it is unnecessary to make explicit using the variables section, so it is unnecessary to make explicit
calls to setup within a playbook.</p> calls to setup within a playbook.</p>
<p>Ansible provides may &#8216;facts&#8217; about the system, automatically.</p> <p>Ansible provides many &#8216;facts&#8217; about the system, automatically.</p>
<p>Some of the variables that are supplied are listed below. These in particular <p>Some of the variables that are supplied are listed below. These in particular
are from a VMWare Fusion 4 VM running CentOS 6.2:</p> are from a VMWare Fusion 4 VM running CentOS 6.2:</p>
<div class="highlight-python"><pre>"ansible_architecture": "x86_64", <div class="highlight-python"><pre>"ansible_architecture": "x86_64",
@ -543,15 +539,13 @@ are from a VMWare Fusion 4 VM running CentOS 6.2:</p>
also be snapshotted into the JSON file for usage in templating. These also be snapshotted into the JSON file for usage in templating. These
variables are prefixed with <tt class="docutils literal"><span class="pre">facter_</span></tt> and <tt class="docutils literal"><span class="pre">ohai_</span></tt> so it&#8217;s easy to variables are prefixed with <tt class="docutils literal"><span class="pre">facter_</span></tt> and <tt class="docutils literal"><span class="pre">ohai_</span></tt> so it&#8217;s easy to
tell their source.</p> tell their source.</p>
<p>All variables are bubbled up to the caller. Using the ansible facts and chosing <p>All variables are bubbled up to the caller. Using the ansible facts and choosing
to not install facter and ohai means you can avoid ruby-dependencies to not install facter and ohai means you can avoid ruby-dependencies
on your remote systems.</p> on your remote systems.</p>
<p><em>anything</em>:</p> <p><em>variablename</em>:</p>
<blockquote> <ul class="simple">
<div><ul class="simple"> <li>Arbitrary variable names, which must be a mix of alphanumeric characters and underscores, can also be defined. Setting a variable creates a <tt class="docutils literal"><span class="pre">key=value</span></tt> pair in the JSON file for use in templating.</li>
<li>Any other parameters can be named basically anything, and set a <tt class="docutils literal"><span class="pre">key=value</span></tt> pair in the JSON file for use in templating.</li>
</ul> </ul>
</div></blockquote>
<p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p> <p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p>
<div class="highlight-python"><pre>vars: <div class="highlight-python"><pre>vars:
ntpserver: 'ntp.example.com' ntpserver: 'ntp.example.com'
@ -565,7 +559,7 @@ on your remote systems.</p>
<span id="id11"></span><h2>shell<a class="headerlink" href="#shell" title="Permalink to this headline"></a></h2> <span id="id11"></span><h2>shell<a class="headerlink" href="#shell" title="Permalink to this headline"></a></h2>
<p>The shell module takes the command name followed by a list of <p>The shell module takes the command name followed by a list of
arguments, space delimited. It is almost exactly like the command module arguments, space delimited. It is almost exactly like the command module
but runs the command through the shell rather than directly.</p> but runs the command through the user&#8217;s configured shell on the remote node.</p>
<p>The given command will be executed on all selected nodes.</p> <p>The given command will be executed on all selected nodes.</p>
<p>If you want to execute a command securely and predicably, it may <p>If you want to execute a command securely and predicably, it may
be better to use the &#8216;command&#8217; module instead. Best practices be better to use the &#8216;command&#8217; module instead. Best practices
@ -574,7 +568,7 @@ unless &#8216;shell&#8217; is explicitly required. When running ad-hoc commands
use your best judgement.</p> use your best judgement.</p>
<p>This module does not support change hooks and returns the return code <p>This module does not support change hooks and returns the return code
from the program as well as timing information about how long the from the program as well as timing information about how long the
command was running for.</p> command was running.</p>
<p>Example action from a playbook:</p> <p>Example action from a playbook:</p>
<div class="highlight-python"><pre>shell somescript.sh &gt;&gt; somelog.txt</pre> <div class="highlight-python"><pre>shell somescript.sh &gt;&gt; somelog.txt</pre>
</div> </div>
@ -583,8 +577,8 @@ command was running for.</p>
<span id="id12"></span><h2>template<a class="headerlink" href="#template" title="Permalink to this headline"></a></h2> <span id="id12"></span><h2>template<a class="headerlink" href="#template" title="Permalink to this headline"></a></h2>
<p>Templates a file out to a remote server. Call the <a class="reference internal" href="#setup"><em>setup</em></a> module <p>Templates a file out to a remote server. Call the <a class="reference internal" href="#setup"><em>setup</em></a> module
prior to usage if you are not running from a playbook. In addition to the options prior to usage if you are not running from a playbook. In addition to the options
listed below, the arguments available to the <cite>file</cite> module can also be passed to the copy listed below, the arguments available to the <cite>file</cite> and <cite>copy</cite> modules can also be passed
module.</p> to the template module.</p>
<p><em>src</em>:</p> <p><em>src</em>:</p>
<ul class="simple"> <ul class="simple">
<li>Path of a Jinja2 formatted template on the local server. This can <li>Path of a Jinja2 formatted template on the local server. This can
@ -592,7 +586,7 @@ be a relative or absolute path.</li>
</ul> </ul>
<p><em>dest</em>:</p> <p><em>dest</em>:</p>
<ul class="simple"> <ul class="simple">
<li>Location to render the template on the remote server.</li> <li>Location to render the template on the remote server</li>
</ul> </ul>
<p>This module also returns md5sum information about the resultant file.</p> <p>This module also returns md5sum information about the resultant file.</p>
<p>Example action from a playbook:</p> <p>Example action from a playbook:</p>
@ -616,19 +610,19 @@ be a relative or absolute path.</li>
</ul> </ul>
<p><em>group</em>:</p> <p><em>group</em>:</p>
<ul class="simple"> <ul class="simple">
<li>Optionally sets the user&#8217;s primary group, takes a group name.</li> <li>Optionally sets the user&#8217;s primary group, takes a group name</li>
</ul> </ul>
<p><em>groups</em>:</p> <p><em>groups</em>:</p>
<ul class="simple"> <ul class="simple">
<li>Put the user in the specified groups, takes comma delimited group names.</li> <li>Put the user in the specified groups, takes comma delimited group names</li>
</ul> </ul>
<p><em>append</em>:</p> <p><em>append</em>:</p>
<ul class="simple"> <ul class="simple">
<li>If true, will only add additional groups to the user listed in &#8216;groups&#8217;, rather than making the user only be in those specified groups.</li> <li>If true, will only add additional groups to the user listed in &#8216;groups&#8217;, rather than making the user only be in those specified groups</li>
</ul> </ul>
<p><em>shell</em>:</p> <p><em>shell</em>:</p>
<ul class="simple"> <ul class="simple">
<li>Optionally sets the user&#8217;s shell.</li> <li>Optionally sets the user&#8217;s shell</li>
</ul> </ul>
<p><em>createhome</em>:</p> <p><em>createhome</em>:</p>
<ul class="simple"> <ul class="simple">
@ -644,11 +638,11 @@ be a relative or absolute path.</li>
</ul> </ul>
<p><em>force</em>:</p> <p><em>force</em>:</p>
<ul class="simple"> <ul class="simple">
<li>When used with a state of &#8216;absent&#8217;, the behavior denoted in the &#8216;userdel&#8217; manpage for &#8211;force is also used when removing the user. Value is &#8216;yes&#8217; or &#8216;no&#8217;, default is &#8216;no&#8217;.</li> <li>When used with a state of &#8216;absent&#8217;, the behavior denoted in the &#8216;userdel&#8217; manpage for <tt class="docutils literal"><span class="pre">--force</span></tt> is also used when removing the user. Value is &#8216;yes&#8217; or &#8216;no&#8217;, default is &#8216;no&#8217;.</li>
</ul> </ul>
<p><em>remove</em>:</p> <p><em>remove</em>:</p>
<ul class="simple"> <ul class="simple">
<li>When used with a state of &#8216;absent&#8217;, the behavior denoted in the &#8216;userdel&#8217; manpage for &#8211;remove is also used when removing the user. Value is &#8216;yes&#8217; or &#8216;no&#8217;, default is &#8216;no&#8217;.</li> <li>When used with a state of &#8216;absent&#8217;, the behavior denoted in the &#8216;userdel&#8217; manpage for <tt class="docutils literal"><span class="pre">--remove</span></tt> is also used when removing the user. Value is &#8216;yes&#8217; or &#8216;no&#8217;, default is &#8216;no&#8217;.</li>
</ul> </ul>
<p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p> <p>Example action from Ansible <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>:</p>
<div class="highlight-python"><pre>user name=mdehaan comment=awesome passwd=awWxVV.JvmdHw createhome=yes <div class="highlight-python"><pre>user name=mdehaan comment=awesome passwd=awWxVV.JvmdHw createhome=yes

View file

@ -196,7 +196,7 @@ Ansible&#8217;s inventory file, which defaults to /etc/ansible/hosts.</p>
<span class="n">three</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">com</span> <span class="n">three</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">com</span>
</pre></div> </pre></div>
</div> </div>
<p>The things in brackets are group names, you don&#8217;t have to have them, <p>The things in brackets are group names. You don&#8217;t have to have them,
but they are useful.</p> but they are useful.</p>
<p>If you have hosts that run on non-standard SSH ports you can put the port number <p>If you have hosts that run on non-standard SSH ports you can put the port number
after the hostname with a colon. This requires Ansible 0.3 (integration branch):</p> after the hostname with a colon. This requires Ansible 0.3 (integration branch):</p>
@ -285,7 +285,7 @@ style file with a YAML one.:</p>
vars: vars:
- asdf: 1234</pre> - asdf: 1234</pre>
</div> </div>
<p>Tip: Be sure to start your YAML file with the YAML record designator &#8220;&#8212;&#8221;.</p> <p>Tip: Be sure to start your YAML file with the YAML record designator <tt class="docutils literal"><span class="pre">---</span></tt>.</p>
<p>NOTE: variables specified in playbooks will override variables specified <p>NOTE: variables specified in playbooks will override variables specified
in the host file. Further, if a host is in multiple groups, currently, the in the host file. Further, if a host is in multiple groups, currently, the
variables set by the last loaded group will win over variables set in other variables set by the last loaded group will win over variables set in other

View file

@ -157,7 +157,7 @@ s.parentNode.insertBefore(ga, s);
<li><a class="reference internal" href="#power-tricks">Power Tricks</a><ul> <li><a class="reference internal" href="#power-tricks">Power Tricks</a><ul>
<li><a class="reference internal" href="#local-playbooks">Local Playbooks</a></li> <li><a class="reference internal" href="#local-playbooks">Local Playbooks</a></li>
<li><a class="reference internal" href="#variables-from-other-hosts">Variables From Other Hosts</a></li> <li><a class="reference internal" href="#variables-from-other-hosts">Variables From Other Hosts</a></li>
<li><a class="reference internal" href="#external-variables-and-prompted-or-sensitive-data">External Variables And Prompted or Sensitive Data</a></li> <li><a class="reference internal" href="#external-variables-and-prompted-or-sensitive-data">External Variables and Prompted or Sensitive Data</a></li>
<li><a class="reference internal" href="#conditional-execution">Conditional Execution</a></li> <li><a class="reference internal" href="#conditional-execution">Conditional Execution</a></li>
<li><a class="reference internal" href="#conditional-imports">Conditional Imports</a></li> <li><a class="reference internal" href="#conditional-imports">Conditional Imports</a></li>
<li><a class="reference internal" href="#include-files-and-reuse">Include Files And Reuse</a></li> <li><a class="reference internal" href="#include-files-and-reuse">Include Files And Reuse</a></li>
@ -261,7 +261,7 @@ documentation. The <cite>user</cite> is just the name of the user account:</p>
user: yourname user: yourname
sudo: True</pre> sudo: True</pre>
</div> </div>
<p>If you need to specify a password to sudo, run <cite>ansible-playbook</cite> with <cite>&#8211;ask-sudo-pass</cite> (<cite>-K</cite>). <p>If you need to specify a password to sudo, run <cite>ansible-playbook</cite> with <tt class="docutils literal"><span class="pre">--ask-sudo-pass</span></tt> (<cite>-K</cite>).
If you run a sudo playbook and the playbook seems to hang, it&#8217;s probably stuck at the sudo prompt. If you run a sudo playbook and the playbook seems to hang, it&#8217;s probably stuck at the sudo prompt.
Just <cite>Control-C</cite> to kill it and run it again with <cite>-K</cite>.</p> Just <cite>Control-C</cite> to kill it and run it again with <cite>-K</cite>.</p>
</div> </div>
@ -308,12 +308,12 @@ before moving on to the next task.</p>
playbook. If things fail, simply correct the playbook file and rerun.</p> playbook. If things fail, simply correct the playbook file and rerun.</p>
<p>The goal of each task is to execute a module, with very specific arguments. <p>The goal of each task is to execute a module, with very specific arguments.
Variables, as mentioned above, can be used in arguments to modules.</p> Variables, as mentioned above, can be used in arguments to modules.</p>
<p>Modules other than <cite>command</cite> are &#8216;idempotent&#8217;, meaning if you run them <p>Modules other than <cite>command</cite> and <cite>shell</cite> are &#8216;idempotent&#8217;, meaning if you run them
again, they will make the changes they are told to make to bring the again, they will make the changes they are told to make to bring the
system to the desired state. This makes it very safe to rerun system to the desired state. This makes it very safe to rerun
the same playbook multiple times. They won&#8217;t change things the same playbook multiple times. They won&#8217;t change things
unless they have to change things.</p> unless they have to change things.</p>
<p>Command will actually rerun the same command again, <p>The <cite>command</cite> and <cite>shell</cite> modules will actually rerun the same command again,
which is totally ok if the command is something like which is totally ok if the command is something like
&#8216;chmod&#8217; or &#8216;setsebool&#8217;, etc.</p> &#8216;chmod&#8217; or &#8216;setsebool&#8217;, etc.</p>
<p>Every task must have a name, which is included in the output from <p>Every task must have a name, which is included in the output from
@ -325,9 +325,9 @@ the service module takes key=value arguments:</p>
- name: make sure apache is running - name: make sure apache is running
action: service name=httpd state=running</pre> action: service name=httpd state=running</pre>
</div> </div>
<p>The command module is the one module that just takes a list <p>The <cite>command</cite> and <cite>shell</cite> modules are the one modules that just takes a list
of arguments, and doesn&#8217;t use the key=value form. This makes of arguments, and don&#8217;t use the key=value form. This makes
it work just like you would expect. Simple:</p> them work just like you would expect. Simple:</p>
<div class="highlight-python"><pre>tasks: <div class="highlight-python"><pre>tasks:
- name: disable selinux - name: disable selinux
action: command /sbin/setenforce 0</pre> action: command /sbin/setenforce 0</pre>
@ -335,7 +335,7 @@ it work just like you would expect. Simple:</p>
<p>Variables can be used in action lines. Suppose you defined <p>Variables can be used in action lines. Suppose you defined
a variable called &#8216;vhost&#8217; in the &#8216;vars&#8217; section, you could do this:</p> a variable called &#8216;vhost&#8217; in the &#8216;vars&#8217; section, you could do this:</p>
<div class="highlight-python"><pre>tasks: <div class="highlight-python"><pre>tasks:
- name: make a directory - name: create a virtual host file for $vhost
action: template src=somefile.j2 dest=/etc/httpd/conf.d/$vhost</pre> action: template src=somefile.j2 dest=/etc/httpd/conf.d/$vhost</pre>
</div> </div>
<p>Those same variables are usable in templates, which we&#8217;ll get to later.</p> <p>Those same variables are usable in templates, which we&#8217;ll get to later.</p>
@ -344,7 +344,7 @@ a variable called &#8216;vhost&#8217; in the &#8216;vars&#8217; section, you cou
<div class="section" id="running-operations-on-change"> <div class="section" id="running-operations-on-change">
<h2>Running Operations On Change<a class="headerlink" href="#running-operations-on-change" title="Permalink to this headline"></a></h2> <h2>Running Operations On Change<a class="headerlink" href="#running-operations-on-change" title="Permalink to this headline"></a></h2>
<p>As we&#8217;ve mentioned, nearly all modules are written to be &#8216;idempotent&#8217; and can relay when <p>As we&#8217;ve mentioned, nearly all modules are written to be &#8216;idempotent&#8217; and can relay when
they have affected a change on the remote system. Playbooks recognize this and they have made a change on the remote system. Playbooks recognize this and
have a basic event system that can be used to respond to change.</p> have a basic event system that can be used to respond to change.</p>
<p>These &#8216;notify&#8217; actions are triggered at the end of each &#8216;play&#8217; in a playbook, and <p>These &#8216;notify&#8217; actions are triggered at the end of each &#8216;play&#8217; in a playbook, and
trigger only once each. For instance, multiple resources may indicate trigger only once each. For instance, multiple resources may indicate
@ -406,7 +406,7 @@ within a template or even an action line:</p>
want to reference data from must be included in either the current play or any previous play.</p> want to reference data from must be included in either the current play or any previous play.</p>
</div> </div>
<div class="section" id="external-variables-and-prompted-or-sensitive-data"> <div class="section" id="external-variables-and-prompted-or-sensitive-data">
<h3>External Variables And Prompted or Sensitive Data<a class="headerlink" href="#external-variables-and-prompted-or-sensitive-data" title="Permalink to this headline"></a></h3> <h3>External Variables and Prompted or Sensitive Data<a class="headerlink" href="#external-variables-and-prompted-or-sensitive-data" title="Permalink to this headline"></a></h3>
<p>It&#8217;s a great idea to keep your playbooks under source control, but <p>It&#8217;s a great idea to keep your playbooks under source control, but
you may wish to make the playbook source public while keeping certain you may wish to make the playbook source public while keeping certain
important variables private. Similarly, sometimes you may just important variables private. Similarly, sometimes you may just
@ -492,6 +492,8 @@ but it is easily handled with a minimum of syntax in an Ansible Playbook:</p>
- name: make sure apache is running - name: make sure apache is running
action: service name=$apache state=running</pre> action: service name=$apache state=running</pre>
</div> </div>
<p>Note that a variable (<cite>$facter_operatingsystem</cite>) is being interpolated into the list of
filenames being defined for vars_files.</p>
<p>As a reminder, the various YAML files contain just keys and values:</p> <p>As a reminder, the various YAML files contain just keys and values:</p>
<div class="highlight-python"><pre>--- <div class="highlight-python"><pre>---
# for vars/CentOS.yml # for vars/CentOS.yml
@ -558,7 +560,7 @@ includes. This may be implemented in a later release.</p>
</div> </div>
<p>Includes can also be used in the &#8216;handlers&#8217; section, for instance, if you <p>Includes can also be used in the &#8216;handlers&#8217; section, for instance, if you
want to define how to restart apache, you only have to do that once for all want to define how to restart apache, you only have to do that once for all
of your playbooks. You might make a notifiers.yaml that looked like:</p> of your playbooks. You might make a handlers.yml that looks like:</p>
<div class="highlight-python"><pre>---- <div class="highlight-python"><pre>----
# this might be in a file like handlers/handlers.yml # this might be in a file like handlers/handlers.yml
- name: restart apache - name: restart apache
@ -618,12 +620,18 @@ actually one of the things playbooks were invented to do.</p>
- testuser1 - testuser1
- testuser2</pre> - testuser2</pre>
</div> </div>
<p>The above would be the equivalent of:</p>
<div class="highlight-python"><pre>- name: add user testuser1
action: user name=testuser1 state=present groups=wheel
- name: add user testuser2
action: user name=testuser2 state=present groups=wheel</pre>
</div>
</div> </div>
<div class="section" id="asynchronous-actions-and-polling"> <div class="section" id="asynchronous-actions-and-polling">
<h3>Asynchronous Actions and Polling<a class="headerlink" href="#asynchronous-actions-and-polling" title="Permalink to this headline"></a></h3> <h3>Asynchronous Actions and Polling<a class="headerlink" href="#asynchronous-actions-and-polling" title="Permalink to this headline"></a></h3>
<p>By default tasks in playbooks block, meaning the connections stay open <p>By default tasks in playbooks block, meaning the connections stay open
until the task is done on each node. If executing playbooks with until the task is done on each node. If executing playbooks with
a small parallelism value (aka <cite>&#8211;forks</cite>), you may wish that long a small parallelism value (aka <tt class="docutils literal"><span class="pre">--forks</span></tt>), you may wish that long
running operations can go faster. The easiest way to do this is running operations can go faster. The easiest way to do this is
to kick them off all at once and then poll until they are done.</p> to kick them off all at once and then poll until they are done.</p>
<p>You will also want to use asynchronous mode on very long running <p>You will also want to use asynchronous mode on very long running
@ -665,7 +673,7 @@ commands later in the playbook against those same resources.</p>
</div> </div>
<div class="admonition note"> <div class="admonition note">
<p class="first admonition-title">Note</p> <p class="first admonition-title">Note</p>
<p class="last">Using a higher value for <cite>&#8211;forks</cite> will result in kicking off asynchronous <p class="last">Using a higher value for <tt class="docutils literal"><span class="pre">--forks</span></tt> will result in kicking off asynchronous
tasks even faster. This also increases the efficiency of polling.</p> tasks even faster. This also increases the efficiency of polling.</p>
</div> </div>
</div> </div>

View file

@ -427,9 +427,7 @@ on your remote systems.
*variablename*: *variablename*:
* Arbitrary variable names, which must be a mix of alphanumeric characters and * Arbitrary variable names, which must be a mix of alphanumeric characters and underscores, can also be defined. Setting a variable creates a ``key=value`` pair in the JSON file for use in templating.
underscores, can also be defined. Setting a variable creates a
``key=value`` pair in the JSON file for use in templating.
Example action from Ansible :doc:`playbooks`:: Example action from Ansible :doc:`playbooks`::

File diff suppressed because one or more lines are too long