1
votes

Background information:

I need to dynamically set a variable on a set of hosts (web1) and then check the same on a different set of hosts. Once they match, I can perform further actions.

Code

My hosts file looks like this:

[web1]
web1.ttv.mydomain.com

[web1:vars]
primary_count=0

[web2]
web2.ttv.mydomain.com

[web2:vars]
secondary_count=0

[web]
web1
web2

And this is the playbook:

- hosts: web1
  tasks:
  - name: query primary servers
    shell: psql -U widget widget -c 'SELECT COUNT(*) FROM test' -t
    register: result
  - set_fact: primary_count={{result.stdout}}

- hosts: web
  tasks:
  - name: retrieve variable from previous play
    shell: echo hello
  - debug: var=primary_count

This playbook produces the following results:

TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]

TASK [query primary servers] ****************************************************
changed: [web1.ttv.mydomain.com]

TASK [debug] *******************************************************************
ok: [web1.ttv.mydomain.com] => {
    "primary_count": 0
}

TASK [set_fact] ****************************************************************
ok: [web1.ttv.mydomain.com]

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]
ok: [web2.ttv.mydomain.com]

TASK [retrieve variable from previous play] ************************************
changed: [web1.ttv.mydomain.com]
changed: [web2.ttv.mydomain.com]

TASK [debug] *******************************************************************
ok: [web2.ttv.mydomain.com] => {
    "primary_count": "VARIABLE IS NOT DEFINED!"
}
ok: [web1.ttv.mydomain.com] => {
    "primary_count": "     2"
}

Problem

Now I need a way to do the following in the second play:

  • run the same select statement on web2.ttv.mydomain.com
  • save the value to secondary_count variable
  • check if secondary_count matches the value of the "primary_count" on web1.mydomain.com. (Notice how right now, since I'm looping through more than just the web1 servers in play 2, I get an error about the "primary_count" not being defined on web2 servers.)
  • when the values match then restart various services on secondary

Questions:

How do I evaluate the "primary_count" variable on the web1 host with the matching web2 host name on? In the future my hosts file will look like this:

[web1]
web1.ttv.mydomain.com
web1.ttx.mydomain.com

[web2]
web2.ttv.mydomain.com
web2.ttx.mydomain.com

[web]
web1
web2

So I need to write some sort of an eval statement that does this: (pseudocode)

while looping through ***ALL*** web servers
  if primary_count on web1.ttv.mydomain.com matches secondary_count on web2.ttx.mydomain.com then
    restart service x on web2.ttx.mydomain.com
  else
    wait a few seconds and repeat
end
end loop

I think the solution lies with my hosts / inventory file. Somehow I need this playbook to run on all web1 servers and all web2 servers... but I also need a way to associate web1.ttv with just web2.ttv and web1.ttx with just web2.ttx and so on.

I'm just learning ansible as I go along, so if this approach is entirely wrong, please let me know!

Thanks.

EDIT 1

On doing some research about group_vars, it looks like group_vars doesn't really help me because I still have the same problem. While looping through all web servers (play 2), the variables I set on web1 servers in play 1 are not visible from web2 servers.

EDIT 2:

- hosts: web1
  tasks:
  - name: query primary servers
    shell: psql -U widget widget -c 'SELECT COUNT(*) FROM widget' -t
    register: result
  - local_action: shell echo {{ result.stdout }} > varacrossplay.txt

That fails on the local_action line with this error:

fatal: [web1.ttv.mydomain.com -> localhost]: FAILED! => {"changed": true, "cmd": "echo 2 > varacrossplay.txt", "delta": "0:00:00.001641", "end": ": "echo 2 > varacrossplay.txt", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "mod 1: cannot create varacrossplay.txt: Permission denied", "stdout": "", "stdout_lines": [], "warnings": []}

1
Have you already tried using group_vars? If you're new to ansible you might also want to take a read of Ansible Best Practices if you haven't already?Dezza
@Dezza, I've read that page but find it a bit sparse as far as examples go. I will google some examples. But which part /question will that solve?dot
@Dezza please check out my comments in Edit 1dot

1 Answers

2
votes

Try with this example playbook:

[jenkins@batman ansible]$ cat testplaybook.yml
- hosts: web1
  tasks:
  - name: query primary servers
    shell: echo "TEST"
    register: result

  - local_action: shell echo {{ result.stdout }} > varacrossplay.txt

- hosts: web
  tasks:

  - local_action: shell cat varacrossplay.txt
    register: result

  - set_fact: other_fact="{{ result.stdout }}"

  - debug: var=other_fact

With my servers all works fine xD

[jenkins@batman ansible]$ ansible-playbook -i inventory testplaybook.yml

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [10.0.0.100]

TASK [query primary servers] ***************************************************
changed: [10.0.0.100]

TASK [command] *****************************************************************
changed: [10.0.0.100 -> localhost]

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [10.0.0.2]
ok: [10.0.0.1]

TASK [command] *****************************************************************
changed: [10.0.0.1 -> localhost]
changed: [10.0.0.2 -> localhost]

TASK [set_fact] ****************************************************************
ok: [10.0.0.1]
ok: [10.0.0.2]

TASK [debug] *******************************************************************
ok: [10.0.0.2] => {
    "other_fact": "TEST"
}
ok: [10.0.0.1] => {
    "other_fact": "TEST"
}

PLAY RECAP *********************************************************************
10.0.0.100            : ok=3    changed=2    unreachable=0    failed=0
10.0.0.1             : ok=4    changed=1    unreachable=0    failed=0
10.0.0.2             : ok=4    changed=1    unreachable=0    failed=0