No variables when looping over inventory_hostname

Hi everyone.

I have a playbook/task that loops over inventory_hostname.

My question - are the variables not transferred to playbook when looping over inventory_hostname?

Can I include the host variables in a way that they match the current host?

I tried ansible.builtin.include_vars but it didn’t work for me.

Maybe someone has a hint for me.

Thanks
Andreas


- name: Install policies
  hosts: mgmt
  connection: httpapi

  tasks:

    - name: install-policy
      check_point.mgmt.cp_mgmt_install_policy:
        access: true
        threat_prevention: false
        policy_package: "{{ policyset }}"
        targets: "{{ item }}"
      with_inventory_hostnames:
        - all:!mgmt

inventory:

[cp_gaia]
cpfwtest01

[cp_smb]
cpfwprod02

[mgmt]
192.0.2.10  ansible_python_interpreter="/opt/CPsuite-R81.20/fw1/Python/bin/python3.9"

[mgmt:vars]
ansible_httpapi_use_ssl=True
ansible_connection=httpapi
ansible_httpapi_port=4434
ansible_httpapi_validate_certs=False
ansible_httpapi_use_ssl=True
ansible_network_os=check_point.mgmt.checkpoint

group_vars:

cp_gaia.yml

policyset: pol_sat_gaia

cp_smb.yml

policyset: pol_sat_smb

Your inventory doesn’t include any “mgmt” group, so I would expect a “skipping: no hosts matched” message. Also, missing the tasks: line. I’m going to assume you’ve left out some stuff in an effort to reduce irrelevant text…[subsequently fixed]

The real problem is, you’re targeting the host(s) in your “mgmt” group. The fact that you’re looping over names of hosts in your inventory doesn’t alter that fact. The variables available with each iteration of the task are still those associated with your target hosts.

Instead, you need to target the correct hosts – 'all:!mgmt' – and use delegate_to: to ensure that the task runs on one of your mgmt hosts, but targeting – and thus using the variables associated with – your non-mgmt hosts.

- name: Install policies
  hosts: 'all:!mgmt'
  tasks:
    - name: Install-policy
      check_point.mgmt.cp_mgmt_install_policy:
        access: true
        threat_prevention: false
        policy_package: "{{ policyset }}"
        targets: "{{ inventory_hostname }}"
      delegate_to: "{{ query('inventory_hostnames', 'mgmt') | first }}"

(N.B.: I’m not familiar with check_point.mgmt.cp_mgmt_install_policy, so I’m making some assumptions about things like the targets parameter for example.)

Hello Todd.

Thanks for your answer.

Yes, I deleted a bit liberally when it came to inventory and the playbook :smiley:
I added that again above.

I’ll take a look at your suggestion and get back to you

Cheers
Andreas

After thinking a bit (but not enough apparently), I’m not exactly sure about the connection: setting. That may need to be different on your mgmt host(s) vs the non-mgmt hosts. You’ll have to sort that out though. You can do that in group_vars, host_vars, inventory, or at the task level I think. I looked at a few docs, but came away more confused than informed. Fortunately for you, you actually have hosts to try various things on.
Do let us know what works in this case, b/c I think others would benefit from a working example.

1 Like

I don’t have to execute anything on the individual inventory host in this case.
Actually, only a connection to the management server (mgmt) has to be made and the policy installation on the individual host is then triggered from there.

If I only include hosts in the inventory - which all have the same policy set and I then hardcode the policy set to the appropriate one - the playbook works.

I just wanted to bring in a little more dynamics :slight_smile:

This playbook is working, when I limit the playbook to the “cp_gaia” group in the inventory and the policy_package is set static to “pol_sat_gaia” …

- name: Install policies
  hosts: mgmt
  connection: httpapi

  tasks:
    - name: install-policy
      cp_mgmt_install_policy:
        access: true
        threat_prevention: false
        policy_package: pol_sat_gaia
        targets: "{{ item }}"
      with_inventory_hostnames:
        - all:!mgmt

Just to beat this dead horse into a plowshare, you could get the effect you want (maybe?) like this:

- name: Install policies
  hosts: mgmt
  connection: httpapi
  tasks:
    - name: install-policy
      check_point.mgmt.cp_mgmt_install_policy:
        access: true
        threat_prevention: false
        policy_package: "{{ policyset }}"
        targets: "{{ item }}"
      with_inventory_hostnames:
        - all:!mgmt
      vars:
        policyset: "{{ hostvars[item].policyset }}"
      run_once: true
      when: policyset is defined

That is, use task variables to set the variable explicitly from the corresponding host’s variables — even though you are targeting one of your "mgmt" hosts. (“One of” b/c of the "run_once:" bit; you don’t want to do it across more than one I don’t think.)

2 Likes

Thank you very much. You have made my day. That was the trick … it works :smiley:

I am still relatively new to the Ansible business … a lot of things work quite well.
But sometimes you need a push in the right direction.

Cheers
Andreas

There are lots of ways to do things.
Some of them are right.
Some of them work.
Some of them are in both sets. :slight_smile:
“Every tool is a hammer is you use it wrong enough.”

Hi again.

I went back to the delegate_to example and it works now. I can now control on which systems the policy should be installed. I think it looks very nice now :slight_smile:

cpman ist the management host.

---
  hosts: "all:!cpman"
  gather_facts: false

  vars:

    threadprevention: false
    desktopsecurity: false
    accesspolicy: true

  tasks:

    - name: Install policy
      check_point.mgmt.cp_mgmt_install_policy:
        access: "{{ accesspolicy }}"
        desktop_security: "{{ desktopsecurity }}"
        threat_prevention: "{{ threadprevention }}"
        policy_package: "{{ policyset }}"
        targets: "{{ inventory_hostname }}"
      delegate_to: cpman

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.