How can I print out the actual values of all the variables used by an Ansible playbook? - variables

An answer on StackOverflow suggests using - debug: var=vars or - debug: var=hostvars to print out all the variables used by an Ansible playbook.
Using var=hostvars did not print out all of the variables. But I did get all of the variables printed out when I added the following lines to the top of the main.yml file of the role executed by my playbook:
- name: print all variables
debug:
var=vars
The problem is that the values of the variables printed out are not fully evaluated if they are dependent on the values of other variables. For example, here is a portion of what gets printed out:
"env": "dev",
"rpm_repo": "project-subproject-rpm-{{env}}",
"index_prefix": "project{{ ('') if (env=='prod') else ('_' + env) }}",
"our_server": "{{ ('0.0.0.0') if (env=='dev') else ('192.168.100.200:9997') }}",
How can I get Ansible to print out the variables fully evaluated like this?
"env": "dev",
"rpm_repo": "project-subproject-rpm-dev",
"index_prefix": "project_dev",
"our_server": "0.0.0.0",
EDIT:
After incorporating the tasks section in the answer into my playbook file and removing the roles section, my playbook file looks like the following (where install-vars.yml contains some variable definitions):
- hosts: all
become: true
vars_files:
- install-vars.yml
tasks:
- debug:
msg: |-
{% for k in _my_vars %}
{{ k }}: {{ lookup('vars', k) }}
{% endfor %}
vars:
_special_vars:
- ansible_dependent_role_names
- ansible_play_batch
- ansible_play_hosts
- ansible_play_hosts_all
- ansible_play_name
- ansible_play_role_names
- ansible_role_names
- environment
- hostvars
- play_hosts
- role_names
_hostvars: "{{ hostvars[inventory_hostname].keys() }}"
_my_vars: "{{ vars.keys()|
difference(_hostvars)|
difference(_special_vars)|
reject('match', '^_.*$')|
list|
sort }}"
When I try to run the playbook, I get this failure:
shell> ansible-playbook playbook.yml
SSH password:
SUDO password[defaults to SSH password]:
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.100.111]
TASK [debug] *******************************************************************
fatal: [192.168.100.111]: FAILED! => {"failed": true, "msg": "lookup plugin (vars) not found"}
to retry, use: --limit #/usr/local/project-directory/installer-1.0.0.0/playbook.retry
PLAY RECAP *********************************************************************
192.168.100.111 : ok=1 changed=0 unreachable=0 failed=1

The minimal playbook below
shell> cat pb.yml
- hosts: localhost
gather_facts: false
vars:
test_var1: A
test_var2: "{{ test_var1 }}"
tasks:
- debug:
var: vars
reproduces the problem you described. For example,
shell> ansible-playbook pb.yml | grep test_var
test_var1: A
test_var2: '{{ test_var1 }}'
Q: How can I print out the actual values of all the variables used by an Ansible playbook?
A: You can get the actual values of the variables when you evaluate them. For example,
shell> cat pb.yml
- hosts: localhost
gather_facts: false
vars:
test_var1: A
test_var2: "{{ test_var1 }}"
tasks:
- debug:
msg: |-
{% for k in _my_vars %}
{{ k }}: {{ lookup('vars', k) }}
{% endfor %}
vars:
_special_vars:
- ansible_dependent_role_names
- ansible_play_batch
- ansible_play_hosts
- ansible_play_hosts_all
- ansible_play_name
- ansible_play_role_names
- ansible_role_names
- environment
- hostvars
- play_hosts
- role_names
_hostvars: "{{ hostvars[inventory_hostname].keys() }}"
_my_vars: "{{ vars.keys()|
difference(_hostvars)|
difference(_special_vars)|
reject('match', '^_.*$')|
list|
sort }}"
gives the evaluated playbook's vars
msg: |-
test_var1: A
test_var2: A

Looking for an answer to the same question, I found the following solution from this link:
- name: Display all variables/facts known for a host
debug:
var: hostvars[inventory_hostname]
tags: debug_info

Related

extract password as variable

new to ansible ..
Trying to get this result:
variable tgt_wls_pwd = the result of env1.wls_pwd = 1234
variable tgt_apps_pwd = the result of env1.apps_pwd = 5678
The unencrypted password file vault.yml
env1:
wls_pwd: 1234
apps_pwd: 5678
Playbook
ansible-playbook tgt-app-stop.yml --extra-vars="target_clone=env1"
- name: Stop Application Tier(s) process
hosts: " {{ target_clone }}-app01"
any_errors_fatal: true
remote_user: ansible
become: yes
become_user: install
roles:
- oraapp-stop
vars_files:
- vault.yml
tasks:
- set_fact:
target_clone: "{{ target_clone }}"
vars:
# tgt_wls_pwd: "{{ target_clone }}||{{ wls_pwd }}"
# tgt_apps_pwd: "{{ target_clone }}||{{ apps_pwd }}"
# tgt_wls_pwd: "{{ target_clone ['{{ wls_pwd }}'] }}"
# tgt_apps_pwd: "{{ target_clone ['{{ apps_pwd }}'] }}"
tgt_wls_pwd: "{{ target_clone.wls_pwd }}"
tgt_apps_pwd: "{{ target_clone.apps_pwd }}"
I've tried quite a few permutations
target_clone is an extra variable passed to the playbook when running.
Thanks.
You'll need the vars lookup plugin. See
shell> ansible-doc -t lookup vars
For example, given the file
shell> cat vault.yml
env1:
wls_pwd: 1234
apps_pwd: 5678
and the inventory
shell> cat hosts
env1-app01
The playbook
shell> cat tgt-app-stop.yml
- hosts: "{{ target_clone }}-app01"
gather_facts: false
vars_files:
- vault.yml
vars:
tgt_wls_pwd: "{{ lookup('vars', target_clone).wls_pwd }}"
tgt_apps_pwd: "{{ lookup('vars', target_clone).apps_pwd }}"
tasks:
- debug:
msg: |
tgt_wls_pwd: {{ tgt_wls_pwd }}
tgt_apps_pwd: {{ tgt_apps_pwd }}
gives
shell> ansible-playbook tgt-app-stop.yml -e "target_clone=env1"
PLAY [env1-app01] ****************************************************************************
TASK [debug] *********************************************************************************
ok: [env1-app01] =>
msg: |-
tgt_wls_pwd: 1234
tgt_apps_pwd: 5678
PLAY RECAP ***********************************************************************************
env1-app01: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

add variables from Ansible inventory file to a dynamic inventory

i have an inventory file containing 200 servers and thier respective variables as shown in a sample below:
[myhost1.mrsh.com]
myhost1.mrsh.com ORACLE_HOME=/u/orahome12/middleware/12c_db1 ansible_user=wladmin
[myhost2.mrsh.com]
myhost2.mrsh.com ORACLE_HOME=/u/orahome12/middleware/12c_db1 ansible_user=wladmin
..........
........
i ask the user to enter any hostname which is passed to hostnames variable as below:
ansible-playbook /web/playbooks/automation/applycpupatch/applycpupatch.yml -i /web/playbooks/automation/applycpupatch/applycpupatch.hosts -f 5 -e action=status -e hostnames='myhost1
myhost2' -e patch_file='p33286132_122130_Generic.zip'
if myhost1 is present in the applycpupatch.hosts file i then wish to create a dynamic inventory using add_host having only myhost1 and its variables like ORACLE_HOME
Below is my code:
- name: "Play 1 - Set Destination details"
hosts: all
tasks:
- add_host:
name: "{{ item | upper }}"
groups: dest_nodes
ansible_user: "{{ hostvars[item + '*'].ansible_user }}"
ORACLE_HOME: "{{ hostvars[item + '*'].ORACLE_HOME }}"
when: inventory_hostname | regex_search(item)"
with_items: "{{ hostnames.split() }}"
Unfortunately, i get the error as below:
TASK [add_host] ****************************************************************
Saturday 20 November 2021 19:05:38 -0600 (0:00:00.059) 0:00:23.532 *****
[0;31mfatal: [myhost222.mrsh.com]: FAILED! => {"msg": "The conditional check 'inventory_hostname | regex_search(item)\"' failed. The error was: template error while templating string: unexpected char '\"' at 45. String: {% if inventory_hostname | regex_search(item)\" %} True {% else %} False {% endif %}\n\nThe error appears to be in '/web/playbooks/automation/applycpupatch/applycpupatch.yml': line 36, 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 - add_host:\n ^ here\n"}[0m
I also tried the below but it fails with the error.
ORACLE_HOME: "{{ hostvars['all'][item + '*'].ORACLE_HOME }}"
Thus my dynamic inventory constructed runtime dest_nodes in this example should have ONLY the below.
myhost1.mrsh.com ORACLE_HOME=/u/orahome12/middleware/12c_db1 ansible_user=wladmin
myhost2.mrsh.com ORACLE_HOME=/u/orahome12/middleware/12c_db1 ansible_user=wladmin
i dont understand very well what do you want, but you have lot of errors to fix in your playbook:
1- launch your playbook with -e hostnames='myhost1,myhost2'
2- fix your playbook: you have to test the result of your regex_search, use the variable inventory_hostname and use split(','):
a sample
- name: "Play 1 - Set Destination details"
hosts: all
tasks:
- debug:
msg: "{{ item }} - {{ hostvars[inventory_hostname].ORACLE_HOME }}"
when: (inventory_hostname | regex_search(item)) != ''
with_items: "{{ hostnames.split(',') }}"

Ansible Unable to assign variable the value to another variable

If the user does not pass dest_path parameter or if dest_path is EMPTY i.e contains only whitespaces then dest_path should be the same as source_file value.
Below is my playbook:
---
- name: "Play 1"
hosts: localhost
any_errors_fatal: false
gather_facts: false
tasks:
- set_fact:
dest_path: "{{ dest_path | default(source_file) }}"
- set_fact:
dest_path: "{{ source_file }}"
when: dest_path | length == 0
- debug:
msg: "DESTINATION PATH IS: {{ dest_path }} and the SOURCE PATH is: {{ source_file }}"
This is how you run this playbook:
ansible-playbook -i /web/playbooks/allmwhosts.hosts /web/playbooks/test.yml -e '{ source_file: /web/bea_apps/CURRENT }' -e dest_path=
In the above example when the user does not specify any value for dest_path I m expecting dest_path should be source_file i.e /web/bea_apps/CURRENT
However, as you can see in the output below that is not the case:
Output:
PLAY [Play 1] *******************
TASK [set_fact] **************************************************************************************
ok: [localhost]
TASK [set_fact] **************************************************************************************
ok: [localhost]
TASK [debug] *****************************************************************************************
ok: [localhost] => {
"msg": "DESTINATION PATH IS: and the SOURCE PATH is: /web/bea_apps/CURRENT"
}
PLAY RECAP *******************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
Can you please suggest?
The extra variable that you pass as parameter is overriding the variable in set_fact variable dest_path. Below is the working code. In set_fact instead of dest_path I replaced with path.
---
- name: "Play 1"
hosts: localhost
any_errors_fatal: false
gather_facts: false
tasks:
- set_fact:
path: "{{ source_file }}"
when: (dest_path is not defined) or (dest_path | length == 0)
- set_fact:
path: "{{ dest_path }}"
when: (dest_path is defined) or (dest_path | length != 0)
- debug:
msg: "DESTINATION PATH IS: {{ path }} and the SOURCE PATH is: {{ source_file }}"

How can we access set_fact of a remote host to a localhost in Ansible

I have a remote host called dest_nodes which has a set_fact called mailsub
I wish to get the value of mailsub ina different localhost play and i use map('extract') for the same.
However, I dont get the value assigned to set_fact in localhost when i debug MAILSUBISX.
Below is my playbook:
- name: "Play 2 Configure Destination nodes"
hosts: dest_nodes
any_errors_fatal: True
tasks:
- set_fact:
mailsub: "WebSphere | on IP and NUMBER OF PROFILES"
- name: "Play 3-Construct inventory"
hosts: localhost
any_errors_fatal: True
gather_facts: no
tasks:
- debug:
msg: "MAILSUBISX:{{ groups['dest_nodes'] | map('extract', hostvars, 'mailsub') }}"
- set_fact:
mailfrom: "creator#myshop.com"
Here is the Error received when I run the playbook and debug the variable in a different host:
Output:
"msg": "MAILSUBISX:<generator object do_map at 0x7fba4b5698c0>"
I also tried the following:
- debug:
msg: "MAILSUBISX:{{ hostvars[groups['dest_nodes']]['mailsub'] }}"
and
- debug:
msg: "MAILSUBISX:{{ hostvars['dest_nodes']['mailsub'] }}"
But they too do not work.
This is how dest_nodes is constructed:
---
- name: "Play 1-Construct inventory"
hosts: localhost
any_errors_fatal: True
gather_facts: no
tasks:
- name: Add hosts
include_tasks: "{{ playbook_dir }}/gethosts1.yml"
loop:
- 01
- 02
- 03
loop_control:
loop_var: my_result
cat gethosts1.yml
---
- name: Generate JSON data
add_host:
hostname: "{{ item }}_{{ my_result }}"
groups: dest_nodes
ansible_host: "{{ item }}"_NUMBER }}"
with_items: "{{ SERVER_IP.split(',') }}"
Can you please suggest?

Create Variable From Ansible Facts

I have four systems, in those I need to extract facts then use them as variables on a jinja 2 template.
In Ansible i have:
vars:
office1:
web01:
myip: 10.10.10.10 // or fact
peer: 10.10.10.20
web02
myip: 10.10.10.20 // or fact
peer: 10.10.10.10
office2:
web01:
myip: 10.20.20.30 // or fact
peer: 10.20.20.40
web02
myip: 10.20.20.40 // or fact
peer: 10.20.20.30
On the jinja 2 template I have:
# Config File:
host_name: {{ ansible_hostname }} // web01
host_ip: {{ ansible_eth0.ipv4.address }}
host_peer: {{ office1."{{ ansible_hostname }}".peer }}
I however get error that Ansible variable: office1.ansible_hostname.peer is not defined.
Any help with this would be greatly appreciated.
Expansion in Ansible is not recursive. Try the expansion below
host_peer: {{ office1[ansible_hostname].peer }}
For example the play below
- hosts: test_01
gather_facts: yes
vars:
office1:
test_01:
myip: 10.20.20.30
peer: 10.20.20.40
tasks:
- template:
src: template.j2
dest: /scratch/test_01.cfg
with template.j2
# Config File:
host_name: {{ ansible_hostname }}
host_peer: {{ office1[ansible_hostname].peer }}
gives
# cat /scratch/test_01.cfg
# Config File:
host_name: test_01
host_peer: 10.20.20.40
To answer the question
Q: "Create Variable From Ansible Facts"
A: An option would be to use lookup vars. For example the play below
vars:
var1: var1
var2: var2
var3: var3
tasks:
- debug:
msg: "{{ lookup('vars', 'var' + item) }}"
with_sequence: start=1 end=3
gives (abridged)
"msg": "var1"
"msg": "var2"
"msg": "var3"