ansible *when* say : "error while evaluating conditional" - ansible

I try to do something like that:
I have this playbook
---
- hosts: all
vars:
user: myuser
venv_name: venv
only_deploy_code: "yes"
roles:
- my_venv
In roles/my_venv/tasks/main.yml::
---
- name: pip Install packages into virtualenv
pip: name={{ item }} virtualenv="{{ home }}/{{ venv_name }}" virtualenv_site_packages="yes"
with_items:
- PyYAML
- numexpr
sudo_user: "{{ user }}"
sudo: true
when: only_code_deploy == "no"
but I get this error::
TASK: [akd_venv | pip Install packages into virtualenv]
***********************
fatal: [vagrant] => error while evaluating conditional: only_code_deploy == "no"

Just try to omit the quotes around the yes and change your when statement like this:
- hosts: all
gather_facts: no
vars:
only_deploy_code: yes
tasks:
- debug:
msg: "This is yes message"
when: not only_deploy_code
Tested on the local machine like this:
ansible-playbook -i "localhost," test.yml -c local
with the output:
PLAY ***************************************************************************
TASK [debug] *******************************************************************
skipping: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=0
I think this is the expected behaviour that you want, just modified the when statement if you want to skip it for no instead of yes like this:
when: only_deploy_code

Related

How to calculate ansible_uptime_seconds and output this in os.csv

I am trying to create a csv file that can be used to review certain systems details. One of these items is the system uptime, which is reflected in unix seconds. But in the os.csv output file I would like to see it as days, HH:MM:SS.
Below my yaml script:
---
- name: playbook query system and output to file
hosts: OEL7_systems
vars:
output_file: os.csv
tasks:
- block:
# For permisison setup.
- name: get current user
command: whoami
register: whoami
run_once: yes
- name: clean_file
copy:
dest: "{{ output_file }}"
content: 'hostname,distribution,version,release,uptime'
owner: "{{ whoami.stdout }}"
run_once: yes
- name: fill os information
lineinfile:
path: "{{ output_file }}"
line: "{{ ansible_hostname }},\
{{ ansible_distribution }},\
{{ ansible_distribution_version }},\
{{ ansible_distribution_release }},\
{{ ansible_uptime_seconds }}"
# Tries to prevent concurrent writes.
throttle: 1
delegate_to: localhost
Any help is appreciated.
tried several conversions but can't get it to work.
There is actually a (somewhat hard to find) example in the official documentation on complex data manipulations doing exactly what you are looking for (check at the bottom of the page).
Here is a full example playbook to run it on localhost
---
- hosts: localhost
tasks:
- name: Show the uptime in days/hours/minutes/seconds
ansible.builtin.debug:
msg: Uptime {{ now().replace(microsecond=0) - now().fromtimestamp(now(fmt='%s') | int - ansible_uptime_seconds) }}
which gives on my machine:
PLAY [localhost] ************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************
ok: [localhost]
TASK [Show the uptime in days/hours/minutes/seconds] ************************************************************************************************************
ok: [localhost] => {
"msg": "Uptime 1 day, 3:56:34"
}
PLAY RECAP ******************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

How to execute on multiple hosts in ansible

I have a script that will execute in two parts. First it will execute on localhost and query a database table to get a hostname. second part of the script should run on the host which was registered in the query before. I am not able to set the host with the set_fact I did in the first part of the code.
this is what iam trying to do:
- hosts: localhost
gather_facts: false
become: yes
become_user: oracle
vars_files:
- vars/main.yml
tasks:
- name: Get new hostname
tempfile:
state: file
register: tf
- name: create sql file
template:
src: get_hostname.sql.j2
dest:"{{ tf.path }}"
mode: 0775
- name: login
command:
argv:
- "sqlplus"
- -s
- "#{{ tf.path }}"
environment:
ORACLE_HOME: "oracle/home"
register: command_out
- set_fact:
NEW_HOST: "{{ command_out.stdout }}"
- hosts: "{{ NEW_HOST }}"
gather_facts: false
become: yes
become_user: oracle
vars_file:
- vars/main.yml
tasks:
- name: debug
command: hostname
register: new_host_out
- debug:
msg: "new host is {{ new_host_out.stdout }}"
Everything works fine in the first part of the code, but errors out at the second part saying it cannot find the NEW_HOST.
Use hostvars to reference such a variable. Create a dummy host to keep this variable. For example, given the inventory
shell> cat hosts
dummy
[test]
test_11
test_12
test_13
The playbook creates the variable. See Delegated facts
shell> cat pb.yml
- hosts: localhost
tasks:
- set_fact:
NEW_HOST: test_12
delegate_to: dummy
delegate_facts: true
- debug:
var: hostvars.dummy.NEW_HOST
- hosts: "{{ hostvars.dummy.NEW_HOST }}"
gather_facts: false
tasks:
- debug:
var: inventory_hostname
gives
shell> ansible-playbook pb.yml
PLAY [localhost] ****************************************************************************
TASK [set_fact] *****************************************************************************
ok: [localhost -> dummy]
TASK [debug] ********************************************************************************
ok: [localhost] =>
hostvars.dummy.NEW_HOST: test_12
PLAY [test_12] ******************************************************************************
TASK [debug] ********************************************************************************
ok: [test_12] =>
inventory_hostname: test_12
PLAY RECAP **********************************************************************************
localhost: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_12 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
You can use localhost for this purpose as well. The playbook below works as expected
- hosts: localhost
tasks:
- set_fact:
NEW_HOST: test_12
- hosts: "{{ hostvars.localhost.NEW_HOST }}"
gather_facts: false
tasks:
- debug:
var: inventory_hostname

Play recap and ignored=1 in Ansible

I am checking whether all services related to a docker-compose.yml are running on a system. The code snippet shown below.
---
- name:
shell: docker-compose ps -q "{{ item }}"
register: result
ignore_errors: yes
The code above works as expected. I have to ignore errors otherwise Ansible will not complete. The following result shows ignored=1
PLAY RECAP *******************************************************************************************************
192.168.50.219 : ok=38 changed=12 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
If this completes successfully I want to run a subsequent playbook but don't know how to specify ignored=1 correctly.
---
- name:
include_tasks: do_other_things.yml
when: ignored is false
How do I get the result from PLAY RECAP into something I can test with?
A better idea than trying to cope with the error returned by docker compose ps when the container does not exist would be to use the purposed module: docker_container_info to achieve the same.
Given the playbook:
- hosts: localhost
gather_facts: no
tasks:
- docker_container_info:
name: "{{ item }}"
register: containers
loop:
- node1 # exists
- node404 # does not exists
- debug:
msg: "`{{ item.item }}` is not started"
loop: "{{ containers.results }}"
loop_control:
label: "{{ item.item }}"
when: not item.exists
This would yield:
TASK [docker_container_info] *************************************************
ok: [localhost] => (item=node1)
ok: [localhost] => (item=node404)
TASK [debug] *****************************************************************
skipping: [localhost] => (item=node1)
ok: [localhost] => (item=node404) =>
msg: `node404` is not started

Running Environment variable at Ansible Play level question

I have following commands declared in main playbook file:
---
- name: Install config
hosts: all
become: yes
become_method: sudo
become_user: root
roles:
- initial_config
environment:
http_proxy: http://{{ProxyHost}}:{{ProxyPort}}
https_proxy: http://{{ProxyHost}}:{{ProxyPort}}
ftp_proxy: http://{{ProxyHost}}:{{ProxyPort}}
Inside my group_vars/ all: I have declared these parameter:
ProxyHost: proxy.test.com
ProxyPort: 9999
no_proxy: 'test.com'
But I am receiving error when i run main playbook locally saying:
ERROR! Syntax Error while loading YAML.
found unexpected end of stream
The play below
shell> cat group_vars/all
ProxyHost: proxy.test.com
ProxyPort: 9999
no_proxy: test.com
shell> cat pb.yml
- hosts: test_01
environment:
http_proxy: "http://{{ ProxyHost }}:{{ ProxyPort }}"
https_proxy: "http://{{ ProxyHost }}:{{ ProxyPort }}"
ftp_proxy: "http://{{ ProxyHost }}:{{ ProxyPort }}"
tasks:
- shell: set | grep proxy
register: result
- debug:
var: result.stdout_lines
gives
shell> ansible-playbook pb.yml
PLAY [test_01] **********
TASK [shell] ************
changed: [test_01]
TASK [debug] ************
ok: [test_01] => {
"result.stdout_lines": [
"SUDO_COMMAND='/bin/sh -c echo BECOME-SUCCESS-hhojceebldohrrfvivcndrtjtvtrzgfg ; http_proxy=http://proxy.test.com:9999 https_proxy=http://proxy.test.com:9999 ftp_proxy=http://proxy.test.com:9999 /usr/local/bin/python3.7 /home/admin/.ansible/tmp/ansible-tmp-1588775688.2160842-43227888427690/AnsiballZ_command.py'",
"ftp_proxy=http://proxy.test.com:9999",
"http_proxy=http://proxy.test.com:9999",
"https_proxy=http://proxy.test.com:9999"
]
}
PLAY RECAP **********
test_01: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

ansible delegation to other hosts

I use ansible 2.1 and I want to run a command to a group of hosts, using delegate_to. I use localhost as the host param and I want to delegate a “touch” command to both of cls hosts
I have the following
---
- hosts: ansible
# gather_facts: yes
tasks:
- debug: var=groups.cls
- name: touch a file to running host
shell: echo {{ item }} >> /tmp/{{ inventory_hostname }}
delegate_to: "{{ item }}"
with_items: "{{ groups.cls }}"
with output:
[root#ansible control]# ansible-playbook -i inventory test.yml
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [ansible]
TASK [debug] *******************************************************************
ok: [ansible] => {
"groups.cls": [
"cls-host-1",
"cls-host-2"
]
}
TASK [touch a file to running host] ********************************************
changed: [ansible -> cls-host-1] => (item=cls-host-1)
changed: [ansible -> cls-host-2] => (item=cls-host-2)
PLAY RECAP *********************************************************************
ansible : ok=3 changed=1 unreachable=0 failed=0
but the touch is done only on the first host:
[root#cls-host-1 ~]# more /tmp/ansible
cls-host-1
cls-host-2
Is anything wrong? Can I delegate the command with any other way?
I've tested a variation of your playbook using Ansible 2.4.0.0:
#!/usr/bin/env ansible-playbook
- hosts: stretch.fritz.box
tasks:
- name: touch
shell: echo {{item}} >>/tmp/{{inventory_hostname}}
delegate_to: "{{item}}"
with_items:
- jessie.fritz.box
- short.fritz.box
This is working fine: the touch is performed on jessie and short
jessie$ cat /tmp/stretch.fritz.box
jessie.fritz.box
short$ cat /tmp/stretch.fritz.box
short.fritz.box
Perhaps this feature was introduced in Ansible between 2.1 and 2.4.

Resources