Reputation: 1652
I'm using Ansible to setup EC2 instances and deploy an application. There's a hosts script which gathers tags related servers and groups info. I'd like to run these actions as a single playbook, so
However, the inventory is loaded in advance, so, there is no servers/groups data if servers are created/updated during the play. I can
But, there are drawbacks in those approaches.
Can I force Ansible to reload inventory?
My test files are:
hosts
script:
#!/bin/sh
echo `date` >> log.log
echo "{\"standalone\":[\"localhost\"]}"
Sample playbook.yml
:
---
- hosts: all
tasks:
- name: show inventory_hostname
command: echo {{ inventory_hostname }}
I run it with the command ansible-playbook -i hosts playbook.yml -v
and see two runs:
$> cat log.log
Thu Mar 12 09:43:16 SAMT 2015
Thu Mar 12 09:43:16 SAMT 2015
but I haven't found a command to double it.
Upvotes: 58
Views: 36627
Reputation: 676
With Ansible 2.0+, you can refresh your inventory mid-play by running the task:
- meta: refresh_inventory
Upvotes: 66
Reputation: 133
Please note that meta: refresh_inventory
does not work in Ansible Tower (AWX).
https://docs.ansible.com/ansible-tower/3.3.1/html/userguide/best_practices.html
Playbooks should not use the meta: refresh_inventory Ansible feature, as it is incompatible with how Tower processes inventory, if a playbook does refresh inventory, it will refresh back to the start of the inventory the job began with. Instead, use a workflow with separate inventory refresh steps.
I do not yet have enough rep to comment, otherwise, I would have.
Upvotes: 0
Reputation: 369
I had a similar scenario and meta did not help, but setup did. So, this is for all folks that might find this useful... To give a little bit of context, what I was doing is to limit the linux kernel memory to a certain amount of what the real memory was and then update some files based on the new values.
For instance, the ansible tasks were something like:
- name: Print real memory
debug:
msg: {{ ansible_memory_mb.real.total }}
- name: Reset GRUB_CMDLINE_LINUX
lineinfile:
path: /etc/default/grub
regexp: '^{{ item.key }}='
line: '{{ item.key }}="{{ item.value }}"'
with_items:
- { key: 'GRUB_CMDLINE_LINUX',
value: '{{ ansible_memory_mb.real.total - reserved }}m'}
- name: Update GRUB
command: update-grub
- name: Reboot the node to load the system's real memory settings
reboot:
- name: Print real memory
debug:
msg: {{ ansible_memory_mb.real.total }}
and the output was the same for both debug logs because the ansible_memory_mb
variable was not reload after the linux kernel configuration changed.
Solution? Add a task to setup
after rebooting the system.
- name: Refresh ansible facts (ansible_memory_mb) after updating grub
setup:
Upvotes: 0
Reputation: 1149
You can also edit the ec2.ini file and set the option:
cache_max_age = 0
to prevent the need for reload by making sure that nothing is cached in the first place.
Upvotes: 2
Reputation: 5202
I found the meta: refresh_inventory
to be insufficient.
I had to add an explicit call to ec2.py --refresh-cache
first.
- name: refresh inventory hosts: localhost connection: local gather_facts: False tasks: - name: Refresh EC2 cache command: /etc/ansible/ec2.py --refresh-cache - name: Refresh in-memory EC2 cache meta: refresh_inventory
Upvotes: 21
Reputation: 127
Take a look at add_host.
It does add a host (and alternatively a group) to the ansible-playbook in-memory inventory
Upvotes: -2
Reputation: 20719
Ansible currently doesn't support this. If you look at the source code of the ansible
or ansible-playbook
commands you'll see that the inventory is loaded first and then the inventory object is passed to the ansible command that runs the specified task or playbook. Moving the inventory processing so that it happens within the task/playbook handlers would probably be a pretty major undertaking for a number of reasons.
Your best bet when doing something like this is to simply break your playbook into two and wrap their calls in a shell script that you only have to invoke once.
Upvotes: 6