How can I reference other servers in the same inventory by group name?

Viewed 46

I have a static inventory that contains groups and servers inside these groups. Group names can change and so the server names. I'm passing group names as a variable during runtime to the playbook. I'm trying to check a bunch of ports between different servers in the inventory.

So if this is the inventory

group1
  server1

group2
  server2
  server3

And I have group1 and group2 as variables.

I'm trying to do something like this

hosts: group1_var
tasks:
 - name: test connection
   ansible.windows.win_wait_for:
   host: **{{groups[group2_var]}}**   ##How do I implement this correctly????
   port: 443
   delay: 3

Also a second part to this question, but I cannot for some reason return the value of the magic variable if groupX is a variable. When it's a simple string it returns the server names ok.

debug : msg="{{groups['{{groupX}}']))"
2 Answers

From your description

... check ... ports between different servers in the inventory

I understand that you like to do connection test from servers in group1 to servers in group2

group1 --------> group2
            ---> server2
server1 ---|
            ---> server3

and whereby servers in group1 (server1) are not the Ansible Control Node.

To do so you could use an approach like

---
- hosts: all
  become: false
  gather_facts: false

  tasks:

  - name: Show connection test
    delegate_to: group1
    debug:
      msg: "Connect from 'group1' node to {{ inventory_hostname }}"
    when: "'group2' in group_names"

resulting into

TASK [Show connection test] ****************
ok: [server2 -> server1] =>
  msg: Connect from 'group1' node to server2
ok: [server3 -> server1] =>
  msg: Connect from 'group1' node to server3

Documentation


Regarding

I cannot for some reason return the value of the magic variable if groupX is a variable.

you may have a look into the following example

---
- hosts: "{{ target_group }}" # aka group_var
  become: false
  gather_facts: false

  vars:

    group_x: "group1"

  tasks:

  - debug:
      msg: "{{ groups[group_x] }}"

and

FAQ

What I understand from your question.

  • You have a source group and target group of server(s)
  • You want to pass those dynamically to your playbook at run time
  • You want to run a task on each server in the source group for each server in the target group.

You actually need two loops. The first one is the natural play loop (i.e. hosts parameter in your play). The second loop: will be on your task. I used a debug task for the example. You just have to report the loop on your own task.

Given the inventory inventories/default/main.yml

---
group1:
  hosts:
    server1:

group2:
  hosts:
    server2:
    server3:

And the following playbook.yml

---
- hosts: "{{ source_group }}"
  gather_facts: false

  tasks:
    - name: test connection
      debug:
        msg: "testing connection from {{ inventory_hostname }} to {{ item }}"
      loop: "{{ groups[target_group] }}"

You can check connections from group1 to group2

$ ansible-playbook -i inventories/default/ playbook.yml \
  -e source_group=group1 -e target_group=group2

PLAY [group1] ********************************************************

TASK [test connection] ***********************************************
ok: [server1] => (item=server2) => {
    "msg": "testing connection from server1 to server2"
}
ok: [server1] => (item=server3) => {
    "msg": "testing connection from server1 to server3"
}

PLAY RECAP ***********************************************************
server1: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Or from group2 to group1

$ ansible-playbook -i inventories/default/ playbook.yml \
  -e source_group=group2 -e target_group=group1

PLAY [group2] ********************************************************

TASK [test connection] ***********************************************
ok: [server2] => (item=server1) => {
    "msg": "testing connection from server2 to server1"
}
ok: [server3] => (item=server1) => {
    "msg": "testing connection from server3 to server1"
}

PLAY RECAP ***********************************************************
server2: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
server3: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Or even from group2 to group2 itself

$ ansible-playbook -i inventories/default/ playbook.yml \
  -e source_group=group2 -e target_group=group2

PLAY [group2] ********************************************************

TASK [test connection] ***********************************************
ok: [server2] => (item=server2) => {
    "msg": "testing connection from server2 to server2"
}
ok: [server2] => (item=server3) => {
    "msg": "testing connection from server2 to server3"
}
ok: [server3] => (item=server2) => {
    "msg": "testing connection from server3 to server2"
}
ok: [server3] => (item=server3) => {
    "msg": "testing connection from server3 to server3"
}

PLAY RECAP ***********************************************************
server2: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
server3: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Related