How to obtain a value from one host in a play, and apply the value on another host.

I am trying to orchestrate a database replication setup. This means I need to read configuration details from the master node, and apply this on the slave to facilitate the replication setup.

I try to read a configuration value, which works (master has ‘primary’ set to true):

  • name: get audit file dest from database
    action: “shell export ORACLE_SID={{ oracle_sid }}; export ORACLE_HOME={{ oracle_home }}; printf "set head off\nselect value from v\$parameter where name = ‘audit_file_dest’;" | $ORACLE_HOME/bin/sqlplus -S / as sysdba | grep -v ^$”
    when: primary
    register: audit_file_dest

Then I try to apply the value on the slave (slave has ‘standby’ set to true):

  • name: create audit file dest on standby
    file: path={{ audit_file_dest.stdout }} state=directory
    when: standby

This is how the execution looks like:

TASK: [get audit file dest from database] *************************************
skipping: [192.168.39.142]
changed: [192.168.39.139]

TASK: [create audit file dest on standby] *************************************
skipping: [192.168.39.139]
fatal: [192.168.39.142] => One or more undefined variables: ‘dict object’ has no attribute ‘stdout’

When using the debug module, I see the problem:

TASK: [debug var=audit_file_dest] *********************************************
ok: [192.168.39.142] => {
“audit_file_dest”: {
“changed”: false,
“skipped”: true
}
}
ok: [192.168.39.139] => {
“audit_file_dest”: {
“changed”: true,
“cmd”: “export ORACLE_SID=test; export ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/dbhome_1; printf "set head off\nselect value from v\$parameter where name = ‘audit_file_dest’;" | $ORACLE_HOME/bin/sqlplus -S / as sysdba | grep -v ^$”,
“delta”: “0:00:00.035030”,
“end”: “2014-12-24 15:54:41.230344”,
“invocation”: {
“module_args”: “export ORACLE_SID=test; export ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/dbhome_1; printf "set head off\nselect value from v\$parameter where name = ‘audit_file_dest’;" | $ORACLE_HOME/bin/sqlplus -S / as sysdba | grep -v ^$”,
“module_name”: “shell”
},
“rc”: 0,
“start”: “2014-12-24 15:54:41.195314”,
“stderr”: “”,
“stdout”: “/u01/app/oracle/admin/test/adump”,
“stdout_lines”: [
“/u01/app/oracle/admin/test/adump”
],
“warnings”:
}
}

Because I try to use the variable on an host on which the variable was not filled, there is not stdout for it.
How can I simply obtain a value on one host for use on another? In this case I would love to make the registered variable contents global.
It can’t be that this is a unique situation? Or is there another way that I should do this?

Thanks

register stays on the host and gets reset in the loop to reflect the
task was skipped, you might want to use a subsequent set_fact and then
access the variable thourgh hostvars[<primary_host_name>].

Thank you Brian!

Can you help me a bit with that?

Please mind I created a group of one called ‘primary’ and a group of one called ‘standby’ in the hosts file, not sure if that can be used.
I used that to have specific per node variables declared.

It would really help in this specific case to have a value/status obtained on one node to configure the other or others. How is that normally done with Ansible?

Cheers,
Frits

you can access the data from other nodes through hostvars:

hostvars[<hostname>][<varname>]

Thank you again Brian, for all your help.

As I’ve stated in the explanation of the problem, I’ve declared groups in the host file. It’s a group of one, but still a group.
I solved this in the following way:

  1. get the value
  • name: get audit file dest from database
    action: “shell export ORACLE_SID={{ oracle_sid }}; export ORACLE_HOME={{ oracle_home }}; printf "set head off\nselect value from v\$parameter where name = ‘audit_file_dest’;" | $ORACLE_HOME/bin/sqlplus -S / as sysdba | grep -v ^$”
    when: primary
    register: audit_file_dest
  1. set the registered variable as fact
  • name: register audit file dest
    set_fact: audit_file_dest=“{{ audit_file_dest.stdout }}”
    when: primary
  1. call the fact from another host via the group name and (mandatory, as far as I can see) host group number:
  • name: create audit file dest on standby
    file: path={{ hostvars[groups[‘primary’][0]][‘audit_file_dest’] }} state=directory
    when: standby

Cheers,
Frits