359 lines
No EOL
17 KiB
HTML
359 lines
No EOL
17 KiB
HTML
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
|
<title>Best Practices — Ansible - SSH-Based Configuration Management & Deployment</title>
|
|
|
|
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
|
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
|
<link rel="stylesheet" href="_static/bootstrap.css" type="text/css" />
|
|
<link rel="stylesheet" href="_static/bootstrap-sphinx.css" type="text/css" />
|
|
|
|
<script type="text/javascript">
|
|
var DOCUMENTATION_OPTIONS = {
|
|
URL_ROOT: '',
|
|
VERSION: '0.01',
|
|
COLLAPSE_INDEX: false,
|
|
FILE_SUFFIX: '.html',
|
|
HAS_SOURCE: false
|
|
};
|
|
</script>
|
|
<script type="text/javascript" src="_static/jquery.js"></script>
|
|
<script type="text/javascript" src="_static/underscore.js"></script>
|
|
<script type="text/javascript" src="_static/doctools.js"></script>
|
|
<script type="text/javascript" src="_static/bootstrap-dropdown.js"></script>
|
|
<script type="text/javascript" src="_static/bootstrap-scrollspy.js"></script>
|
|
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
|
<link rel="top" title="Ansible - SSH-Based Configuration Management & Deployment" href="index.html" />
|
|
<link rel="next" title="API & Integrations" href="api.html" />
|
|
<link rel="prev" title="Advanced Playbooks" href="playbooks2.html" />
|
|
<script type="text/javascript">
|
|
(function () {
|
|
/**
|
|
* Patch TOC list.
|
|
*
|
|
* Will mutate the underlying span to have a correct ul for nav.
|
|
*
|
|
* @param $span: Span containing nested UL's to mutate.
|
|
* @param minLevel: Starting level for nested lists. (1: global, 2: local).
|
|
*/
|
|
var patchToc = function ($span, minLevel) {
|
|
var $tocList = $("<ul/>").attr('class', "dropdown-menu"),
|
|
findA;
|
|
|
|
// Find all a "internal" tags, traversing recursively.
|
|
findA = function ($elem, level) {
|
|
var level = level || 0,
|
|
$items = $elem.find("> li > a.internal, > ul, > li > ul");
|
|
|
|
// Iterate everything in order.
|
|
$items.each(function (index, item) {
|
|
var $item = $(item),
|
|
tag = item.tagName.toLowerCase(),
|
|
pad = 10 + ((level - minLevel) * 10);
|
|
|
|
if (tag === 'a' && level >= minLevel) {
|
|
// Add to existing padding.
|
|
$item.css('padding-left', pad + "px");
|
|
// Add list element.
|
|
$tocList.append($("<li/>").append($item));
|
|
} else if (tag === 'ul') {
|
|
// Recurse.
|
|
findA($item, level + 1);
|
|
}
|
|
});
|
|
};
|
|
|
|
// Start construction and return.
|
|
findA($span);
|
|
|
|
// Wipe out old list and patch in new one.
|
|
return $span.empty("ul").append($tocList);
|
|
};
|
|
|
|
$(document).ready(function () {
|
|
// Patch the global and local TOC's to be bootstrap-compliant.
|
|
patchToc($("span.globaltoc"), 1);
|
|
patchToc($("span.localtoc"), 2);
|
|
|
|
// Activate.
|
|
$('#topbar').dropdown();
|
|
});
|
|
}());
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
|
|
var _gaq = _gaq || [];
|
|
_gaq.push(['_setAccount', 'UA-29861888-1']);
|
|
_gaq.push(['_trackPageview']);
|
|
|
|
(function() {
|
|
var ga = document.createElement('script'); ga.type =
|
|
'text/javascript'; ga.async = true;
|
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' :
|
|
'http://www') + '.google-analytics.com/ga.js';
|
|
var s = document.getElementsByTagName('script')[0];
|
|
s.parentNode.insertBefore(ga, s);
|
|
})();
|
|
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
(function() {
|
|
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
|
|
po.src = 'https://apis.google.com/js/plusone.js';
|
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
|
|
})();
|
|
</script>
|
|
|
|
<script>(function(d, s, id) {
|
|
var js, fjs = d.getElementsByTagName(s)[0];
|
|
if (d.getElementById(id)) return;
|
|
js = d.createElement(s); js.id = id;
|
|
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
|
|
fjs.parentNode.insertBefore(js, fjs);
|
|
}(document, 'script', 'facebook-jssdk'));</script>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="topbar" data-scrollspy="scrollspy" >
|
|
<div class="topbar-inner">
|
|
<div class="container">
|
|
<!-- <a class="brand" href="index.html">Ansible</a> -->
|
|
<ul class="nav">
|
|
|
|
<li class="dropdown" data-dropdown="dropdown">
|
|
<a href="index.html"
|
|
class="dropdown-toggle">Chapter</a>
|
|
<span class="globaltoc"><ul class="current">
|
|
<li class="toctree-l1"><a class="reference internal" href="gettingstarted.html">Getting Started</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="patterns.html">Inventory & Patterns</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="examples.html">Command Line Examples And Next Steps</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="modules.html">Ansible Modules</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="YAMLSyntax.html">YAML Syntax</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="playbooks.html">Playbooks</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="playbooks2.html">Advanced Playbooks</a></li>
|
|
<li class="toctree-l1 current"><a class="current reference internal" href="">Best Practices</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="api.html">API & Integrations</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="moduledev.html">Module Development</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="faq.html">FAQ</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="who_uses_ansible.html">Who Uses Ansible</a></li>
|
|
</ul>
|
|
</span>
|
|
</li>
|
|
<li class="dropdown" data-dropdown="dropdown">
|
|
<a href="#"
|
|
class="dropdown-toggle">Page</a>
|
|
<span class="localtoc"><ul>
|
|
<li><a class="reference internal" href="#">Best Practices</a><ul>
|
|
<li><a class="reference internal" href="#always-mention-state">Always Mention State</a></li>
|
|
<li><a class="reference internal" href="#group-by-roles">Group By Roles</a></li>
|
|
<li><a class="reference internal" href="#directory-organization">Directory Organization</a></li>
|
|
<li><a class="reference internal" href="#bundling-ansible-modules-with-playbooks">Bundling Ansible Modules With Playbooks</a></li>
|
|
<li><a class="reference internal" href="#miscellaneous-tips">Miscellaneous Tips</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</span>
|
|
</li>
|
|
|
|
</ul>
|
|
<ul class="nav secondary-nav">
|
|
|
|
|
|
<form class="pull-left" action="search.html" method="get">
|
|
<input type="text" name="q" placeholder="Search" />
|
|
<input type="hidden" name="check_keywords" value="yes" />
|
|
<input type="hidden" name="area" value="default" />
|
|
</form>
|
|
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<a href="http://github.com/ansible/ansible"><img style="position: absolute; right: 0; border: 0;" src="http://ansible.github.com/github.png" alt="Fork me on GitHub"></a>
|
|
|
|
|
|
<div class="container">
|
|
<a href="http://ansible.github.com"><img src="http://ansible.github.com/ansible-logo.png" alt="Ansible"/></a><br/>
|
|
<br/>
|
|
|
|
<div class="section" id="best-practices">
|
|
<h1><a class="toc-backref" href="#contents">Best Practices</a><a class="headerlink" href="#best-practices" title="Permalink to this headline">¶</a></h1>
|
|
<p>Here are some tips for making the most of Ansible.</p>
|
|
<div class="contents topic" id="contents">
|
|
<p class="topic-title first">Contents</p>
|
|
<ul class="simple">
|
|
<li><a class="reference internal" href="#best-practices" id="id1">Best Practices</a><ul>
|
|
<li><a class="reference internal" href="#always-mention-state" id="id2">Always Mention State</a></li>
|
|
<li><a class="reference internal" href="#group-by-roles" id="id3">Group By Roles</a></li>
|
|
<li><a class="reference internal" href="#directory-organization" id="id4">Directory Organization</a></li>
|
|
<li><a class="reference internal" href="#bundling-ansible-modules-with-playbooks" id="id5">Bundling Ansible Modules With Playbooks</a></li>
|
|
<li><a class="reference internal" href="#miscellaneous-tips" id="id6">Miscellaneous Tips</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="always-mention-state">
|
|
<h2><a class="toc-backref" href="#contents">Always Mention State</a><a class="headerlink" href="#always-mention-state" title="Permalink to this headline">¶</a></h2>
|
|
<p>The ‘state’ parameter is optional to a lot of modules. Whether
|
|
‘state=present’ or ‘state=absent’, it’s always best to leave that
|
|
parameter in your playbooks to make it clear, especially as some
|
|
modules support additional states.</p>
|
|
</div>
|
|
<div class="section" id="group-by-roles">
|
|
<h2><a class="toc-backref" href="#contents">Group By Roles</a><a class="headerlink" href="#group-by-roles" title="Permalink to this headline">¶</a></h2>
|
|
<p>A system can be in multiple groups. See <a class="reference internal" href="patterns.html"><em>Inventory & Patterns</em></a>. Having groups named after things like
|
|
<em>webservers</em> and <em>dbservers</em> is repeated in the examples because it’s a very powerful concept.</p>
|
|
<p>This allows playbooks to target machines based on role, as well as to assign role specific variables
|
|
using the group variable system.</p>
|
|
</div>
|
|
<div class="section" id="directory-organization">
|
|
<h2><a class="toc-backref" href="#contents">Directory Organization</a><a class="headerlink" href="#directory-organization" title="Permalink to this headline">¶</a></h2>
|
|
<p>Playbooks should be organized like this:</p>
|
|
<div class="highlight-python"><pre># root of source control repository
|
|
├── acme/
|
|
│ ├── setup.yml
|
|
│ └── stop.yml
|
|
├── files/
|
|
│ └── some_file_path_foo.conf
|
|
├── handlers/
|
|
│ └── main.yml
|
|
├── tasks/
|
|
│ ├── setup.yml
|
|
│ └── stop.yml
|
|
├── templates/
|
|
│ ├── etc_acme_conf_acme.conf
|
|
│ └── etc_other_conf_other.conf
|
|
├── vars/
|
|
│ └── main.yml
|
|
└── global_vars.yml</pre>
|
|
</div>
|
|
<p>Any directories or files not needed can be omitted. Not all modules
|
|
may require ‘vars’ or ‘files’ sections, though most will require
|
|
‘handlers’, ‘tasks’, and ‘templates’. To review what each of
|
|
these sections do, see <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a> and <a class="reference internal" href="playbooks2.html"><em>Advanced Playbooks</em></a>.</p>
|
|
<p>The acme/setup.yml playbook would be as simple as:</p>
|
|
<div class="highlight-python"><pre>---
|
|
- hosts: webservers
|
|
user: root
|
|
|
|
vars_files:
|
|
- ../global_vars.yml
|
|
- vars/main.yml
|
|
tasks:
|
|
- include: tasks/setup.yml
|
|
handlers:
|
|
- include: handlers/main.yml</pre>
|
|
</div>
|
|
<p>The tasks are individually broken out in ‘acme/tasks/setup.yml’, and handlers, which are common to all task files,
|
|
are contained in ‘acme/handlers/main.yml’. As a reminder, handlers are mostly just used to notify services to restart
|
|
when things change, and these are described in <a class="reference internal" href="playbooks.html"><em>Playbooks</em></a>.</p>
|
|
<p>Including more than one setup file or more than one handlers file is of course legal.</p>
|
|
</div>
|
|
<div class="section" id="bundling-ansible-modules-with-playbooks">
|
|
<h2><a class="toc-backref" href="#contents">Bundling Ansible Modules With Playbooks</a><a class="headerlink" href="#bundling-ansible-modules-with-playbooks" title="Permalink to this headline">¶</a></h2>
|
|
<p class="versionadded">
|
|
<span class="versionmodified">New in version 0.5.</span></p>
|
|
<p>If a playbook has a ”./library” directory relative to it’s YAML file,
|
|
this directory can be used to add ansible modules that will
|
|
automatically be in the ansible module path. This is a great way to
|
|
keep modules that go with a playbook together.</p>
|
|
</div>
|
|
<div class="section" id="miscellaneous-tips">
|
|
<h2><a class="toc-backref" href="#contents">Miscellaneous Tips</a><a class="headerlink" href="#miscellaneous-tips" title="Permalink to this headline">¶</a></h2>
|
|
<p>When you can do something simply, do something simply. Do not reach
|
|
to use every feature of Ansible together, all at once. Use what works
|
|
for you. For example, you should probably not need ‘vars’,
|
|
‘vars_files’, ‘vars_prompt’ and ‘–extra-vars’ all at once,
|
|
while also using an external inventory file.</p>
|
|
<p>Optimize for readability. Whitespace between sections of YAML
|
|
documents and in between tasks is strongly encouraged, as is usage of
|
|
YAML comments, which start with ‘#’. It is also useful to comment
|
|
at the top of each file the purpose of the individual file and the
|
|
author, including email address.</p>
|
|
<p>It is possible to leave off the ‘name’ for a given task, though it
|
|
is recommended to provide a descriptive comment about why something is
|
|
being done instead.</p>
|
|
<p>Use version control. Keep your playbooks and inventory file in git
|
|
(or another version control system), and commit when you make changes
|
|
to them. This way you have an audit trail describing when and why you
|
|
changed the rules automating your infrastructure.</p>
|
|
<p>Resist the urge to write the same playbooks and configuration files
|
|
for heterogeneous distributions. While lots of software packages
|
|
claim to make this easy on you, the configuration files are often
|
|
quite different, to the point where it would be easier to treat them
|
|
as different playbooks. This is why, for example, Ansible has a
|
|
separate <a class="reference internal" href="modules.html#yum"><em>yum</em></a> and <a class="reference internal" href="modules.html#apt"><em>apt</em></a> module. Yum and apt have different
|
|
capabilities, and we don’t want to code for the least common
|
|
denominator.</p>
|
|
<p>Use variables for user tunable settings versus having constants in the
|
|
tasks file or templates, so that it is easy to reconfigure a playbook.
|
|
Think about this as exposing the knobs to things you would like to
|
|
tweak.</p>
|
|
<p>Since a system can be in more than one group, if you have multiple
|
|
datacenters or sites, consider putting systems into groups by role,
|
|
but also different groups by geography. This allows you to assign
|
|
different variables to different geographies.</p>
|
|
<div class="admonition-see-also admonition seealso">
|
|
<p class="first admonition-title">See also</p>
|
|
<dl class="last docutils">
|
|
<dt><a class="reference internal" href="YAMLSyntax.html"><em>YAML Syntax</em></a></dt>
|
|
<dd>Learn about YAML syntax</dd>
|
|
<dt><a class="reference internal" href="playbooks.html"><em>Playbooks</em></a></dt>
|
|
<dd>Review the basic playbook features</dd>
|
|
<dt><a class="reference internal" href="modules.html"><em>Ansible Modules</em></a></dt>
|
|
<dd>Learn about available modules</dd>
|
|
<dt><a class="reference internal" href="moduledev.html"><em>Module Development</em></a></dt>
|
|
<dd>Learn how to extend Ansible by writing your own modules</dd>
|
|
<dt><a class="reference internal" href="patterns.html"><em>Inventory & Patterns</em></a></dt>
|
|
<dd>Learn about how to select hosts</dd>
|
|
<dt><a class="reference external" href="https://github.com/ansible/ansible/tree/devel/examples/playbooks">Github examples directory</a></dt>
|
|
<dd>Complete playbook files from the github project source</dd>
|
|
<dt><a class="reference external" href="http://groups.google.com/group/ansible-project">Mailing List</a></dt>
|
|
<dd>Questions? Help? Ideas? Stop by the list on Google Groups</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<br/>
|
|
</div>
|
|
<footer class="footer">
|
|
|
|
<div class="container">
|
|
<div id="fb-root"></div>
|
|
<p>
|
|
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
|
<input type="hidden" name="cmd" value="_donations">
|
|
<input type="hidden" name="business" value="michael.dehaan@gmail.com">
|
|
<input type="hidden" name="lc" value="US">
|
|
<input type="hidden" name="item_name" value="Ansible">
|
|
<input type="hidden" name="no_note" value="0">
|
|
<input type="hidden" name="currency_code" value="USD">
|
|
<input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_LG.gif:NonHostedGuest">
|
|
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
|
|
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
|
|
</form>
|
|
</p>
|
|
<p>
|
|
<a href="https://twitter.com/share" class="twitter-share-button" data-text="ansible.github.com">Share On Twitter</a>
|
|
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
|
<g:plusone annotation="inline"></g:plusone>
|
|
<div class="fb-like" data-href="http://ansible.github.com" data-send="true" data-width="450" data-show-faces="false"></div>
|
|
</p>
|
|
<p>
|
|
© Copyright 2012 Michael DeHaan.<br/>
|
|
Last updated on Aug 30, 2012.<br/>
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
</body>
|
|
</html> |