Is it possible to merge(by auto resolving conflicts) 2 config files using Ansible?
For eg,
// c1.conf
A=20
B="Hello"
D=24
// c2.conf
X=30
A=20
B="Hello2"
C=31
E=33
//output.conf
X=30
A=20
B="Hello" # In case of update, give priority to c1.conf
C=31 # In case of add/delete, give priority to c2.conf
E=33
Declare the list of files
files:
- /tmp/c2.conf
- /tmp/c1.conf
and slurp them
- slurp:
src: "{{ item }}"
loop: "{{ files }}"
register: out
Then, the declaration
result: "{{ out.results | map(attribute='content')
| map('b64decode')
| map('community.general.jc', 'ini')
| combine }}"
gives
result:
A: '20'
B: Hello
C: '31'
D: '24'
E: '33'
X: '30'
If you want to keep the c2 attributes only, declare the below dictionary and key list
c2dict: "{{ out.results.0.content | b64decode
| community.general.jc('ini') }}"
c2keys: "{{ c2dict.keys() | sort }}"
give
c2dict:
A: '20'
B: Hello2
C: '31'
E: '33'
X: '30'
c2keys: [A, B, C, E, X]
Then, keep the c2 keys in the result
resul2: "{{ [result] | community.general.keep_keys(target=c2keys)
| first }}"
gives
resul2:
A: '20'
B: Hello
C: '31'
E: '33'
X: '30'
Example of a complete playbook for testing
- hosts: localhost
vars:
files:
- /tmp/c2.conf
- /tmp/c1.conf
result: "{{ out.results | map(attribute='content')
| map('b64decode')
| map('community.general.jc', 'ini')
| combine }}"
c2dict: "{{ out.results.0.content | b64decode
| community.general.jc('ini') }}"
c2keys: "{{ c2dict.keys() | sort }}"
resul2: "{{ [result] | community.general.keep_keys(target=c2keys)
| first }}"
tasks:
- slurp:
src: "{{ item }}"
loop: "{{ files }}"
register: out
- debug:
var: out.results
- debug:
var: result
- debug:
var: c2dict
- debug:
var: c2keys | to_yaml
- debug:
var: resul2