Skip to content

bigip_virtual_server.py - Bug with metadata inconsistently set (removed each 1 of 2 run) #2509

@amolari

Description

@amolari
COMPONENT NAME

bigip_virtual_server.py

Environment

ANSIBLE VERSION
2.16.9
BIGIP VERSION
17.5.1.3
CONFIGURATION

N/A

OS / ENVIRONMENT

N/A

SUMMARY
STEPS TO REPRODUCE

I create a VS with metadata being a var (dictionary)

- name: set fact vs_metadata
  set_fact:
    vs_metadata:
      run_caller: "{{ run_caller }}"
      application: "{{ application | regex_replace('^[A-Z-]+_(.*)$', '\\1') }}"

- name: set fact vs_metadata - add conditionally httpver=2 (when http2_enabled)
  set_fact:
    vs_metadata: "{{ vs_metadata | combine({ 'httpver': '2' }) }}"
  when: http2_enabled

- name: Add VS "{{ application }}_vs" - with config map
  bigip_virtual_server:
    provider: "{{ provider }}"
    state: present
    partition: Common
    name: "{{ application }}_vs"
    description: "{{ scope + ', ' + source_allowlist }}"
    metadata: "{{ vs_metadata }}"
    destination: "{{ int_vs_ip }}"
    port: '443'
    pool: "{{ application }}_pool"
    snat: "{{ snat_pool_default }}"
    profiles: "{{ vs_config_map['profiles'] }}"
    policies: "{{ vs_config_map['policies'] | default([]) }}"
    security_log_profiles: "{{ vs_config_map['security_log_profiles'] }}"
    irules: "{{ (irules_list is defined and irules_list | length>0) | ternary(vs_config_map['irules'], []) }}"
    check_profiles: no
    default_persistence_profile: "{% if lb_mode is defined and lb_mode == 'lb' and ( pool_members_aggregate_list | length ) > 1 %}default_cookie_insert_persistence{% else %}{% endif %}"
  delegate_to: localhost
EXPECTED RESULTS

At every playbook run, the metadata should be set as defined in the task, consistently.

ACTUAL RESULTS

Looking in the /var/log/audit file of the target BIG-IP I can see that in every 1 of 2 runs the metadata is not set.

1st run:

notice icrd_child[10785]: 01420002:5: AUDIT - pid=10785 user=XXXXX folder=/Common module=(tmos)# status=[Command OK] cmd_data=modify ltm virtual /Common/example.com_vs { metadata replace-all-with { run_caller { value managedservices } application { value example.com } httpver { value 2 } f5-ansible.version { value 2.16.9 persist true } f5-ansible.last_modified { value "2026-01-18 11:06:14.545560" persist true } } profiles replace-all-with { /Common/http { context all } /Common/websecurity { context all } /Common/default_serverssl { context serverside } /Common/internal_clientssl { context clientside } /Common/default_http2 { context all } /Common/httprouter { context all } } }

2nd run (re-run):

notice icrd_child[10785]: 01420002:5: AUDIT - pid=10785 user=XXXXX  folder=/Common module=(tmos)# status=[Command OK] cmd_data=modify ltm virtual /Common/example.com_vs { profiles replace-all-with { /Common/http { context all } /Common/websecurity { context all } /Common/default_serverssl { context serverside } /Common/internal_clientssl { context clientside } /Common/default_http2 { context all } /Common/httprouter { context all } } metadata replace-all-with { f5-ansible.version { value 2.16.9 persist true } f5-ansible.last_modified { value "2026-01-18 11:07:54.975015" persist true } } }

3rd run will set it as 1st run, 4th as 2nd and so on.

The Bug is in this part of the code:

result = self._diff_complex_items(self.want.metadata, self.have.metadata)

which calls that function (L3191 condition is the issue):
def _diff_complex_items(self, want, have):
if want == [] and have is None:
return None
if want is None:
return None
w = self.to_tuple(want)
h = self.to_tuple(have)
if set(w).issubset(set(h)):
return None
else:
return want

Haven't digged that much into it but replacing L3453 with the following seems to fix it:

result = self.want.metadata

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssues that are related to bugs in the Ansible modulesuntriagedissue that needs an initial response from the developers

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions