Score:0

How to share ansible variables between loop tasks

kz flag

I'm trying to create a Fortinet FortiManager automation with their Ansible collection.

I've created a dynamic ADOM creation task which runs in a loop and now I'm trying to run another dynamic tasks that creates CLI templates inside all of the created ADOM's. The problem I'm facing is that I have to defined ADOM name multiple times in different tasks that run in a loop, but what I would like to do is inherit/share the ADOM name between loop tasks so I do not have to repeatedly define it for each loop task with another variable name.

This is the code I have with descriptions:

  1. I've created a task that includes ADOM creation tasks and runs it in a loop for each ADOM I need to create. I need to do this due to the fact that FortiManager ADOM creation task state result does not give "OK" if the ADOM is already created, but it fails. So I had to build it like this.
---
  name: 'Setup ADOMS'
  loop: '{{ fmg_adom_list }}'
  loop_control:
    loop_var: '__adom'
    label: '{{ __adom.fmg_adom_name }}'
  ansible.builtin.include_tasks: 'fmg_setup_adom.yml'
  1. This is the ADOM creation task and check if ADOM exists to skip the creation
 - name: Check if ADOM exists
  fortinet.fortimanager.fmgr_fact:
    facts:
      selector: "dvmdb_adom"
      params:
        adom: "{{ __adom.fmg_adom_name }}"
  register: fmg_adom_check
  no_log: false
  ignore_errors: true
  changed_when: "fmg_adom_check.rc != 0"
  failed_when: "fmg_adom_check.rc == -3"

 - name: "Create ADOM {{ __adom.fmg_adom_name }}"
  fortinet.fortimanager.fmgr_dvmdb_adom:
    bypass_validation: "{{ fmg_bypass_validation }}"
    state: "{{ __adom.fmg_adom_state | default('present') }}"
    dvmdb_adom:
      name: "{{ __adom.fmg_adom_name | replace(' ', '_') }}"
      desc: "{{ __adom.fmg_adom_desc }}"
      os_ver: "{{ __adom.fmg_adom_os_ver | default(7.0) | float }}"
      mode: "{{ __adom.fmg_adom_mode | default('gms') }}"
      restricted_prds: "{{ __adom.fmg_adom_restricted_prds | default('fos') }}"
      state: " {{ __adom.fmg_dvmdb_adom_state | default(1) | int }}"
      flags: "{{ __adom.fmg_adom_flags }}"
  register: fmg_adom_create
  when: fmg_adom_check.meta.response_message == "Object does not exist"

 - name: Print ADOM creation error message
  ansible.builtin.debug:
    msg: "Failed to create ADOM: {{ fmg_adom_check.meta.response_message }}"
  when: fmg_adom_create is failed

 - name: Print ADOM already exists message
  ansible.builtin.debug:
    msg: "ADOM {{ __adom.fmg_adom_name }} already exists"
  when: fmg_adom_create is skipped

 - name: Print ADOM created successfully message
  ansible.builtin.debug:
    msg: "ADOM {{ __adom.fmg_adom_name }} created successfully"
  when: fmg_adom_create is succeeded and fmg_adom_create is not skipped
  1. This is the CLI template task that gives me a error: The error was: 'list object' has no attribute 'fmg_adom_name'. I'm stuck on understanding how can I make the task use fmg_adom_name from ADOM creation variable list, instead of needed to repeat the variable with a new name like fmg_tmpl_grp_adom as the ADOM is a mandatory variable.
---
- name: Create CLI template group {{ item.fmg_tmpl_grp_name }} to ADOM {{ item.fmg_adom_name }}
  fortinet.fortimanager.fmgr_templategroup:
    workspace_locking_adom: "{{ item.fmg_adom_name }}"
    adom: "{{ item.fmg_adom_name }}"
    state: "{{ item.fmg_tmpl_grp_state }}"
    templategroup:
      name: "{{ item.fmg_tmpl_grp_name }}"
      description: "{{ item.fmg_tmpl_grp_desc }}"
      member: "{{ item.fmg_tmpl_grp_mbr | list }}"
  loop: "{{ fmg_tmpl_grp_list | zip(fmg_adom_list) | list }}"
  1. These are the variables that I define in the playbook
# ADOM Creation variables
    fmg_adom_list: 
      - fmg_adom_name: "ADOM_One"
        fmg_adom_desc: "ADOM One"
        fmg_adom_flags:
          - no_vpn_console
          - per_device_wtp
          - per_device_fsw
# ADOM CLI Template group creation varibles
    fmg_tmpl_grp_list:
      - fmg_tmpl_grp_state: present
        fmg_tmpl_grp_name: "Test"
        fmg_tmpl_grp_desc: "Test group"
        fmg_tmpl_grp_mbr: 
          - "test_cli_template"

I hope I explained myself as clearly and understandably as possible.

Thank you!

Score:2
gu flag

You're zipping two lists together which means you end up with a list of two-tuples, ie. each element of the list is itself a list. Hence accessing the fmg_adom_name attribute of a list item (instead of the expected dictionary) results in the observed error.

You need to access [0] for the adom information and [1] for the template information.

- name: Create CLI template group {{ item[1].fmg_tmpl_grp_name }} to ADOM {{ item[0].fmg_adom_name }}
  fortinet.fortimanager.fmgr_templategroup:
    workspace_locking_adom: "{{ item[0].fmg_adom_name }}"
    adom: "{{ item[0].fmg_adom_name }}"
    state: "{{ item[1].fmg_tmpl_grp_state }}"
    templategroup:
      name: "{{ item[1].fmg_tmpl_grp_name }}"
      description: "{{ item[1].fmg_tmpl_grp_desc }}"
      member: "{{ item[1].fmg_tmpl_grp_mbr }}"
  loop: "{{ fmg_tmpl_grp_list | zip(fmg_adom_list) }}"

Side note, this will map the first adom to the first template, the second adom to the second template, etc. If that's not what you want zip isn't the right filter.

cr0c avatar
kz flag
First of all thank you for the answer. As I understand if I want to loop through all the templates on all of the ADOM's I shouldn't use `zip` as the filter. My question would be if I want all of the templates on all ADOM's then which filter should I be using for the loop to get ADOM names and loop over them.
Ginnungagap avatar
gu flag
If you need a Cartesian product, `ansible.builtin.product` (which maps to Pythons `itertools.product`). The resulting elements will have the same format so you only have to change the filter.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.