By default, Ansible will try to manage all of the machines referenced in a play in parallel. For a rolling update use case, you can define how many hosts Ansible should manage at a single time by using the ``serial`` keyword::
By default, Ansible will try to manage all of the machines referenced in a play in parallel. For a rolling update use case, you can define how many hosts Ansible should manage at a single time by using the ``serial`` keyword::
---
- name: test play
- name: test play
hosts: webservers
hosts: webservers
serial: 2
serial: 2
gather_facts: False
gather_facts: False
tasks:
tasks:
- name: task one
- name: task one
command: hostname
command: hostname
- name: task two
- name: task two
command: hostname
command: hostname
In the above example, if we had 4 hosts in the group 'webservers', 2
In the above example, if we had 4 hosts in the group 'webservers', 2
would complete the play completely before moving on to the next 2 hosts::
would complete the play completely before moving on to the next 2 hosts::
@ -72,6 +73,7 @@ would complete the play completely before moving on to the next 2 hosts::
The ``serial`` keyword can also be specified as a percentage, which will be applied to the total number of hosts in a
The ``serial`` keyword can also be specified as a percentage, which will be applied to the total number of hosts in a
play, in order to determine the number of hosts per pass::
play, in order to determine the number of hosts per pass::
---
- name: test play
- name: test play
hosts: webservers
hosts: webservers
serial: "30%"
serial: "30%"
@ -80,33 +82,36 @@ If the number of hosts does not divide equally into the number of passes, the fi
As of Ansible 2.2, the batch sizes can be specified as a list, as follows::
As of Ansible 2.2, the batch sizes can be specified as a list, as follows::
---
- name: test play
- name: test play
hosts: webservers
hosts: webservers
serial:
serial:
- 1
- 1
- 5
- 5
- 10
- 10
In the above example, the first batch would contain a single host, the next would contain 5 hosts, and (if there are any hosts left),
In the above example, the first batch would contain a single host, the next would contain 5 hosts, and (if there are any hosts left),
every following batch would contain 10 hosts until all available hosts are used.
every following batch would contain 10 hosts until all available hosts are used.
It is also possible to list multiple batch sizes as percentages::
It is also possible to list multiple batch sizes as percentages::
---
- name: test play
- name: test play
hosts: webservers
hosts: webservers
serial:
serial:
- "10%"
- "10%"
- "20%"
- "20%"
- "100%"
- "100%"
You can also mix and match the values::
You can also mix and match the values::
---
- name: test play
- name: test play
hosts: webservers
hosts: webservers
serial:
serial:
- 1
- 1
- 5
- 5
- "20%"
- "20%"
..note::
..note::
No matter how small the percentage, the number of hosts per pass will always be 1 or greater.
No matter how small the percentage, the number of hosts per pass will always be 1 or greater.
@ -122,6 +127,7 @@ In some situations, such as with the rolling updates described above, it may be
certain threshold of failures have been reached. To achieve this, you can set a maximum failure
certain threshold of failures have been reached. To achieve this, you can set a maximum failure
percentage on a play as follows::
percentage on a play as follows::
---
- hosts: webservers
- hosts: webservers
max_fail_percentage: 30
max_fail_percentage: 30
serial: 10
serial: 10
@ -147,51 +153,47 @@ Be aware that it does not make sense to delegate all tasks, debug, add_host, inc
Using this with the 'serial' keyword to control the number of hosts executing at one time is also a good idea::
Using this with the 'serial' keyword to control the number of hosts executing at one time is also a good idea::
These commands will run on 127.0.0.1, which is the machine running Ansible. There is also a shorthand syntax that you can use on a per-task basis: 'local_action'. Here is the same playbook as above, but using the shorthand syntax for delegating to 127.0.0.1::
These commands will run on 127.0.0.1, which is the machine running Ansible. There is also a shorthand syntax that you can use on a per-task basis: 'local_action'. Here is the same playbook as above, but using the shorthand syntax for delegating to 127.0.0.1::
A common pattern is to use a local action to call 'rsync' to recursively copy files to the managed servers.
A common pattern is to use a local action to call 'rsync' to recursively copy files to the managed servers.
Here is an example::
Here is an example::
---
---
# ...
# ...
tasks:
- name: recursively copy files from management server to target
tasks:
local_action: command rsync -a /path/to/files {{ inventory_hostname }}:/path/to/target/
- name: recursively copy files from management server to target
local_action: command rsync -a /path/to/files {{ inventory_hostname }}:/path/to/target/
Note that you must have passphrase-less SSH keys or an ssh-agent configured for this to work, otherwise rsync
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.
will need to ask for a passphrase.
@ -200,15 +202,15 @@ In case you have to specify more arguments you can use the following syntax::
---
---
# ...
# ...
tasks:
- name: Send summary mail
tasks:
local_action:
- name: Send summary mail
module: mail
local_action:
subject: "Summary Mail"
module: mail
to: "{{ mail_recipient }}"
subject: "Summary Mail"
body: "{{ mail_body }}"
to: "{{ mail_recipient }}"
run_once: True
body: "{{ mail_body }}"
run_once: True
The `ansible_host` variable (`ansible_ssh_host` in 1.x or specific to ssh/paramiko plugins) reflects the host a task is delegated to.
The `ansible_host` variable (`ansible_ssh_host` in 1.x or specific to ssh/paramiko plugins) reflects the host a task is delegated to.
@ -220,8 +222,9 @@ Delegated facts
By default, any fact gathered by a delegated task are assigned to the `inventory_hostname` (the current host) instead of the host which actually produced the facts (the delegated to host).
By default, any fact gathered by a delegated task are assigned to the `inventory_hostname` (the current host) instead of the host which actually produced the facts (the delegated to host).
The directive `delegate_facts` may be set to `True` to assign the task's gathered facts to the delegated host instead of the current one.::
The directive `delegate_facts` may be set to `True` to assign the task's gathered facts to the delegated host instead of the current one.::
---
- hosts: app_servers
- hosts: app_servers
tasks:
tasks:
- name: gather facts from db servers
- name: gather facts from db servers
setup:
setup:
@ -297,6 +300,7 @@ To run an entire playbook locally, just set the "hosts:" line to "hosts: 127.0.0
Alternatively, a local connection can be used in a single playbook play, even if other plays in the playbook
Alternatively, a local connection can be used in a single playbook play, even if other plays in the playbook
use the default remote connection type::
use the default remote connection type::
---
- hosts: 127.0.0.1
- hosts: 127.0.0.1
connection: local
connection: local
@ -330,21 +334,24 @@ For datacenter "A", the playbook can be written this way::
---
---
- hosts: load_balancers_dc_a
- hosts: load_balancers_dc_a
any_errors_fatal: True
any_errors_fatal: True
tasks:
tasks:
- name: 'shutting down datacenter [ A ]'
- name: 'shutting down datacenter [ A ]'
command: /usr/bin/disable-dc
command: /usr/bin/disable-dc
- hosts: frontends_dc_a
- hosts: frontends_dc_a
tasks:
tasks:
- name: 'stopping service'
- name: 'stopping service'
command: /usr/bin/stop-software
command: /usr/bin/stop-software
- name: 'updating software'
- name: 'updating software'
command: /usr/bin/upgrade-software
command: /usr/bin/upgrade-software
- hosts: load_balancers_dc_a
- hosts: load_balancers_dc_a
tasks:
tasks:
- name: 'Starting datacenter [ A ]'
- name: 'Starting datacenter [ A ]'
command: /usr/bin/enable-dc
command: /usr/bin/enable-dc
In this example Ansible will start the software upgrade on the front ends only if all of the load balancers are successfully disabled.
In this example Ansible will start the software upgrade on the front ends only if all of the load balancers are successfully disabled.