The “add host” module is currently coded as something called a “bypass host group” module, which means it only runs once.
This means it’s meant to be used in plays that look like this:
tasks:
It has to be outside the host group as each fork/host has a different copy of the shared memory.
While this may seem to be somewhat non-intuitive, it also means you don’t have to do “local_action:” all throughout the provisioning play.
However, I’ll agree that this is non-obvious, but somewhat of an artifact of Ansible not intending to be used as a programming language.
Michael, I believe I understand what you’re saying. However, if I may, I should like to make an observation and then give you a scenario where I am finding the current add_hosts behaviour to be exceedingly unhelpful. Perhaps you’ll have a solution for the latter!
First, the observation. People keep being bitten by this add_hosts behaviour – both on this group (as in this thread), but also in the ansible issue tracker on github (e.g. issues #5145, #2963, #6912, etc.). There have been repeated requests to note this unintuitive behaviour in the documentation for the add_host command, and even issues raised specifically to address this (e.g. #104, #532 in ansible-modules-core). Nevertheless, the documentation still doesn’t mention this, and thus additional people are continuing to waste hours over this, as I did today.
As someone coming fresh to ansible in the last week or so, this sort of unexpected gotcha, especially combined with inadequate documentation, has been a source of considerable frustration. Another example of this class of problem would be the apparent inability to specify binary (non-text) parameter values – see my open question on that in relation to ec2 user_data, here: https://groups.google.com/d/msg/ansible-project/HYa3ipze_aY/ebkguL57hkAJ
Now, all that said, I’m very grateful that Ansible exists and is supplied under a generous licence – thank you! I really want to like it, and it seems (nearly) to do so many things right, but these unexpected and counter-intuitive stumbling blocks are obviously causing a lot of friction for a number of people.
Secondly, my scenario. I want to provision multiple ec2 regions simultaneously, because that will greatly speed up the provisioning process. e.g. if I have three regions, with a similar configuration, provisioning all three at the same will be approximately 3x faster than doing them serially. When we’re talking about several minutes of elapsed time to provision each region, the savings soon add up, especially during the development and testing phase. Now, to achieve simultaneous provisioning, and to do so in a clear, flexible, and self-documenting way, I defined a static inventory file along these lines:
[aws_webserver_regions]
eu-west-1 ansible_ssh_host=localhost ansible_connection=local freebsd_ami=ami-3013a747 # Ireland
us-west-2 ansible_ssh_host=localhost ansible_connection=local freebsd_ami=ami-53fcb763 # Oregon
…
In my playbooks, I can then do something like this:
- hosts: aws_webserver_regions
gather_facts: false
vars_files:
- vars/araxis_users.yml
roles:
- role: ec2-webserver-provisioning
aws_region: “{{ inventory_hostname }}”
aws_ami: “{{ freebsd_ami }}”
ec2_user: “{{ araxis_users[‘ec2-user’] }}”
- hosts: ec2_provisioned_instances
connection: ssh
remote_user: ec2-user
su: yes
su_user: root
roles:
And, you know what, this works great. All, that is, except for the add_host invocation in my ec2-webserver-provisioning role (which is intended to add the newly provisioned instances to the group ec2_provisioned_instances). That doesn’t work as I intended at all, because the add_host invocation only works for one of my regions.
Having wasted a good many hours on this today, I eventually discovered that add_hosts isn’t expected to work in this situation. Ok, that’s annoying, but there’s an easy work around, I think – I’ll simply make use of the ec2 dynamic host inventory (since my provisioning role waits for ssh to be up-and-running on all the instances) in my playbook and go from there. That way, I won’t need add_host at all. Except that I’ve just read about yet another gotcha, which is that dynamic inventory is evaluated only once, at the beginning of the playbook run. So now I’m stuck, and beginning to think that, for me at least, ansible is proving to be anything but the radically simple solution that it is pitched as being.
Now, I apologise for the moaning – though it has been a frustrating couple of days! I’m sure that simultaneous provisioning across multiple ec2 regions is not an atypical thing to want to do, so how ought I to go about that?
(I am aware that I can put serial: 1 in the top part of my playbook. And, if I do, everything works perfectly. Except, of course, that I am then unable to provision against multiple regions simultaneously.)
Many thanks in advance for your help! And again, I really, really am trying to like ansible 