how to use when condition in ansible - ansible

I have the part of the script:
- name: To Display SPLUNK Status
shell: service splunk status | grep PID
register: STATUS
- name: Showing SPLUNK Status
debug: var=STATUS.stdout_lines
- name: Getting Process IDs of the SPLUNK
shell: ps -ef|grep -i splunk
register: pids_of_SPLUNK
- name: Printing the process IDs obtained
debug: var=pids_of_SPLUNK.stdout_lines
#- name: SPLUNK is NOT running
- debug: msg="Splunk is NOT running"
when: not STATUS.stat.exists
#- name: SPLUNK is Running
- debug: msg="Splunk is Restarted and Running"
that line getting me the error: when: not STATUS.stat.exists
when splunk is running it has the status:
Splunk status:
splunkd is running (PID: 7198).
splunk helpers are running (PIDs: 7200).
When splunk is not running:
Splunk status:
splunkd is not running.
how I can use: when condition for it ?
Thank you.

Use service_facts. For example
vars:
my_services:
- 'splunk'
- 'apache2'
- 'ssh'
tasks:
- service_facts:
- debug:
msg: "Service {{ item }} is not available."
loop: "{{ my_services }}"
when: item not in ansible_facts.services.keys()|list
- debug:
msg: "Service {{ item }} is available."
loop: "{{ my_services }}"
when: item in ansible_facts.services.keys()|list
- debug:
msg: "{{ item }} is {{ ansible_facts.services[item].state }}"
loop: "{{ my_services }}"
when: item in ansible_facts.services.keys()|list
give
"msg": "Service splunk is not available."
"msg": "Service apache2 is available."
"msg": "Service ssh is available."
"msg": "apache2 is stopped"
"msg": "ssh is running"

Related

Loop over list and evaluate element property in Ansible

I have a list with shell lines that I want to execute on inventory hosts so I can determine if the database is working. For the test purposes I have 1 server with PostgreSQL and 1 with MySQL.
This is my playbook so far:
- name: Check db statuses
shell: "{{ item }}"
loop:
- ps -fp $(pgrep -u postgres) | grep /usr/lib/postgresql
- ps -fp $(pgrep -u mysql) | grep mysqld
register: http
ignore_errors: yes
changed_when: item.failed == false
this is failing with:
{
"http": {
"failed": true,
"msg": "The conditional check 'item.failed == false' failed. The error was: error while evaluating conditional (item.failed == false): 'ansible.parsing.yaml.objects.AnsibleUnicode object' has no attribute 'failed'"
}
}
I want to assign only the item.failed==false result in the register variable (http) but ignore the failed ones.
You can't select what will be registered in a loop. Instead, you'll have to evaluate the registered results in the next task(s), e.g.
- hosts: localhost
tasks:
- command: "{{ item }}"
loop:
- /bin/true
- /bin/false
register: http
ignore_errors: true
- debug:
msg: "{{ item.item }} failed: {{ item.failed }}"
loop: "{{ http.results }}"
loop_control:
label: "{{ item.cmd }}"
gives
ok: [localhost] => (item=['/bin/true']) =>
msg: '/bin/true failed: False'
ok: [localhost] => (item=['/bin/false']) =>
msg: '/bin/false failed: True'

Ansible to consolidate service status on multiple servers

Below playbook works where inventory groups has multiple servers and to check the status of each service and display its status on console.
Problem is, I wanted to consolidate the status of each service on every server and send in an email, but it seems array (uistatus_app, uistatus_status, uistatus_print) gets re-initiated for each server run.
Is there any way where I can store the status in the global variable of each run and display?
for example:
server1: nginx is active
server1: PHP is active
server2: nginx is active
server2: PHP is unknown
Thanks.
- name: checking services
shell: 'systemctl is-active {{item}}'
with_items:
- nginx
- php74-php-fpm
failed_when: false
register: uistatus
when: 'inventory_hostname in groups[''stg-ui]'
- name: get ui status in arrray
set_fact:
uistatus_app: '{{uistatus_app}}+[ ''{{item.item}}'']'
uistatus_status: '{{uistatus_app}}+[ ''{{item.stdout}}'']'
with_items: '{{ uistatus.results }}'
when: 'inventory_hostname in groups[''stg-ui]'
- name: consolidate
set_fact:
uistatus_print: '{{uistatus_print}}+{{inventory_hostname}}: {{item[0]}} is item[1]}}]'
loop: '{{ query(''together'',uistatus_app, uistatus.status }}'
when: 'inventory_hostname in groups[''stg-ui]'
Set the variable with the list of the statuses in each host, e.g.
- hosts: all
tasks:
- name: checking services
command: "echo {{ item }} is active"
loop:
- nginx
- php74-php-fpm
failed_when: False
register: uistatus
when: inventory_hostname in groups.stg_ui
- set_fact:
my_services: "{{ uistatus.results|default([])|
map(attribute='stdout')|
list }}"
- debug:
var: my_services
gives
ok: [server1] =>
my_services:
- nginx is active
- php74-php-fpm is active
ok: [server2] =>
my_services:
- nginx is active
- php74-php-fpm is active
Then run_once, extract the lists and create the dictionary all_services, e.g.
- set_fact:
all_services: "{{ dict(ansible_play_hosts|zip(stats)) }}"
vars:
stats: "{{ ansible_play_hosts|
map('extract', hostvars, 'my_services')|
list }}"
run_once: true
- debug:
var: all_services
run_once: true
gives
ok: [server1] =>
all_services:
server1:
- nginx is active
- php74-php-fpm is active
server2:
- nginx is active
- php74-php-fpm is active
The dictionary is available to all hosts in the playbook.

Setting become_user conditionally

I am trying to shutdown databases in a loop, the catch is some databases run as a different user and others just run as oracle. I login as oracle user and run the playbook and if the database is run as oracle user it goes through fine. If it is running as a different user I would like to become that user (oracle user has permissions to do that).
Here is my main playbook:
[oracle#ansctrlsrv.localdomain epd3]$ cat test.yml
---
- hosts: testdrive
tasks:
- set_fact:
db_list: "{{ lookup('file', 'vars/' ~ inventory_hostname ~ '.dblist')|from_yaml }}"
- name: Shutdown running databases
include_tasks: shutdowndb.yml
loop: "{{ db_list }}"
DB list is as follows:
[oracle#ansctrlsrv.localdomain epd3]$ cat vars/dbsrv.localdomain.dblist
- ebs1
- ebs2
- ndb1
[oracle#ansctrlsrv.localdomain epd3]$ cat shutdowndb.yml
---
- debug: msg='Shutting down {{ item }}'
- name: Execute shutdown
shell: id "{{ item }}"
register: shutdown_output
become: "{{ item is search('ebs') | ternary('yes','no') }}"
become_user: "{{ item }}"
- debug: msg="{{ shutdown_output.stdout }}"
[oracle#ansctrlsrv.localdomain epd3]$ cat inventory
[testdrive]
dbsrv.localdomain
[oracle#ansctrlsrv.localdomain epd3]$ ansible-playbook -i inventory test.yml
TASK [Execute shutdown] ***
fatal: [dbsrv1.localdomain]: FAILED! => {"changed": false, "module_stderr": "Shared connection to dbsrv1.localdomain closed.\r\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1} ...ignoring
I tried this question on another thread but got closed, so trying another hand after realizing a few issues myself such as being unable to run blocks of code with a loop, etc.
Appreciate any help.
Set become user conditionally
Fix the line
shell: id "{{ item }}"
correct syntax (use shell only when necessary)
command: "id {{ item }}"
The playbook below
- hosts: testdrive
tasks:
- set_fact:
db_list: "{{ lookup('file', 'vars/' ~ inventory_hostname ~ '.dblist')|from_yaml }}"
- name: Shutdown running databases
include_tasks: shutdowndb.yml
loop: "{{ db_list }}"
with the included tasks
$ cat shutdowndb.yml
- debug:
msg:
- "shell: {{ 'shutdown.sh ' ~ item }}"
- "become: {{ item is search('ebs')|ternary('yes', 'no') }}"
- "become_user: {{ item }}"
give
"msg": [
"shell: shutdown.sh ebs1",
"become: yes",
"become_user: ebs1"
]
"msg": [
"shell: shutdown.sh ebs2",
"become: yes",
"become_user: ebs2"
]
"msg": [
"shell: shutdown.sh ndb1",
"become: no",
"become_user: ndb1"
]
Q: "Why the command whoami is still giving oracle rather than ebs1?"
A: Short answer: Because become is not set to True.
Debugging
1) Is it possible to become all of the users in db_list? Yes.
- hosts: test_01
become: no
remote_user: admin
vars:
db_list: ['ebs1', 'ebs2', 'ndb1']
tasks:
- command: whoami
become_user: "{{ item }}"
become: true
register: result
loop: "{{ db_list }}"
- debug:
msg: "{{ result.results|json_query('[].stdout') }}"
give
"msg": [
"ebs1",
"ebs2",
"ndb1"
]
2) Does search and ternary work properly? Yes.
- debug:
msg: "{{ item is search('ebs')|ternary(true, false) }}"
loop: "{{ db_list }}"
gives
"msg": true
"msg": true
"msg": false
3) Does become and become_user work properly?. Yes.
- command: whoami
become_user: "{{ item }}"
become: "{{ item is search('ebs')|ternary(true, false) }}"
register: result
loop: "{{ db_list }}"
- debug:
msg: "{{ result.results|json_query('[].stdout') }}"
give
"msg": [
"ebs1",
"ebs2",
"admin"
]

ansible command for checking service

I am using Ansible and trying to make a simple playbook to check if a service is up.
service... account-daemon.service
part of my playbook which included this is as follows:
- name account daemon service get status
command: systemctl show -p SubState account-daemon
register: status
- debug: msg="{{ status.stout }}"
Please note there is no spaces between playbook.
You can use as below to check the status of services, example below for rscd
- name: populate service facts
service_facts:
- debug:
var: ansible_facts.services
- debug:
msg: "service is running"
when: ansible_facts.services['account-daemon.service'].state == "running"
Output:
ok: [localhost] => {
"msg": "service is running"
}
Reference: https://docs.ansible.com/ansible/latest/modules/service_facts_module.html
Edit:
- name: check rscd
stat:
path: /etc/init.d/rscd
register: serv
- name: populate service facts
service_facts:
- debug:
var: ansible_facts.services
- debug:
msg: "rscd is running"
when: serv.stat.exists and ansible_facts.services['rscd.service'].state == "running"

Ansible conditional handlers for a task?

FYI, I'm running my Ansible playbook in "pull-mode" not push mode. Therefore, my nodes will publish the results of their task via Hipchat.
With that said, I have a task that installs RPMs. When the installs are successful, the nodes notify via Hipchat that the task was successfully run. Now, in the event that a task fails, i force it to notify hipchat w/ the "--force-handlers" paramter. My question, is there a way to call a particular handler depending on the outcome of the task?
Task
- name: Install Perl modules
command: sudo rpm -Uvh {{ rpm_repository }}/{{ item.key }}-{{ item.value.svn_tag }}.rpm --force
with_dict: deploy_modules_perl
notify: announce_hipchat
Handler
- name: announce_hipchat
local_action: hipchat
from="deployment"
token={{ hipchat_auth_token }}
room={{ hipchat_room }}
msg="[{{ ansible_hostname }}] Successfully installed RPMs!"
validate_certs="no"
In this case, I use multiple handlers. See following example :
file site.yml
- hosts: all
gather_facts: false
force_handlers: true
vars:
- cmds:
echo: hello
eccho: hello
tasks:
- name: echo
command: "{{ item.key }} {{ item.value }}"
register: command_result
with_dict: "{{ cmds }}"
changed_when: true
failed_when: false
notify:
- "hipchat"
handlers:
- name: "hipchat"
command: "/bin/true"
notify:
- "hipchat_succeeded"
- "hipchat_failed"
- name: "hipchat_succeeded"
debug:
var: "{{ item }}"
with_items: "{{ command_result.results | selectattr('rc', 'equalto', 0) | list }}"
- name: "hipchat_failed"
debug:
var: "{{ item }}"
with_items: "{{ command_result.results | rejectattr('rc', 'equalto', 0) | list }}"
Use command
ansible-playbook -c local -i "localhost," site.yml
CAUTION: use test filter 'equalsto' added in jinja2 2.8

Resources