Ansible playbook to check OS and given mount points - ansible

Below is my playbook to check to verify OS and Mount points. Getting below error and couldn't debug it. The issue seems to be with the later part "Verify Mount points"
---
- hosts: all
gather_facts: true
vars:
M1: ['RedHat','7']
M2: ['/u01','/u02']
tasks:
- name: "Verify OS"
when: >
not ((ansible_os_family == M1[0] and ansible_distribution_major_version == M1[1]))
fail:
msg: "OS not supported"
- name: "Verify Mount Points"
with_items: ansible_mounts
when: >
not ((item.mount == M2[0] and item.mount == M2[1]))
fail:
msg: "Mount Point doesn't exist"
Output:
ansible-playbook -i dbservers test.yml
PLAY [all] **********************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************
ok: [192.168.0.107]
ok: [192.168.0.109]
TASK [Verify OS] ****************************************************************************************************************************************
skipping: [192.168.0.109]
skipping: [192.168.0.107]
TASK [Verify Mount Points] ******************************************************************************************************************************
fatal: [192.168.0.109]: FAILED! => {"msg": "The conditional check 'not ((item.mount == M2[0] and item.mount == M2[1]))\n' failed. The error was: error while evaluating conditional (not ((item.mount == M2[0] and item.mount == M2[1]))\n): 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'mount'\n\nThe error appears to be in '/etc/ansible/test.yml': line 14, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: \"Verify Mount Points\"\n ^ here\n"}
fatal: [192.168.0.107]: FAILED! => {"msg": "The conditional check 'not ((item.mount == M2[0] and item.mount == M2[1]))\n' failed. The error was: error while evaluating conditional (not ((item.mount == M2[0] and item.mount == M2[1]))\n): 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'mount'\n\nThe error appears to be in '/etc/ansible/test.yml': line 14, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: \"Verify Mount Points\"\n ^ here\n"}
PLAY RECAP **********************************************************************************************************************************************
192.168.0.107 : ok=1 changed=0 unreachable=0 failed=1 skipped=1 rescued=0 ignored=0
192.168.0.109 : ok=1 changed=0 unreachable=0 failed=1 skipped=1 rescued=0 ignored=0

First, you need to set gather_facts: true when using ansible defined variables.
Second, try to focus on the main issue here. Something along these lines should work:
---
- hosts: all
gather_facts: true
vars:
M1: ['RedHat','7']
M2: ['/u01','/u02']
tasks:
- name: "Verifying os and mount points"
debug:
msg: "{{ item }}"
loop:
- ansible_os_family
- ansible_distribution_major_version
- ansible_mounts
when:
- not item.ansible_os_family == 'M1[0]' # you could also replace 'M1[0]' with 'Redhat'.
- item.ansible_distribution_major_version == 'M1[1]'. # you could also replace 'M1[1]' with '7'.
- fail:
msg: "mount points not correctly"
loop: ansible_mounts
when:
- item.mount is defined
- item.mount != 'M2[0]'
- item.mount == 'M2[1]'
You shouldn't specify multiple fails in a single task, as fail is it's own task.

Related

how can I complete correctly ansible playbook to get info what i want

I'm very new with ansible so I need help to complete my first ansible playbook
I need to get the results from file created below logs directory.
I also need to input container name which is migrated to find results file named with container and starts with 1 and 3 (2 results of files need)
can't find which part got wrong.
Please help me out
Thank you in advance.
---
- name : find the results for migration ended
hosts: newmigservers
tasks:
- pause:
prompt: "what is the container name?"
echo: yes
register: result
- set_fact:
container: "{{ result.user_input }}"
- debug:
var: container
- name: find where the container is
shell: "grep -lr '{{ container }}'"
args:
chdir: "logs/"
register: grep_output
- name: cat 1,3 file for the results
command: cat {{ grep_output }}
register: results
PLAY [find the results for migration ended] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [1.1.1.1]
ok: [2.2.2.2]
ok: [3.3.3.3]
TASK [pause] ********************************************************************************************************************************************************************************************************************************
[pause]
what is the container name?:
ok: [1.1.1.1]
TASK [set_fact] *****************************************************************************************************************************************************************************************************************************
ok: [1.1.1.1]
fatal: [2.2.2.2]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'result' is undefined\n\nThe error appears to have been in '/home/amber/results.yml': line 9, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n register: result\n - set_fact:\n ^ here\n"}
fatal: [3.3.3.3]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'result' is undefined\n\nThe error appears to have been in '/home/amber/results.yml': line 9, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n register: result\n - set_fact:\n ^ here\n"}
TASK [debug] ********************************************************************************************************************************************************************************************************************************
ok: [1.1.1.1] => {
"container": "amber_test_file_size.txt"
}
TASK [find where the container is] **********************************************************************************************************************************************************************************************************
skipping: [2.2.2.2]
TASK [cat 1,3 file for the results] *********************************************************************************************************************************************************************************************************
skipping: [3.3.3.3.]
to retry, use: --limit #/home/amber/results.retry
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
1.1.1.1 : ok=4 changed=0 unreachable=0 failed=0
2.2.2.2 : ok=1 changed=0 unreachable=0 failed=1
3.3.3.3 : ok=1 changed=0 unreachable=0 failed=1
Pause runs only once for the play batch, causing only the first server in the batch (1.1.1.1 in my case) to pick the variable.
You can workaround this by adding serial to your playbook as below:
---
- name : find the results for migration ended
hosts: newmigservers
serial: 1
tasks:
- pause:
prompt: "what is the container name?"
echo: yes
register: result
- set_fact:
container: "{{ result.user_input }}"
- debug:
var: container

Run a handler play and exit play if rc == 0 in ansible

Hi is there a way I can run a handler play then exit the play if rc == 0. It can only do is exit the play using failed_when and proceed if rc != 0. I can't make notify: Service Guard execute. Been play with other approach like creating 2 play notify and exit no luck.
- name: Exit SG server from play
command: /usr/local/cmcluster/bin/cmversion
register: sg_check
notify: Service Guard
failed_when: sg_check.rc == 0
Here is new code I tried
- name: Check if Service Gurad then exit
command: /usr/local/cmcluster/bin/cmversion
register: sg_check
notify: Service Guard
changed_when: sg_check.rc == 0
ignore_errors: true
- meta: end_play
when: sg_check.rc == 0
but I get this:
ERROR! The conditional check 'sg_check.rc == 0' failed. The error was: error while evaluating conditional (sg_check.rc == 0): 'sg_check' is undefined
The error appears to have been in '/home/ansible/linuxpatchingv2/roles/applyPatch/tasks/main.yml': line 9, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
ignore_errors: true
meta: end_play
^ here
Q: "Run a handler play then exit the play if rc == 0"
A: This is not possible to accomplish in one task because a task can't be both changed and failed at the same time. These two actions must be split. For example, in the playbook below the command will succeed, notify the handler, and end the play
shell> cat pb.yml
- hosts: localhost
gather_facts: false
tasks:
- command: "{{ cmd|default('/bin/true') }}"
register: sg_check
notify: Service Guard
changed_when: sg_check.rc == 0
ignore_errors: true
- meta: end_play
when: sg_check.rc == 0
- debug:
msg: Continue
handlers:
- name: Service Guard
debug:
msg: Service Guard notified
gives (abridged)
shell> ansible-playbook pb.yml
...
RUNNING HANDLER [Service Guard] ****
ok: [localhost] =>
msg: Service Guard notified
PLAY RECAP ****
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The same playbook will continue if the command fails. For example
shell> ansible-playbook pb.yml -e "cmd=/bin/false"
PLAY [localhost] ****
TASK [command] ****
fatal: [localhost]: FAILED! => changed=false
cmd:
- /bin/false
delta: '0:00:00.003035'
end: '2020-08-24 09:33:22.039762'
msg: non-zero return code
rc: 1
start: '2020-08-24 09:33:22.036727'
stderr: ''
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
...ignoring
TASK [debug] ****
ok: [localhost] =>
msg: Continue
PLAY RECAP ****
localhost: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1

Ansible set_facts based on OS version not working

I want to set the patch based on the OS version. came up with this playbook in Ansible version 2.8. but its giving The task includes an option with an undefined variable. error message in the debug line.
---
- hosts: all
gather_facts: yes
vars:
patch_name_8: 'centos8-updates'
patch_name_7: 'centos7-updates'
tasks:
- name: Set fact for CentOS 7
set_fact:
install_patch_name: "{{ patch_name_7 }}"
when: ansible_distribution_major_version == 7
- name: Set fact for CentOS 8
set_fact:
install_patch_name: "{{ patch_name_8 }}"
when: ansible_distribution_major_version == 8
- name: patch name display
debug:
msg: "install {{ install_patch_name }}"
How to set the install_patch_name variable value based on the OS version?
adding the error message:
TASK [patch name display] ************************************************************************************************************
fatal: [host01]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'install_patch_name' is undefined\n\nThe error appears to be in 't.yaml': line 23, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n
- name: patch name display\n ^ here\n"}
thanks
TLDR;
Use
when: ansible_distribution_major_version == "8"
or
when: ansible_distribution_major_version | int == 8
Explanation
Note: all following examples have been played against a centos:8 docker image.
The fact your are looking after is returned as a string :
[root#f6408271fc8c ~]# ansible localhost -m setup -a filter=ansible_distribution_major_version
localhost | SUCCESS => {
"ansible_facts": {
"ansible_distribution_major_version": "8"
},
"changed": false
}
Variables keep their types when using comparison and need to be correctly casted if need be, as demonstrated by the following playbook.
---
- hosts: localhost
tasks:
- name: default compare
debug:
msg: Comparison is true
when: ansible_distribution_major_version == 8
- name: compare as strings
debug:
msg: Comparison is true
when: ansible_distribution_major_version == "8"
- name: compare as ints
debug:
msg: Comparison is true
when: ansible_distribution_major_version | int == 8
Which gives
[root#f6408271fc8c ~]# ansible-playbook play.yml
PLAY [localhost] **************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [localhost]
TASK [default compare] ********************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [compare as strings] *****************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Comparison is true"
}
TASK [compare as ints] ********************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Comparison is true"
}
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

Ansible error: The task includes an option with an undefined variable

Below is how my complete helpA.yml playbook looks like:
- hosts: localhost
tasks:
- name: "Construct File Path {{ inventory_hostname }} before Deployment."
tags: validate
include_vars:
file: "{{ item }}"
with_fileglob:
- "vars/{{ Layer }}_*.yaml"
- name: "set_fact"
tags: validate
set_fact:
fpath_APP: "{{ fpath_APP + [ BASEPATH ~ '/' ~ vars[item.split('.')[1]] ~ '/' ~ item | basename ] }}"
when: Layer == 'APP'
with_items:
- "{{ Source_Filenames.split(',') }}"
vars:
fpath_APP: []
- debug: var=fpath_{{ Layer }}
I'm getting the below syntax error running the yml.
$ ansible-playbook /app/helpA.yml --tags validate -e
"Source_Filenames=/tmp/logs/filename1.src,/tmp/logs/33211.sql,/app/Jenkins/file1.mrt
Layer=APP" [WARNING]: provided hosts list is empty, only localhost is
available. Note that the implicit localhost does not match 'all'
PLAY [localhost]
TASK [Construct File Path localhost before Deployment.]
************************************************************************************************* ok: [localhost] => (item=/app/vars/APP_BASE_vars.yaml)
TASK [set_fact]
*************************************************************************************************************************************************************** fatal: [localhost]: FAILED! => {"msg": "The task includes an option
with an undefined variable. The error was: 'dict object' has no
attribute u'src'\n\nThe error appears to be in '/app/helpA.yml': line
12, column 6, but may\nbe elsewhere in the file depending on the exact
syntax problem.\n\nThe offending line appears to be:\n\n\n - name:
\"set_fact\"\n ^ here\n"}
PLAY RECAP
******************************************************************************************************************************************************************** localhost : ok=1 changed=0 unreachable=0
failed=1 skipped=0 rescued=0 ignored=0
I'm on the latest version on of ansible and python 2.7.5

Ansible commands to pull file from remote server and prevent if exist already

Using Ansible, to host server(172.19.113.104) I want to copy files ( ansibletest & MariaDB-client-5.1.67-122.el5.x86_64.rpm ) from remote server(172.19.113.87), but it should not copy if file exist already.
I tried like below but throwing error:
- hosts: webservers
vars:
ip: 172.19.113.87
tasks:
- name: this is to pull
local_action: shell 'ls /opt/ansibletest'
register: result
- name: ts2
synchronize: src={{ item }} dest=/opt/ mode=pull
with_items:
- "/opt/ansibletest"
- "/opt/MariaDB-client-5.1.67-122.el5.x86_64.rpm"
when: result.shell.exists == true
[root#rbtstaging ansible]# ansible-playbook fetch.yml
PLAY [webservers] ************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************
ok: [172.19.113.87]
TASK [this is to pull] *******************************************************************************************************************************************
changed: [172.19.113.87]
TASK [ts2] *******************************************************************************************************************************************************
fatal: [172.19.113.87]: FAILED! => {"msg": "The conditional check 'result.stat.exists == True' failed. The error was: error while evaluating conditional (result.stat.exists == True): 'dict object' has no attribute 'stat'\n\nThe error appears to have been in '/RND/sudhir/ansible/fetch.yml': line 9, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: ts2\n ^ here\n"}
to retry, use: --limit #/RND/sudhir/ansible/fetch.retry
PLAY RECAP *******************************************************************************************************************************************************
172.19.113.87 : ok=2 changed=1 unreachable=0 failed=1
Note: Files exist with permission
You can prepend the fetch (fetch file from remote server - copy will send the file to the remove server) by a local "stat" operation, and check for existence of the local file.
local_action:
module: stat
path: /path/to/local/file
register: local_file
become: no
fetch:
src: /path/to/remote/file
dest: /path/to/local/file
flat: yes
when: local_file.stat.exists == False

Resources