< !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 > FAQ — 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 = "Who Uses Ansible" href = "who_uses_ansible.html" / >
< link rel = "prev" title = "Module Development" href = "moduledev.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 > ( f u n c t i o n ( d , s , i d ) {
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< / 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" > < a class = "reference internal" href = "bestpractices.html" > 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 current" > < a class = "current reference internal" href = "" > 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 = "#" > FAQ< / a > < ul >
< li > < a class = "reference internal" href = "#what-inspired-ansible" > What inspired Ansible?< / a > < / li >
< li > < a class = "reference internal" href = "#comparisons" > Comparisons< / a > < ul >
< li > < a class = "reference internal" href = "#vs-func" > vs Func?< / a > < / li >
< li > < a class = "reference internal" href = "#vs-puppet" > vs Puppet?< / a > < / li >
< li > < a class = "reference internal" href = "#vs-chef" > vs Chef?< / a > < / li >
< li > < a class = "reference internal" href = "#vs-capistrano-fabric" > vs Capistrano/Fabric?< / a > < / li >
< / ul >
< / li >
< li > < a class = "reference internal" href = "#other-questions" > Other Questions< / a > < ul >
< li > < a class = "reference internal" href = "#what-is-ansible-s-approach-to-security" > What is Ansible’ s approach to security?< / a > < / li >
< li > < a class = "reference internal" href = "#how-does-ansible-scale" > How does Ansible scale?< / a > < / li >
< li > < a class = "reference internal" href = "#are-transports-other-than-ssh-supported" > Are transports other than SSH supported?< / a > < / li >
< li > < a class = "reference internal" href = "#what-are-some-ideal-uses-for-ansible" > What are some ideal uses for Ansible?< / a > < / li >
< / ul >
< / 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 = "faq" >
< h1 > FAQ< a class = "headerlink" href = "#faq" title = "Permalink to this headline" > ¶< / a > < / h1 >
< div class = "section" id = "what-inspired-ansible" >
< h2 > What inspired Ansible?< a class = "headerlink" href = "#what-inspired-ansible" title = "Permalink to this headline" > ¶< / a > < / h2 >
< p > Back when I worked for Red Hat and working on < a class = "reference external" href = "http://cobbler.github.com/" > Cobbler< / a > , several of us identified a gap between
provisioning (Cobbler) and configuration management solutions (cfengine, Puppet, etc).
There was a need for a way to do ad-hoc tasks efficiently, and various parallel
SSH scripts were not API based enough for us. So we (Adrian Likins, Seth Vidal, and I)
created < a class = "reference external" href = "http://fedorahosted.org/func" > Func< / a > – a secure distributed command framework.< / p >
< p > I always wanted to have a configuration management system built on Func, but never
built it due to needing to spend time on Cobbler and other projects.
In the meantime, a John Eckersberg developed Taboot,
a deployment framework of sorts that sat on top of Func, using a YAML syntax very
much like what Ansible now has in < a class = "reference internal" href = "playbooks.html" > < em > Playbooks< / em > < / a > .< / p >
< p > After trying to get Func running again recently at a new company, I got tired
of some SSL and DNS issues and decided to create something a bit simpler, taking
all of the good ideas from Func, and merging them with experience I learned from
working at Puppet Labs. I wanted something that was easy to pick up and was installable
without any bootstrapping, and didn’ t suffer from the “ I don’ t want to learn X” mentality
that often impacted adoption of tools like Puppet and Chef among certain ops teams.< / p >
< p > I also spent some time working with a couple of sites that needed to do large webapp deployments,
and noticed how complex various configuration management and deployment tools were to these
companies, compared with what they actually needed. Release processes were too complex
and needed something simple to straighten them out – but I really didn’ t want to train
all the dev(ops) on Puppet or Chef, and they really didn’ t want to learn them either.< / p >
< p > I kept thinking, is there a reason for these programs to be so large and complicated?
Well, systems management is a little complicated, but no. Not really.< / p >
< p > Can I build something that a sysadmin can
figure out in 15 minutes and get going, and then extend in any language he knows?
That’ s how Ansible was born. It sheds ‘ best practices’ for ‘ you know your infrastructure
best’ , and distills all of the ideas behind all of these other tools to the core.< / p >
< p > Not only is Ansible very simple and easy to learn/extend, it’ s configuration management, deployment, and ad-hoc tasks all in one app. And I think that makes it pretty powerful. It hasn’ t really been done before.< / p >
< p > I’ d like to know what you think of it. Hop by the mailing list and say hi.< / p >
< / div >
< div class = "section" id = "comparisons" >
< h2 > Comparisons< a class = "headerlink" href = "#comparisons" title = "Permalink to this headline" > ¶< / a > < / h2 >
< div class = "section" id = "vs-func" >
< h3 > vs Func?< a class = "headerlink" href = "#vs-func" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > Ansible uses SSH by default instead of SSL and custom daemons, and requires
no extra software to run on managed machines. You can also write modules
in any language as long as they return JSON. Ansible’ s API, of course, is
heavily inspired by Func. Ansible also adds
a configuration management and multinode orchestration layer (< a class = "reference internal" href = "playbooks.html" > < em > Playbooks< / em > < / a > )
that Func didn’ t have.< / p >
< / div >
< div class = "section" id = "vs-puppet" >
< h3 > vs Puppet?< a class = "headerlink" href = "#vs-puppet" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > First off, Ansible wouldn’ t have happened without Puppet. Puppet took configuration
management ideas from cfengine and made them sane. However, I still think they can
be much simpler.< / p >
< p > Ansible playbooks ARE a complete configuration management system. Unlike Puppet, playbooks
are implicitly ordered (more like Chef), but still retain the ability to signal
notification events (like Puppet). This is kind of a ‘ best of both worlds’ thing.< / p >
< p > There is no central server subject to thundering herd problems, and Ansible is
also designed with multi-node deployment in mind from day-one – something that is difficult
for Puppet because of the pull architecture. Ansible is push based,
so you can do things in an ordered fashion, addressing batches of servers
at one time, and you do not have to contend with the dependency graph. It’ s also extensible in any language
and the source is designed so that you don’ t have to be an expert programmer to submit a patch.< / p >
< p > Ansible’ s resources are heavily inspired by Puppet, with the “ state” keyword being a more or less
direct port of “ ensure” from Puppet. Unlike Puppet, Ansible can be extended in any language,
even bash ... just return some output in JSON format. You don’ t need to know Ruby.< / p >
< p > Unlike Puppet, hosts are taken out of playbooks when they have a failure. It encourages
‘ fail first’ , so you can correct the error, instead of configuring as much of the system
as it can. A system shouldn’ t be half correct, especially if we’ re planning on configuring
other systems that depend on that system.< / p >
< p > Ansible also has a VERY short learning curve – but it also has less language constructs and
does not create its own programming language. What constructs Ansible does have should be enough to cover 80% or so of the cases of most Puppet users, and it should scale equally well (not having a server is
almost like cheating).< / p >
< p > Ansible does support gathering variables from ‘ facter’ , if installed, and Ansible templates
in jinja2 in a way just like Puppet does with erb. Ansible also has it’ s own facts though,
so usage of facter is not required to get variables about the system.< / p >
< / div >
< div class = "section" id = "vs-chef" >
< h3 > vs Chef?< a class = "headerlink" href = "#vs-chef" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > Much in the ways Ansible is different from Puppet. Chef is notoriously hard
to set up on the server, and requires that you know how to program in Ruby to
use the language. As such, it seems to have a pretty good following mainly
among Rails coders.< / p >
< p > Like Chef (and unlike Puppet), Ansible executes configuration tasks in the order
given, rather than having to manually specify a dependency graph. Ansible extends
this though, by allowing triggered notifiers, so Apache can, be restarted if needed,
only once, at the end of a configuration run.< / p >
< p > Unlike Chef, Ansible’ s playbooks are not a programming language. This means
that you can parse Ansible’ s playbooks and treat the instructions as data. It also
means working on your infrastructure is not a development task and testing is easier.< / p >
< p > Ansible can be used regardless of your programming language experience. Both
Chef and Puppet are around 60k+ lines of code, while Ansible is a much simpler
program. I believe this strongly leads to more reliable software and a richer
open source community – the code is kept simple so it is easy for anyone to
submit a patch or module.< / p >
< p > Ansible does support gathering variables from ‘ ohai’ , if installed. Ansible also
has it’ s own facts so you do not need to use ohai unless you want to.< / p >
< / div >
< div class = "section" id = "vs-capistrano-fabric" >
< h3 > vs Capistrano/Fabric?< a class = "headerlink" href = "#vs-capistrano-fabric" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > These tools aren’ t really well suited to doing idempotent configuration and are
typically about pushing software out for web deployment and automating steps.< / p >
< p > Meanwhile Ansible is designed for other types of configuration management, and contains some
advanced scaling features.< / p >
< p > The ansible playbook syntax is documented within one HTML page and also has a MUCH lower learning curve.
And because Ansible is designed for more than pushing webapps, it’ s more generally
useful for sysadmins (not just web developers), and can also be used for firing off ad-hoc tasks.< / p >
< / div >
< / div >
< div class = "section" id = "other-questions" >
< h2 > Other Questions< a class = "headerlink" href = "#other-questions" title = "Permalink to this headline" > ¶< / a > < / h2 >
< div class = "section" id = "what-is-ansible-s-approach-to-security" >
< h3 > What is Ansible’ s approach to security?< a class = "headerlink" href = "#what-is-ansible-s-approach-to-security" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > Ansible aims to not develop custom daemon or PKI code but rely heavily on OpenSSH, which is extremely well
peer reviewed and the most widely used security subsystem in the industry. As a result, Ansible
has a lower attack surface than any configuration management tool featuring daemons that run
as root, and you do not have to worry about network security vulnerabilities in the tool itself.< / p >
< p > If your central server is taken over (or even logged into by a malicious employee),
provided you were using SSH-agent and encrypted keys (and/or sudo with a password),
your keys are still locked and no one can take control of your nodes.< / p >
< p > Compared with something like Chef/Puppet/other, compromised manifests would lead
to a loss of the whole network, with your network turning into an easily controllable
botnet. Further by not running daemon infrastructure, you have more
free RAM and compute resources, which should be relevant to users wanting to maximize their
computing investments.< / p >
< / div >
< div class = "section" id = "how-does-ansible-scale" >
< h3 > How does Ansible scale?< a class = "headerlink" href = "#how-does-ansible-scale" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > Whether in single-execution mode or using ansible playbooks, ansible can
run multiple commands in seperate parallel forks, thanks to the magic behind
Python’ s multiprocessing module.< / p >
< p > You can decide if you want to try to manage 5 hosts at a time, or 50 at a time.
It’ s up to you and how much power you can throw at it and how fast you want
to go.< / p >
< p > There are no daemons so it’ s entirely up to you. When you are aren’ t using
Ansible, it is not consuming any resources, and you don’ t have to contend
with a herd of machines all knocking at the door of your management server
all at once.< / p >
< p > The SSH connection type (paramiko is the default, binary openssh is an option)
can also make use of “ ControlMaster” features in SSH, which reuses network
connections.< / p >
< p > If you have 10,000 systems, running a single ansible playbook against all of
them probably isn’ t appropriate, which is why ansible-pull exists. This tool
is designed for running out of git and cron, and can scale to any
number of hosts. Ansible-pull uses local connections versus SSH, but can be
easily bootstrapped or reconfigured just using SSH. There is more information
available about this in the < a class = "reference internal" href = "playbooks2.html" > < em > Advanced Playbooks< / em > < / a > section. The self-bootstrapping
and ease of use are ansible are still retained, even when switching to the pull
model.< / p >
< p > If you’ d like to discuss scaling strategies further, please hop on the mailing list.< / p >
< / div >
< div class = "section" id = "are-transports-other-than-ssh-supported" >
< h3 > Are transports other than SSH supported?< a class = "headerlink" href = "#are-transports-other-than-ssh-supported" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > Currently SSH (you can choose between paramiko or the openssh binaries)
and local connections are supported. The interface is actually pluggable so a
small patch could bring transport over message bus or XMPP as an option.< / p >
< p > Stop by the mailing list if you have ideas. The connection-specific parts of Ansible
are all abstracted away from the core implementation so it is very easy to extend.< / p >
< / div >
< div class = "section" id = "what-are-some-ideal-uses-for-ansible" >
< h3 > What are some ideal uses for Ansible?< a class = "headerlink" href = "#what-are-some-ideal-uses-for-ansible" title = "Permalink to this headline" > ¶< / a > < / h3 >
< p > One of the best use cases? Complex multi-node cloud deployments using playbooks. Another good
example is for configuration management where you
are starting from a clean OS with no extra software installed, adopting systems
that are already deployed.< / p >
< p > Ansible is also great for running ad-hoc tasks across a wide variety of Linux, Unix, and BSDs.
Because it just uses the basic tools available on the system, it is exceptionally cross platform
without needing to install management packages on each node.< / p >
< p > It also excels for writing distributed
scripts and ad-hoc applications that need to gather data or perform arbitrary
tasks – whether for a QA sytem, build system, or anything you can think of.< / 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 = "examples.html" > < em > Command Line< / em > < / a > < / dt >
< dd > Examples of basic commands< / dd >
< dt > < a class = "reference internal" href = "playbooks.html" > < em > Playbooks< / em > < / a > < / dt >
< dd > Learning ansible’ s configuration management language< / 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 >
< dt > < a class = "reference external" href = "http://irc.freenode.net" > irc.freenode.net< / a > < / dt >
< dd > #ansible IRC chat channel< / dd >
< / dl >
< / div >
< / div >
< / div >
< / div >
< br / >
< / div >
< footer class = "footer" >
< div class = "container" >
< div id = "fb-root" > < / div >
< 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 Jul 27, 2012.< br / >
< / p >
< / div >
< / footer >
< / body >
< / html >