I am testing on both 1.9.4 and 2.1 and seeing the exact same behavior.
We have a fact.d generator that creates a tree of facts under ansible_local. We use this to set defaults, but if during playbook execution it needs to update a default, it clobbers the entire ansible_local parent fact. I created a test playbook to replicate the same issue.
- hosts: localhost
connection: local
vars:
my_roles:
info:
hardware: “CPU info”
cmdb:
local: [{‘name’:‘blah’}]
remote: Falsetasks:
name: set new facts
set_fact:
args:
test_dict: {‘name’: meh’}name: test
set_fact:
args:
my_roles:
cmdb:
local: “{{ my_roles.cmdb.local + ([test_dict]|list) }}”
remote: Truedebug: var=my_roles
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]TASK [set facts] ***************************************************************
ok: [localhost]TASK [test] ********************************************************************
ok: [localhost]TASK [debug] *******************************************************************
ok: [localhost] => {
“my_roles”: {
“cmdb”: {
“local”: [
{
“name”: “blah”
},
{
“name”: “meh”
}
],
“remote”: true
}
}
}PLAY RECAP *********************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0
As you can see, the playbook clobbers the parent my_roles and updates with whatever is in the set_fact task. I have read through various documentation links, and searched around but have not seen anyone come across this specifically. I understand that ansible uses everything as a string, so taking a fact and then updating obliterates the original fact, but how does one update a nested fact in Ansible?