diff --git a/README.md b/README.md index b19d81eb77c..75f9d6a3c80 100644 --- a/README.md +++ b/README.md @@ -47,76 +47,82 @@ which for bonus points you can install with ansible! Easy enough. * python-jinja2 -Inventory file -============== +Patterns and Groups +=================== -To use ansible you must have a list of hosts somewhere. The default inventory host list (override with -l) is /etc/ansible/hosts and is a list of all hostnames to manage with ansible, one per line. These can be hostnames or IPs. +Ansible works off an inventory file (/etc/ansible/hosts or overrideable with -i). Hosts can +be listed by IP or hostname, and groups are supported with square brackets: Example: abc.example.com def.example.com + + [atlanta] 192.168.10.50 192.168.10.51 + + [raleigh] + 192.168.10.52 + +When running ansible commands, specific hosts are addressed by wildcard or group name. +The default pattern is '*', meaning all ansible hosts. -This list is further filtered by the pattern wildcard (-p) to target -specific hosts. This is covered below. You can also organize groups of systems by having multiple inventory files (i.e. keeping webservers different from dbservers, etc) + -p '*.example.com' + -p 'atlanta;raleigh' + -p 'database*;appserver*' + -p '192.168.10.50;192.168.10.52' -Massive Parallelism, Pattern Matching, and a Usage Example -========================================================== +Example: Massive Parallelism and Running Shell Commands +======================================================= Reboot all web servers in Atlanta, 10 at a time: ssh-agent bash ssh-add ~/.ssh/id_rsa.pub + ansible -p "atlanta-web*" -f 10 -n command -a "/sbin/reboot" -Other than the comamnd module, though, ansible modules are not scripts. They make -the remote system look like you state, and run the commands neccessary to get it -there. +The -f 10 specifies the usage of 10 simultaneous processes. -[Read the manpage](https://github.com/mpdehaan/ansible/blob/master/docs/man/man1/ansible.1.asciidoc) +Note that other than the command module, ansible modules do not work like simple scripts. They make +the remote system look like you state, and run the commands neccessary to get it there. -File Transfer -============= +[Read the ansible manpage](https://github.com/mpdehaan/ansible/blob/master/docs/man/man1/ansible.1.asciidoc) + +Example: File Transfer and Templating +===================================== -Ansible can SCP lots of files to lots of places in parallel. +Ansible can SCP lots of files to multiple machines in parallel, and optionally use +them as template sources. - ansible -p "web-*.acme.net" -f 10 -n copy -a "/etc/hosts /tmp/hosts" +To just transfer a file directly to many different servers: -Templating -========== + ansible -n copy -a "/etc/hosts /tmp/hosts" -JSON files can be placed for template metadata using Jinja2. Variables -placed by 'setup' can be reused between ansible runs. +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 template module to write the +files using the templates. Templates are written in Jinja2 format. - ansible -p "*" -n setup -a "favcolor=red ntp_server=192.168.1.1" - ansible -p "*" -n template -a "src=/srv/motd.j2 dest=/etc/motd" - ansible -p "*" -n template -a "src=/srv/ntp.j2 dest=/etc/ntp.conf" + ansible -p webservers -n setup -a "favcolor=red ntp_server=192.168.1.1" + ansible -p webservers -n template -a "src=/srv/motd.j2 dest=/etc/motd" + ansible -p webservers -n template -a "src=/srv/ntp.j2 dest=/etc/ntp.conf" Need something like the fqdn in a template? If facter or ohai are installed, data from these projects -will also be made available to the template engine, using 'facter_' and 'ohai_' -prefixes for each. +will also be made available to the template engine, using 'facter_' and 'ohai_' prefixes for each. -Git Deployments -=============== +Example: Software Deployment From Source Control +================================================ Deploy your webapp straight from git - ansible -p "web*" -n git -a "repo=git://foo dest=/srv/myapp version=HEAD" - -Take Inventory -============== - -Run popular open-source data discovery tools across a wide number of hosts. -This is best used from API scripts that want to learn about remote systems. - - ansible -p "dbserver*" -n facter - ansible -p "dbserver"" -n ohai + ansible -p webservers -n git -a "repo=git://foo dest=/srv/myapp version=HEAD" Other Modules ============= +Ansible has lots of other modules. + See the library directory for lots of extras. There's also a manpage, [ansible-modules(5)](https://github.com/mpdehaan/ansible/blob/master/docs/man/man5/ansible-modules.5.asciidoc) that covers all the options they take. You can read the asciidoc in github in the 'docs' directory. @@ -124,15 +130,13 @@ read the asciidoc in github in the 'docs' directory. Playbooks ========= -Playbooks are particularly awesome. Playbooks can batch ansible commands -together, and can even fire off triggers when certain commands report changes. +Playbooks are a completely different way to use ansible and are particularly awesome. They are the basis for a really simple configuration management system, unlike any that already exist, and one that is very well suited to deploying complex multi-machine applications. -An example showing just once pattern in a playbook is below. Playbooks can contain -multple patterns in a single file. +An example showing a small playbook: --- - pattern: 'webservers*' @@ -151,16 +155,17 @@ multple patterns in a single file. - name: restart apache - action: service name=httpd state=restarted -See the playbook format manpage -- [ansible-playbook(5)](https://github.com/mpdehaan/ansible/blob/master/docs/man/man5/ansible-playbook.5.asciidoc) for more details. - To run a playbook: ansible-playbook playbook.yml +See the playbook format manpage -- [ansible-playbook(5)](https://github.com/mpdehaan/ansible/blob/master/docs/man/man5/ansible-playbook.5.asciidoc) for more details. + + API === -The Python API is pretty powerful. +The Python API is very powerful: import ansible.runner @@ -172,8 +177,9 @@ The Python API is pretty powerful. ) datastructure = runner.run() -And returns results per host, for hosts we could contact -and also ones that we failed to contact. +The run method returns results per host, grouped by whether they +could be contacted or not. Return types are module specific, as +expressed in the 'ansible-modules' manpage. { "dark" : { @@ -182,33 +188,21 @@ and also ones that we failed to contact. "contacted" : { "web2.example.com" : 1 } - } -A module can return any type of JSON data it wants, so Ansible can -be used as a framework to build arbitrary applications and very powerful -scripts. - -Future plans -============ - -See github's issue tracker for what we're thinking about +Since a module can return any type of JSON data it wants, so Ansible can +be used as a framework to rapidly build powerful applications and scripts. License ======= GPLv3 -Mailing List and IRC -==================== - -Join the mailing list to talk about Ansible: - -[ansible-project](http://groups.google.com/group/ansible-project) - -irc.freenode.net: #ansible +Communicate +=========== -Everyone may not always be available on IRC, for important issues/questions, use the list or file a ticket. + * [ansible-project mailing list](http://groups.google.com/group/ansible-project) + * irc.freenode.net: #ansible Author ====== diff --git a/bin/ansible b/bin/ansible index 82d99598e65..b4b561f13d6 100755 --- a/bin/ansible +++ b/bin/ansible @@ -39,29 +39,28 @@ class Cli(object): def runner(self): parser = OptionParser() - parser.add_option("-l", "--host-list", dest="host_list", - help="path to hosts list", default=C.DEFAULT_HOST_LIST) - parser.add_option("-m", "--module-path", dest="module_path", - help="path to module library", default=C.DEFAULT_MODULE_PATH) - parser.add_option('-u', '--user', default=C.DEFAULT_REMOTE_USER, - dest='remote_user', help='set the default username') - parser.add_option("-p", "--pattern", dest="pattern", - help="hostname pattern", default=C.DEFAULT_PATTERN) - parser.add_option("-k", "--ask-pass", default=False, action="store_true", - help="ask the user to input the ssh password for connecting") + parser.add_option("-a", "--args", dest="module_args", + help="module arguments", default=C.DEFAULT_MODULE_ARGS) parser.add_option('-f','--forks', dest='forks', default=C.DEFAULT_FORKS, type='int', help='set the number of forks to start up') + parser.add_option("-p", "--host-pattern", dest="hosts", + help="hostname glob or group name", default=C.DEFAULT_PATTERN) + parser.add_option("-i", "--inventory", dest="inventory", + help="inventory host list", default=C.DEFAULT_HOST_LIST) + parser.add_option("-k", "--ask-pass", default=False, action="store_true", + help="ask the user to input the ssh password for connecting") + parser.add_option("-m", "--module-path", dest="module_path", + help="path to module library", default=C.DEFAULT_MODULE_PATH) parser.add_option("-n", "--name", dest="module_name", help="module name to execute", default=None) - parser.add_option("-a", "--args", dest="module_args", - help="module arguments", default=C.DEFAULT_MODULE_ARGS) parser.add_option('-o', '--one-line', dest='one_line', action='store_true', help="try to print output on one line") parser.add_option('-t', '--tree', dest='tree', default=None, help="if specified, a directory name to save output to, one file per host") parser.add_option('-T', '--timeout', default=C.DEFAULT_TIMEOUT, type='int', dest='timeout', help="set the timeout in seconds for ssh") - + parser.add_option('-u', '--user', default=C.DEFAULT_REMOTE_USER, + dest='remote_user', help='set the default username') options, args = parser.parse_args() if options.module_name is None: @@ -83,10 +82,10 @@ class Cli(object): module_args=shlex.split(options.module_args), remote_user=options.remote_user, remote_pass=sshpass, - host_list=options.host_list, + host_list=options.inventory, timeout=options.timeout, forks=options.forks, - pattern=options.pattern, + pattern=options.hosts, verbose=True, ) return runner diff --git a/docs/man/man1/ansible.1.asciidoc b/docs/man/man1/ansible.1.asciidoc index e805c1d1331..fa278d6d498 100644 --- a/docs/man/man1/ansible.1.asciidoc +++ b/docs/man/man1/ansible.1.asciidoc @@ -12,8 +12,7 @@ ansible - run a command somewhere else SYNOPSIS -------- -ansible [-f forks] [-p pattern ] [-u remote_user] - [-n module_name] [-a [args1 [args2 ...]]] +ansible [-f forks] [-p pattern ] [-n module_name] [-a args] DESCRIPTION @@ -26,30 +25,15 @@ SSH. OPTIONS ------- -*-k*, *--ask-pass*:: -Ask the user to input the ssh password for connecting. Generally using -ssh-agent instead is preferred. +*-i*, *--inventory*:: - -*-l*, *--host-list*:: - -Path to hosts list, which defaults to /etc/ansible/hosts. Users can use -multiple files to emulate groups of systems. - - -*-m*, *--module-path*:: - -Override the path to module library, which defaults to /usr/share/ansible. -The module library contains runnable modules that do 'things' to remote -hosts. See ansible-modules(5) for a list of those that bundled with -Ansible. +Path to the inventory hosts file, which defaults to /etc/ansible/hosts. *-f*, *--forks*:: -Level of parallelism. Specify as an integer, the default is 3. If set to "1" -debugging for certain classes of internal errors may become easier. +Level of parallelism. Specify as an integer, the default is 5. *-n*, *--name*:: @@ -59,29 +43,25 @@ Module name to execute. *-a*, *--args*:: -Arguments to module, as a single string. Be sure to observe proper shell quoting rules. -How these are handled are up to the module, but most modules take "key=value" pairs -delimited by spaces. +Arguments to module, as a single string. *-p*, *--pattern*:: Hostname pattern. Accepts shell-like globs which can be seperated with ";" -The default is "*" which matches all hosts in the ansible hosts file. - +The default is "*" which matches all hosts in the ansible hosts file. Group +names from the ansible inventory file can also be used. -*-u*, *--remote-user*:: -Remote user to connect as. Uses __root__ by default. +See ansible --help for additional options. INVENTORY --------- Ansible stores the hosts it can potentially operate on in an inventory -file. The syntax is simple: one host per line. Organize your hosts -into multiple groups by separating them into multiple inventory files. - +file. The syntax is one host per line. Groups headers are allowed and +are included on their own line, enclosed in square brackets. FILES ----- diff --git a/examples/ansible_hosts b/examples/ansible_hosts index fabc8938ac4..76a289565cf 100644 --- a/examples/ansible_hosts +++ b/examples/ansible_hosts @@ -1,2 +1,12 @@ -127.0.0.1 -192.168.1.255 +[webservers] +alpha.example.org +beta.example.org +192.168.1.100 +192.168.1.110 + +[dbservers] +192.168.1.200 +192.168.1.201 +foo.example.org +bar.example.org +