From 41909d7fd53db0a115957ed83dc071df23a08281 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Fri, 4 Oct 2013 18:34:39 -0400 Subject: [PATCH] More exciting anchor tags, document more loop features! --- docsite/latest/rst/modules.rst | 3 + docsite/latest/rst/playbooks_acceleration.rst | 2 +- .../latest/rst/playbooks_best_practices.rst | 37 ++++++++++ docsite/latest/rst/playbooks_checkmode.rst | 3 + docsite/latest/rst/playbooks_delegation.rst | 8 ++ .../latest/rst/playbooks_error_handling.rst | 4 + docsite/latest/rst/playbooks_loops.rst | 73 ++++++++++++++++++- 7 files changed, 127 insertions(+), 3 deletions(-) diff --git a/docsite/latest/rst/modules.rst b/docsite/latest/rst/modules.rst index 8b90956197..823a7c7361 100644 --- a/docsite/latest/rst/modules.rst +++ b/docsite/latest/rst/modules.rst @@ -4,6 +4,8 @@ Ansible Modules .. contents:: :depth: 3 +.. _modules_intro: + Introduction ```````````` @@ -55,6 +57,7 @@ Let's see what's available in the Ansible module library, out of the box: .. include:: modules/_list.rst +.. _writing_modules: Writing your own modules ```````````````````````` diff --git a/docsite/latest/rst/playbooks_acceleration.rst b/docsite/latest/rst/playbooks_acceleration.rst index d2368be719..2ff85869c8 100644 --- a/docsite/latest/rst/playbooks_acceleration.rst +++ b/docsite/latest/rst/playbooks_acceleration.rst @@ -54,7 +54,7 @@ As noted above, accelerated mode also supports running tasks via sudo, however t * You must remove requiretty from your sudoers options. * Prompting for the sudo password is not yet supported, so the NOPASSWD option is required for commands. - +.. _fireball_mode: Fireball Mode ````````````` diff --git a/docsite/latest/rst/playbooks_best_practices.rst b/docsite/latest/rst/playbooks_best_practices.rst index 5b843bb6ed..9be11f11a4 100644 --- a/docsite/latest/rst/playbooks_best_practices.rst +++ b/docsite/latest/rst/playbooks_best_practices.rst @@ -8,6 +8,8 @@ You can find some example playbooks illustrating these best practices in our `an .. contents:: :depth: 2 +.. _content_organization: + Content Organization ++++++++++++++++++++++ @@ -17,6 +19,8 @@ so feel free to modify this approach and organize as you see fit. (One thing you will definitely want to do though, is use the "roles" organization feature, which is documented as part of the main playbooks page) +.. _directory_layout: + Directory Layout ```````````````` @@ -54,6 +58,8 @@ The top level of the directory would contain files and directories like so:: monitoring/ # "" fooapp/ # "" +.. _stage_vs_prod: + How to Arrange Inventory, Stage vs Production ````````````````````````````````````````````` @@ -97,6 +103,8 @@ data source as well, but this is just a basic example. Define groups based on p boston-webservers boston-dbservers +.. _groups_and_hosts: + Group And Host Variables ```````````````````````` @@ -130,6 +138,8 @@ We can define specific hardware variance in systems in a host_vars file, but avo foo_agent_port: 86 bar_agent_port: 99 +.. _role_vars: + Role Variables `````````````` @@ -140,6 +150,8 @@ Variables that are associated with a given role can be defined in a main.yml fil python_version: "2.7.5" pip_version: "1.3.1" +.. _split_by_role: + Top Level Playbooks Are Separated By Role ````````````````````````````````````````` @@ -160,6 +172,8 @@ In a file like webservers.yml (also at the top level), we simply map the configu - common - webtier +.. _role_organization: + Task And Handler Organization For A Role ```````````````````````````````````````` @@ -190,6 +204,8 @@ of each play:: - name: restart ntpd service: name=ntpd state=restarted +.. _organization_examples: + What This Organization Enables (Examples) ````````````````````````````````````````` @@ -229,6 +245,8 @@ And there are some useful commands to know (at least in 1.1 and higher):: # confirm what hostnames might be communicated with if I said "limit to boston" ansible-playbook -i production webservers.yml --limit boston --list-hosts +.. _dep_vs_config: + Deployment vs Configuration Organization ```````````````````````````````````````` @@ -239,6 +257,8 @@ may be augmented by playbooks like 'deploy_exampledotcom.yml' but the general co Ansible allows you to deploy and configure using the same tool, so you would likely reuse groups and just keep the OS configuration in separate playbooks from the app deployment. +.. _stage_vs_prod: + Stage vs Production +++++++++++++++++++ @@ -247,18 +267,24 @@ As also mentioned above, a good way to keep your stage (or testing) and producti Testing things in a stage environment before trying in production is always a great idea. Your environments need not be the same size and you can use group variables to control the differences between those environments. +.. _rolling_update: + Rolling Updates +++++++++++++++ Understand the 'serial' keyword. If updating a webserver farm you really want to use it to control how many machines you are updating at once in the batch. +.. _mention_the_state: + Always Mention The State ++++++++++++++++++++++++ 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. +.. _group_by_roles: + Group By Roles ++++++++++++++ @@ -268,6 +294,8 @@ A system can be in multiple groups. See :doc:`intro_inventory` and :doc:`intro_ This allows playbooks to target machines based on role, as well as to assign role specific variables using the group variable system. +.. _os_variance: + Operating System and Distribution Variance ++++++++++++++++++++++++++++++++++++++++++ @@ -303,6 +331,7 @@ If group-specific settings are needed, this can also be done. For example:: In the above example, CentOS machines get the value of '42' for asdf, but other machines get '10'. +.. _ship_modules_with_playbooks: Bundling Ansible Modules With Playbooks +++++++++++++++++++++++++++++++++++++++ @@ -312,17 +341,23 @@ Bundling Ansible Modules With Playbooks If a playbook has a "./library" directory relative to its 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. +.. _whitespace: + Whitespace and Comments +++++++++++++++++++++++ Generous use of whitespace to break things up, and use of comments (which start with '#'), is encouraged. +.. _name_tasks: + Always Name Tasks +++++++++++++++++ It is possible to leave off the 'name' for a given task, though it is recommended to provide a description about why something is being done instead. This name is shown when the playbook is run. +.. _keep_it_simple: + Keep It Simple ++++++++++++++ @@ -332,6 +367,8 @@ for you. For example, you will probably not need 'vars', 'vars_files', 'vars_prompt' and '--extra-vars' all at once, while also using an external inventory file. +.. _version_control: + Version Control +++++++++++++++ diff --git a/docsite/latest/rst/playbooks_checkmode.rst b/docsite/latest/rst/playbooks_checkmode.rst index 5cfa2ef711..e80e60cae5 100644 --- a/docsite/latest/rst/playbooks_checkmode.rst +++ b/docsite/latest/rst/playbooks_checkmode.rst @@ -15,6 +15,8 @@ Example:: ansible-playbook foo.yml --check +.. _forcing_to_run_in_check_mode: + Running a task in check mode ```````````````````````````` @@ -37,6 +39,7 @@ As a reminder, a task with a `when` clause evaluated to false, will still be skipped even if it has a `always_run` clause evaluated to true. +.. _diff_mode: Showing Differences with --diff ``````````````````````````````` diff --git a/docsite/latest/rst/playbooks_delegation.rst b/docsite/latest/rst/playbooks_delegation.rst index f91ac64409..8b082bdb27 100644 --- a/docsite/latest/rst/playbooks_delegation.rst +++ b/docsite/latest/rst/playbooks_delegation.rst @@ -13,6 +13,8 @@ at once during a rolling update. This section covers all fo these features. For examples of these items in use, please see the 'ansible-examples' repository in the 'ansible' github organization. +.. _rolling_update_batch_size: + Rolling Update Batch Size ````````````````````````` @@ -29,6 +31,8 @@ use case, you can define how many hosts Ansible should manage at a single time b In the above example, if we had 100 hosts, 3 hosts in the group 'webservers' would complete the play completely before moving on to the next 3 hosts. +.. _maximum_failure_percentage: + Maximum Failure Percentage `````````````````````````` @@ -50,6 +54,8 @@ In the above example, if more than 3 of the 10 servers in the group were to fail The percentage set must be exceeded, not equaled. For example, if serial were set to 4 and you wanted the task to abort when 2 of the systems failed, the percentage should be set at 49 rather than 50. +.. _delegation: + Delegation `````````` @@ -106,6 +112,8 @@ Here is an example:: Note that you must have passphrase-less SSH keys or an ssh-agent configured for this to work, otherwise rsync will need to ask for a passphrase. +.. _local_playbooks: + Local Playbooks ``````````````` diff --git a/docsite/latest/rst/playbooks_error_handling.rst b/docsite/latest/rst/playbooks_error_handling.rst index 873b327b1e..a66f5c9c4a 100644 --- a/docsite/latest/rst/playbooks_error_handling.rst +++ b/docsite/latest/rst/playbooks_error_handling.rst @@ -9,6 +9,8 @@ need to report that it 'changed' the remote system. This section describes how the default behavior of Ansible for certain tasks so output and error handling behavior is as desired. +.. _ignoring_failed_commands: + Ignoring Failed Commands ```````````````````````` @@ -22,6 +24,8 @@ write a task that looks like this:: command: /bin/false ignore_errors: yes +.. _override_the_changed_result: + Overriding The Changed Result ````````````````````````````` diff --git a/docsite/latest/rst/playbooks_loops.rst b/docsite/latest/rst/playbooks_loops.rst index 183f994671..d3793e11bf 100644 --- a/docsite/latest/rst/playbooks_loops.rst +++ b/docsite/latest/rst/playbooks_loops.rst @@ -3,6 +3,7 @@ Loops All about how to use loops in playbooks. +.. _standard_loops: Standard Loops `````````````` @@ -37,6 +38,8 @@ If you have a list of hashes, you can reference subkeys using things like:: - { name: 'testuser1', groups: 'wheel' } - { name: 'testuser2', groups: 'root' } +.. _nested_loops: + Nested Loops ```````````` @@ -56,6 +59,8 @@ As with the case of 'with_items' above, you can use previously defined variables - users - [ 'clientdb', 'employeedb', 'providerdb' ] +.. _looping_over_fileglobs: + Looping over Fileglobs `````````````````````` @@ -78,13 +83,56 @@ be used like this:: Looping over Parallel Sets of Data `````````````````````````````````` -Documentation for this feature is coming soon. +.. note:: This is an uncommon thing to want to do, but we're documenting it for completeness. You won't be reaching for this one often. + +Suppose you have the following variable data was loaded in via somewhere:: + + --- + alpha: [ 'a', 'b', 'c', 'd' ] + numbers: [ 1, 2, 3, 4 ] + +And you want the set of '(a, 1)' and '(b, 2)' and so on. Use 'with_together' to get this:: + + tasks: + - debug: msg="{{ item.0 }} and {{ item.1 }}" + with_together: + - alpha + - numbers Looping over Subelements ```````````````````````` -Documentation for this feature is coming soon. +Suppose you want to do something like loop over a list of users, creating them, and allowing them to login by a certain set of +SSH keys. +How might that be accomplished? Let's assume you had the following defined and loaded in via "vars_files" or maybe a "group_vars/all" file:: + + --- + users: + - name: alice + authorized: + - /tmp/alice/onekey.pub + - /tmp/alice/twokey.pub + - name: bob + authorized: + - /tmp/bob/id_rsa.pub + +It might happen like so:: + + - user: name={{ item.name }} state=present generate_ssh_key=yes + with_items: users + + - authorized_key: user={{ item.0.name }} key={{ lookup('file', item.1) }} + with_subelements: + - users + - authorized + +Subelements walks a list of hashes (aka dictionaries) and then traverses a list with a given key inside of those +records. + +The authorized_key pattern is exactly where it comes up most. + +.. _looping_over_integer_sequences: Looping over Integer Sequences `````````````````````````````` @@ -119,6 +167,27 @@ Negative numbers are not supported. This works as follows:: - group: name=group{{ item }} state=present with_sequence: count=4 +.. _random_choice: + +Random Choices +`````````````` + +The 'random_choice' feature can be used to pick something at random. While it's not a load balancer, it can +somewhat be used as a poor man's loadbalancer in a MacGyver like situation:: + + - debug: msg={{ item }} + with_random_choice: + - "go through the door" + - "drink from the goblet" + - "press the red button" + - "do nothing" + +One of the provided strings will be selected at random. + +At a more basic level, they can be used to add chaos and excitement to otherwise predictable automation environments. + +.. _do_until_loops: + Do-Until Loops ``````````````