From cf81958f66747cb3e2510ecf467acaafbf174277 Mon Sep 17 00:00:00 2001 From: Paul Bourke Date: Tue, 15 Nov 2016 17:14:35 +0000 Subject: [PATCH] Fix fact gathering when using --limit If an operator wants to deploy a single node (e.g. add an additional compute), they may want to use the --limit feature of Ansible to avoid waiting for every play across every node. The problem with this is that --limit will gather facts for that node only, causing template errors such as the infamous ('dict object' has no attribute u'ansible_eth0'"). Ansible has catered to this problem to an extent with it's "delegate_facts" mechanism. The only problem is that in the default 'all nodes' case, we end up with a storm of SSHs as each node SSHs to every other. I'm solving this with a separate task to only use this mechanism when a subset of nodes has been specified (see ansible_play_batch). Useful links on this subject: - https://medium.com/@george.shuklin/perfecting-forced-fact-gathering-in-ansible-1611f9c8d0d5#.tr5zs3e7x - http://docs.ansible.com/ansible/playbooks_delegation.html#delegated-facts Change-Id: Ibb691eae15cacd9e5129ae9280fd296f5ba95940 Closes-Bug: 1642004 --- ansible/site.yml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ansible/site.yml b/ansible/site.yml index 49f6f89d18..6878a1f77d 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -5,14 +5,32 @@ # set to 'false' is a bit confusing but this is to avoid # Ansible gathering facts twice. - name: Gather facts for all hosts - hosts: - - all + hosts: all serial: '{{ serial|default("0") }}' gather_facts: false tasks: - setup: tags: always +# NOTE(pbourke): This case covers deploying subsets of hosts using --limit. The +# limit arg will cause the first play to gather facts only about that node, +# meaning facts such as IP addresses for rabbitmq nodes etc. will be undefined +# in the case of adding a single compute node. +# We don't want to add the delegate parameters to the above play as it will +# result in ((num_nodes-1)^2) number of SSHs when running for all nodes +# which can be very inefficient. +- name: Gather facts for all hosts (if using --limit) + hosts: all + serial: '{{ serial|default("0") }}' + gather_facts: false + tasks: + - setup: + delegate_facts: True + delegate_to: "{{ item }}" + with_items: "{{ groups['all'] }}" + when: + - (play_hosts | length) != (groups['all'] | length) + - hosts: - all roles: