Thanks for the help, Josh. 

I actually am trying to run a command once on a certain set of EC2 
instances I'm managing that match a specific tag. This seems like a very 
reasonable thing to do and yet the run_once skipping functionality makes 
this quite difficult. I managed to find two similar but different ways to 
do this (though not exactly elegant), which I'll post for future reference. 
I was inspired by 
https://groups.google.com/forum/#!topic/ansible-project/cpnrBRxLy0E and 
https://imil.net/blog/2016/08/05/Ansible_and_AWS_ASG

*Method 1* (serial 1 is important due to the add_host behavior Josh pointed 
out). Run the playbook with the AWS dynamic inventory script (-i ec2.py)

- hosts: ec2
user: ubuntu
serial: 1
gather_facts: false
tasks:
- name: add only nodes that don't match your_tag_name to in-memory host 
group
add_host:
name: "{{ inventory_hostname }}"
groups: your_hosts
when: ec2_tag_Name != your_tag_name

and then run the rest of your playbook not serially and perform run_once 
actions like this:

- hosts: ec2
user: ubuntu
gather_facts: true
tasks:
- name: Run once on your_tag_name
shell: echo yes >> yes.txt
run_once: true
delegate_to: "{{ groups['your_hosts'][0] }}"

*Method 2: *use the ec2_instance_facts module to create the in-memory 
group. This requires a tag name variable or constant you can reference to 
match instances with

- hosts: localhost
user: ubuntu
connection: local
gather_facts: true
tasks:
- name: create an in memory group of only nodes with your_tag_name
add_host:
name: "{{ item }}"
groups: your_hosts
with_items: "{{ ec2.instances | selectattr('state.name', 'equalto', 
'running') | selectattr('tags.Name', 'equalto', your_tag_name ) | 
map(attribute='public_ip_address')|list }}"


Either way, if you want to use the information from ec2.py then you'll end 
up having two hosts sections and some verbosity. I suppose with the 
ec2_instance_facts one could potentially create groups of EC2 hosts and run 
the playbook all with hosts: localhost and delegate tasks to certain 
groups? I haven't tried this as I've spend enough time getting run_once to 
work for now.

Dave

On Friday, December 8, 2017 at 1:14:17 PM UTC-7, Josh Smift wrote:
>
> > Weirdly, when I try to create an in-memory host group using when and 
> > add_host the task only gets executed one time (on a skipped host). I 
> > don't have run_once on this task so I'm not sure why all my nodes aren't 
> > executing it. Any ideas? 
>
> add_host is implicitly run_once; there's a note about it at the bottom of 
> http://docs.ansible.com/ansible/latest/add_host_module.html saying "This 
> module bypasses the play host loop and only runs once for all the hosts in 
> the play, if you need it to iterate use a with_ directive." Something like 
>
>   - add_host: 
>       groups: cool_new_group 
>       name: "{{ item }}" 
>     changed_when: False 
>     with_items: "{{ play_hosts }}" 
>
> might do what you need, depending what you need. :^) 
>
>                                       -Josh (j...@care.com <javascript:>) 
>
> (apologies for the automatic corporate disclaimer that follows) 
>
> This email is intended for the person(s) to whom it is addressed and may 
> contain information that is PRIVILEGED or CONFIDENTIAL. Any unauthorized 
> use, distribution, copying, or disclosure by any person other than the 
> addressee(s) is strictly prohibited. If you have received this email in 
> error, please notify the sender immediately by return email and delete the 
> message and any attachments from your system. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to ansible-project+unsubscr...@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/edc84a8a-fd6b-4757-8f08-ede57457828d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to