summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAric Renzo <aricrenzo@gmail.com>2017-03-06 17:39:07 -0500
committerscottb <dharmabumstead@users.noreply.github.com>2017-03-06 14:39:07 -0800
commit96538ec15803744912f60d472c03b9049d3cb4a5 (patch)
tree4fe22f247997a564908eee2a48f4ecbc93d24e8a /docs
parentf0491b426195a2745aeabc11e41bf677ea560913 (diff)
downloadansible-96538ec15803744912f60d472c03b9049d3cb4a5.tar.gz
Standardizing syntax for 'Playbook Loops' documentation (#20863)
Diffstat (limited to 'docs')
-rw-r--r--docs/docsite/rst/playbooks_loops.rst201
1 files changed, 147 insertions, 54 deletions
diff --git a/docs/docsite/rst/playbooks_loops.rst b/docs/docsite/rst/playbooks_loops.rst
index 5fdc3d5d45..94208a1162 100644
--- a/docs/docsite/rst/playbooks_loops.rst
+++ b/docs/docsite/rst/playbooks_loops.rst
@@ -16,7 +16,10 @@ Standard Loops
To save some typing, repeated tasks can be written in short-hand like so::
- name: add several users
- user: name={{ item }} state=present groups=wheel
+ user:
+ name: "{{ item }}"
+ state: present
+ groups: "wheel"
with_items:
- testuser1
- testuser2
@@ -28,9 +31,15 @@ If you have defined a YAML list in a variables file, or the 'vars' section, you
The above would be the equivalent of::
- name: add user testuser1
- user: name=testuser1 state=present groups=wheel
+ user:
+ name: "testuser1"
+ state: present
+ groups: "wheel"
- name: add user testuser2
- user: name=testuser2 state=present groups=wheel
+ user:
+ name: "testuser2"
+ state: present
+ groups: "wheel"
The yum and apt modules use with_items to execute fewer package manager transactions.
@@ -38,7 +47,10 @@ Note that the types of items you iterate over with 'with_items' do not have to b
If you have a list of hashes, you can reference subkeys using things like::
- name: add several users
- user: name={{ item.name }} state=present groups={{ item.groups }}
+ user:
+ name: "{{ item.name }}"
+ state: present
+ groups: "{{ item.groups }}"
with_items:
- { name: 'testuser1', groups: 'wheel' }
- { name: 'testuser2', groups: 'root' }
@@ -55,7 +67,11 @@ Nested Loops
Loops can be nested as well::
- name: give users access to multiple databases
- mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
+ mysql_user:
+ name: "{{ item[0] }}"
+ priv: "{{ item[1] }}.*:ALL"
+ append_privs: yes
+ password: "foo"
with_nested:
- [ 'alice', 'bob' ]
- [ 'clientdb', 'employeedb', 'providerdb' ]
@@ -63,7 +79,11 @@ Loops can be nested as well::
As with the case of 'with_items' above, you can use previously defined variables.::
- name: here, 'users' contains the above list of employees
- mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
+ mysql_user:
+ name: "{{ item[0] }}"
+ priv: "{{ item[1] }}.*:ALL"
+ append_privs: yes
+ password: "foo"
with_nested:
- "{{ users }}"
- [ 'clientdb', 'employeedb', 'providerdb' ]
@@ -90,8 +110,10 @@ And you want to print every user's name and phone number. You can loop through
tasks:
- name: Print phone records
- debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
- with_dict: "{{ users }}"
+ debug:
+ msg: "User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
+ with_dict:
+ - "{{ users }}"
.. _looping_over_fileglobs:
@@ -138,12 +160,20 @@ Looping over Fileglobs
tasks:
# first ensure our target directory exists
- - file: dest=/etc/fooapp state=directory
+ - name: Ensure target directory exists
+ file:
+ dest: "/etc/fooapp"
+ state: directory
# copy each file over that matches the given pattern
- - copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
+ - name: Copy each file over that matches the given pattern
+ copy:
+ src: "{{ item }}"
+ dest: "/etc/fooapp/"
+ owner: "root"
+ mode: 600
with_fileglob:
- - /playbooks/files/fooapp/*
+ - "/playbooks/files/fooapp/*"
.. note:: When using a relative path with ``with_fileglob`` in a role, Ansible resolves the path relative to the `roles/<rolename>/files` directory.
@@ -161,7 +191,8 @@ Suppose you have the following variable data was loaded in via somewhere::
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 }}"
+ - debug:
+ msg: "{{ item.0 }} and {{ item.1 }}"
with_together:
- "{{ alpha }}"
- "{{ numbers }}"
@@ -203,10 +234,18 @@ How might that be accomplished? Let's assume you had the following defined and
It might happen like so::
- - user: name={{ item.name }} state=present generate_ssh_key=yes
- with_items: "{{ users }}"
+ - name: Create User
+ user:
+ name: "{{ item.name }}"
+ state: present
+ generate_ssh_key: yes
+ with_items:
+ - "{{ users }}"
- - authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'"
+ - name: Set authorized ssh key
+ authorized_key:
+ user: "{{ item.0.name }}"
+ key: "{{ lookup('file', item.1) }}"
with_subelements:
- "{{ users }}"
- authorized
@@ -214,10 +253,14 @@ It might happen like so::
Given the mysql hosts and privs subkey lists, you can also iterate over a list in a nested subkey::
- name: Setup MySQL users
- mysql_user: name={{ item.0.name }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }}
+ mysql_user:
+ name: "{{ item.0.name }}"
+ password: "{{ item.0.mysql.password }}"
+ host: "{{ item.1 }}"
+ priv: "{{ item.0.mysql.privs | join('/') }}"
with_subelements:
- "{{ users }}"
- - mysql.hosts
+ - "{{ mysql.hosts }}"
Subelements walks a list of hashes (aka dictionaries) and then traverses a list with a given (nested sub-)key inside of those
records.
@@ -249,21 +292,39 @@ Negative numbers are not supported. This works as follows::
tasks:
# create groups
- - group: name=evens state=present
- - group: name=odds state=present
+ - group:
+ name: "evens"
+ state: present
+ - group:
+ name: "odds"
+ state: present
# create some test users
- - user: name={{ item }} state=present groups=evens
- with_sequence: start=0 end=32 format=testuser%02x
+ - user:
+ name: "{{ item }}"
+ state: present
+ groups: "evens"
+ with_sequence:
+ - start: 0
+ - end: 32
+ - format: testuser%02x
# create a series of directories with even numbers for some reason
- - file: dest=/var/stuff/{{ item }} state=directory
- with_sequence: start=4 end=16 stride=2
+ - file:
+ dest: "/var/stuff/{{ item }}"
+ state: directory
+ with_sequence:
+ - start: 4
+ - end: 16
+ - stride: 2
# a simpler way to use the sequence plugin
# create 4 groups
- - group: name=group{{ item }} state=present
- with_sequence: count=4
+ - group:
+ name: "group{{ item }}"
+ state: present
+ with_sequence:
+ count: 4
.. _random_choice:
@@ -273,7 +334,8 @@ Random Choices
The 'random_choice' feature can be used to pick something at random. While it's not a load balancer (there are modules
for those), it can somewhat be used as a poor man's load balancer in a MacGyver like situation::
- - debug: msg={{ item }}
+ - debug:
+ msg: "{{ item }}"
with_random_choice:
- "go through the door"
- "drink from the goblet"
@@ -293,7 +355,8 @@ Do-Until Loops
Sometimes you would want to retry a task until a certain condition is met. Here's an example::
- - action: shell /usr/bin/foo
+ - action:
+ shell /usr/bin/foo
register: result
until: result.stdout.find("all systems go") != -1
retries: 5
@@ -316,7 +379,9 @@ This isn't exactly a loop, but it's close. What if you want to use a reference
that matches a given criteria, and some of the filenames are determined by variable names? Yes, you can do that as follows::
- name: INTERFACES | Create Ansible header for /etc/network/interfaces
- template: src={{ item }} dest=/etc/foo.conf
+ template:
+ src: "{{ item }}"
+ dest: "/etc/foo.conf"
with_first_found:
- "{{ ansible_virtualization_type }}_foo.conf"
- "default_foo.conf"
@@ -324,7 +389,12 @@ that matches a given criteria, and some of the filenames are determined by varia
This tool also has a long form version that allows for configurable search paths. Here's an example::
- name: some configuration template
- template: src={{ item }} dest=/etc/file.cfg mode=0444 owner=root group=root
+ template:
+ src: "{{ item }}"
+ dest: "/etc/file.cfg"
+ mode: 0444
+ owner: "root"
+ group: "root"
with_first_found:
- files:
- "{{ inventory_hostname }}/etc/file.cfg"
@@ -348,8 +418,9 @@ Ansible provides a neat way to do that, though you should remember, this is alwa
machine::
- name: Example of looping over a command result
- shell: /usr/bin/frobnicate {{ item }}
- with_lines: /usr/bin/frobnications_per_host --param {{ inventory_hostname }}
+ shell: "/usr/bin/frobnicate {{ item }}"
+ with_lines:
+ - "/usr/bin/frobnications_per_host --param {{ inventory_hostname }}"
Ok, that was a bit arbitrary. In fact, if you're doing something that is inventory related you might just want to write a dynamic
inventory source instead (see :doc:`intro_dynamic_inventory`), but this can be occasionally useful in quick-and-dirty implementations.
@@ -357,12 +428,13 @@ inventory source instead (see :doc:`intro_dynamic_inventory`), but this can be o
Should you ever need to execute a command remotely, you would not use the above method. Instead do this::
- name: Example of looping over a REMOTE command result
- shell: /usr/bin/something
+ shell: "/usr/bin/something"
register: command_result
- name: Do something with each result
- shell: /usr/bin/something_else --param {{ item }}
- with_items: "{{ command_result.stdout_lines }}"
+ shell: "/usr/bin/something_else --param {{ item }}"
+ with_items:
+ - "{{ command_result.stdout_lines }}"
.. _indexed_lists:
@@ -377,8 +449,10 @@ If you want to loop over an array and also get the numeric index of where you ar
It's uncommonly used::
- name: indexed loop demo
- debug: msg="at array position {{ item.0 }} there is a value {{ item.1 }}"
- with_indexed_items: "{{ some_list }}"
+ debug:
+ msg: "at array position {{ item.0 }} there is a value {{ item.1 }}"
+ with_indexed_items:
+ - "{{ some_list }}"
.. _using_ini_with_a_loop:
@@ -400,8 +474,13 @@ The ini plugin can use regexp to retrieve a set of keys. As a consequence, we ca
Here is an example of using ``with_ini``::
- - debug: msg="{{ item }}"
- with_ini: value[1-2] section=section1 file=lookup.ini re=true
+ - debug:
+ msg: "{{ item }}"
+ with_ini:
+ - value[1-2]
+ - section: section1
+ - file: "lookup.ini"
+ - re: true
And here is the returned value::
@@ -451,7 +530,9 @@ a really crazy hypothetical datastructure::
As you can see the formatting of packages in these lists is all over the place. How can we install all of the packages in both lists?::
- name: flattened loop demo
- yum: name={{ item }} state=installed
+ yum:
+ name: "{{ item }}"
+ state: present
with_flattened:
- "{{ packages_base }}"
- "{{ packages_apps }}"
@@ -467,10 +548,10 @@ After using ``register`` with a loop, the data structure placed in the variable
Here is an example of using ``register`` with ``with_items``::
- - shell: echo "{{ item }}"
+ - shell: "echo {{ item }}"
with_items:
- - one
- - two
+ - "one"
+ - "two"
register: echo
This differs from the data structure returned when using ``register`` without a loop::
@@ -540,22 +621,30 @@ If you wish to loop over the inventory, or just a subset of it, there is multipl
One can use a regular ``with_items`` with the ``play_hosts`` or ``groups`` variables, like this::
# show all the hosts in the inventory
- - debug: msg={{ item }}
- with_items: "{{ groups['all'] }}"
+ - debug:
+ msg: "{{ item }}"
+ with_items:
+ - "{{ groups['all'] }}"
# show all the hosts in the current play
- - debug: msg={{ item }}
- with_items: "{{ play_hosts }}"
+ - debug:
+ msg: "{{ item }}"
+ with_items:
+ - "{{ play_hosts }}"
There is also a specific lookup plugin ``inventory_hostnames`` that can be used like this::
# show all the hosts in the inventory
- - debug: msg={{ item }}
- with_inventory_hostnames: all
+ - debug:
+ msg: "{{ item }}"
+ with_inventory_hostnames:
+ - all
# show all the hosts matching the pattern, ie all but the group www
- - debug: msg={{ item }}
- with_inventory_hostnames: all:!www
+ - debug:
+ msg: "{{ item }}"
+ with_inventory_hostnames:
+ - all:!www
More information on the patterns can be found on :doc:`intro_patterns`
@@ -580,7 +669,8 @@ As of Ansible 2.1, the `loop_control` option can be used to specify the name of
loop_var: outer_item
# inner.yml
- - debug: msg="outer item={{ outer_item }} inner item={{ item }}"
+ - debug:
+ msg: "outer item={{ outer_item }} inner item={{ item }}"
with_items:
- a
- b
@@ -593,7 +683,9 @@ As of Ansible 2.1, the `loop_control` option can be used to specify the name of
When using complex data structures for looping the display might get a bit too "busy", this is where the C(label) directive comes to help::
- name: create servers
- digital_ocean: name={{item.name}} state=present ....
+ digital_ocean:
+ name: "{{ item.name }}"
+ state: present
with_items:
- name: server1
disks: 3gb
@@ -613,7 +705,9 @@ Another option to loop control is C(pause), which allows you to control the time
# main.yml
- name: create servers, pause 3s before creating next
- digital_ocean: name={{item}} state=present ....
+ digital_ocean:
+ name: "{{ item }}"
+ state: present
with_items:
- server1
- server2
@@ -672,4 +766,3 @@ information. Each of the above features are implemented as plugins in ansible,
Have a question? Stop by the google group!
`irc.freenode.net <http://irc.freenode.net>`_
#ansible IRC chat channel
-