down votfavorite
|
I am trying to check memory consumption of four machines and any of the machines memory consumption is less than 10 GB I want to restart services on all machines.
I have used or operator in when condition, I am able to restart the services only on the ones that have memory less than 10 GB others get skipped. My requirement is if any of the hosts memory goes down below 10GB I want services to be restarted on all machines not just on machines that have memory below 10GB.
Below is the Ansible playbook:<br>- hosts: webapp<br>become: true<br>become_method: sudo<br>gather_facts: yes<br>vars:<br>servers:<br>"10.0.0.1": "machine1"<br>"10.0.0.2": "machine2"<br>"10.0.0.3": "machine3"<br>"10.0.0.4": "machine4"<br>tasks:<br>- name: get mem free for machine1<br>shell: free -g | grep Mem | awk '{print $4}'<br>register: machine1_mem<br>- debug: var=machine1_mem.stdout<br>when: servers[ansible_default_ipv4.address] == "machine1"<br>- name: get mem free for machine2<br>shell: free -g | grep Mem | awk '{print $4}'<br>register: machine2_mem<br>- debug: var=machine2_mem.stdout<br>when: servers[ansible_default_ipv4.address] == "machine2"<br>- name: get mem free for machine3<br>shell: free -g | grep Mem | awk '{print $4}'<br>register: machine3_mem<br>- debug: var=machine3_mem.stdout<br>when: servers[ansible_default_ipv4.address] == "machine3"<br>- name: get mem free for machine4<br>shell: free -g | grep Mem | awk '{print $4}'<br>register: machine4_mem<br>- debug: var=machine4_mem.stdout<br>when: servers[ansible_default_ipv4.address] == "machine4"<br>- name: restart web services<br>when: ( machine4_mem.stdout|int <= 10 or machine1_mem.stdout|int <= 10 or machine3_mem.stdout|int <= 10 or machine2_mem.stdout|int <= 10 )<br> action: service name=httpd state=restarted<br>
|
Ansible operates on an internal loop. Tasks are executed (and facts set) on ‘per-device’ basis. If you need the results of all the checks I suggest you do the following:
- Register the results and store them into files on the controller (either can run as internal ansible loop or manual set of tasks)
- Add another play in your playbook that’s executed on the localhost - check the content of each of the files and identify if you have to restart or not. You can store this as a fact against ‘localhost’ so it’s accessible via hostvars[‘localhost’][‘var_name’]
- Add yet another play that conditionally restarts all the servers if the content of the variable indicates the need for a restart
the whole thing can be also done without storing info in the files - you can loop over all hosts in a group so you can access the results of the check.
kind regards
Pshem
Thanks Pshem for your solution, Is there anything i can use as ANY condition like if any of the servers return value less than 10 do a service restart on all servers. Below is my play book which i tried.
— # first playbook
- hosts: apacheweb
remote_user: ansible
become: true
become_method: sudo
gather_facts: yes
tasks: - name: Register free memory
shell: free -g | grep Mem | awk ‘{print $4}’
register: memory - set_fact: mem={{ memory.stdout }}
- set_fact: Mem_check=False
when: mem|int > 10 - name: Restart web service
service:
name: httpd
state: restarted
when: not Mem_check
Here i am trying to use set_fact with boolean values if it changes to True from false do a restart on all machines . But still it is only restarting the services on machines that are effected.
This is a little ugly but should work
- name: Restart web service
service:
name: httpd
state: restarted
when: {{ group['apacheweb'] | map('extract', hostvars) | list | selectattr('Mem_check') | list | length < group['apacheweb'] | length }}
One possible caveat, if one or more host doesn't respond the service on the host that work will restarted.