1

I have a bunch of root servers with different IP addresses. I'm trying to configure the ufw firewall on the server with MySQL server to only allow access from my servers (might change to webservers later) with Ansible. Initially, I only had the FQDNs in the inventory but added the ansible_host IPs because the firewall is not going to resolve the host names (makes sense).

Unfortunately I do not know how to access the ansible_host in the loop query("inventory_hostnames", "all")

My inventory:

all:
  vars:
    ansible_ssh_user: me
  children:
    sqlserver:
       hosts:
        sqlserver.my-domain.de:
          ansible_ssh_user: mysql_me_user
          ansible_host: 1.1.1.1

    webserver:
      hosts:
        webserver1.my-domain.de:
          ansible_host: 2.2.2.2
        webserver2.my-domain.de:
          ansible_host: 3.3.3.3

now I am trying to loop in the playbook:

- hosts: '{{target|default("sqlserver")}}'
  roles:
    - { name: oefenweb.ufw, become: yes } # needs root but does not define become by itself...
  vars:
    ufw_logging: true
    ufw_rules:
      - rule: allow
        to_port: 22
        protocol: tcp
  tasks:
    - name: open MySQL for servers in my 
      ufw:
        rule: allow
        to_port: 3306
        protocol: tcp
        from_ip: '{{ item }}'
      loop: '{{ hosts|default(query("inventory_hostnames", "all")) }}'
      tags: test
      become: true
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
Kleidersack
  • 452
  • 4
  • 13

2 Answers2

2

There are many options. Make your choice depending on the use case.

  1. For example, the play below
shell> cat pb.yml
- hosts: '{{ target|default("sqlserver") }}'
  tasks:
    - debug:
        msg: "{{ item }}: {{ ansible_host }}"
      loop: "{{ clients|default(groups.webserver) }}"
      vars:
        ansible_host: "{{ hostvars[item].ansible_host }}"

gives

shell> ansible-playbook pb.yml 

PLAY [sqlserver] *****************************************************************************

TASK [debug] *********************************************************************************
ok: [sqlserver.my-domain.de] => (item=webserver1.my-domain.de) => 
  msg: 'webserver1.my-domain.de: 2.2.2.2'
ok: [sqlserver.my-domain.de] => (item=webserver2.my-domain.de) => 
  msg: 'webserver2.my-domain.de: 3.3.3.3'

PLAY RECAP ***********************************************************************************
sqlserver.my-domain.de: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Example of the project for testing

shell> tree .
.
├── ansible.cfg
├── hosts
└── pb.yml

0 directories, 3 files
shell> cat ansible.cfg 
[defaults]
gathering = explicit
inventory = $PWD/hosts
stdout_callback = yaml
shell> cat hosts 
all:
  vars:
    ansible_ssh_user: me
  children:
    sqlserver:
       hosts:
        sqlserver.my-domain.de:
          ansible_ssh_user: mysql_me_user
          ansible_host: 1.1.1.1
    webserver:
      hosts:
        webserver1.my-domain.de:
          ansible_host: 2.2.2.2
        webserver2.my-domain.de:
          ansible_host: 3.3.3.3
shell> cat pb.yml 
- hosts: '{{ target|default("sqlserver") }}'
  tasks:
    - debug:
        msg: "{{ item }}: {{ ansible_host }}"
      loop: "{{ clients|default(groups.webserver) }}"
      vars:
        ansible_host: "{{ hostvars[item].ansible_host }}"

  1. Create the list and the dictionary below
  clients: "{{ groups.webserver }}"
  ah_list: "{{ clients|map('extract', hostvars, 'ansible_host')|list }}"
  ah_dict: "{{ dict(clients|zip(ah_list)) }}"

give

  ah_list:
  - 2.2.2.2
  - 3.3.3.3

  ah_dict:
    webserver1.my-domain.de: 2.2.2.2
    webserver2.my-domain.de: 3.3.3.3

Then, all tasks below give the same results

2a)

    - debug:
        msg: "{{ item.key }}: {{ item.value }}"
      with_dict: "{{ ah_dict }}"

2b)

    - debug:
        msg: "{{ item.0 }}: {{ item.1 }}"
      with_together:
        - "{{ clients }}"
        - "{{ ah_list }}"

2c)

    - debug:
        msg: "{{ item }}: {{ ah_dict[item] }}"
      loop: "{{ clients }}"

Example of a complete playbook for testing

- hosts: '{{ target|default("sqlserver") }}'

  vars:

    clients: "{{ groups.webserver }}"
    ah_list: "{{ clients|map('extract', hostvars, 'ansible_host')|list }}"
    ah_dict: "{{ dict(clients|zip(ah_list)) }}"

  tasks:

    - debug:
        var: ah_list
    - debug:
        var: ah_dict

    - debug:
        msg: "{{ item.key }}: {{ item.value }}"
      with_dict: "{{ ah_dict }}"

    - debug:
        msg: "{{ item.0 }}: {{ item.1 }}"
      with_together:
        - "{{ clients }}"
        - "{{ ah_list }}"

    - debug:
        msg: "{{ item }}: {{ ah_dict[item] }}"
      loop: "{{ clients }}"
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
0

As I was writting the question I understood that should google for accessing inventory property and found a solution in Accessing inventory host variable in Ansible playbook - use

        from_ip: '{{ hostvars[item].ansible_host }}'

for my task.

I hope that this the way to go.

Kleidersack
  • 452
  • 4
  • 13