I have an Ansible role that uses a rather complex configuration in form of a dictionary. The old config format wasn't beneficial in many ways so I rewrote the role to be a lot easier to configure.
As the role is already in broad use I'd like to stay compatible with existing inventories and playbooks that use the old config format. In order to achieve this I thought I could migrate the old config into the new format (all data is there and migratable, so technically it's possible) before running the role.
Sample data
Old config format:
petshop_old:
petshop_data:
name: awesome_petshop
employee_data:
- name_of_employee: sara
date_of_birth: 2000
- name_of_employee: john
date_of_birth: 1995
task_data:
- name: clean_dogs
time: morning
by: john
- name: clean_cats
time: evening
by: john
- name: feed_birds
time: evening
by: sara
New config format:
petshop_new:
name: awesome_petshop
employees:
- name: sara
birth_year: 2000
tasks:
- name: feed_birds
time: evening
- name: john
birth_year: 1995
tasks:
- name: clean_dogs
time: morning
- name: clean_cats
time: evening
tasks/main.yml:
- name: Migrate the old config data into the new format
when: (petshop_old is defined) and (petshop_new is not defined)
block:
[...] Here come the migration tasks [...]
- name: This tasks prints the config, even when originally petshop_old was given to the role
ansible.builtin.debug:
var: petshop_new
[...] do more stuff with the data [...]
What would be the best approach to migrate the old config into the new format before running the actual tasks that perform the role?
For the given old.conf
YAML file, using a quick and lazy loop approach with Jinja2 Templating, a minimal example playbook
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- include_vars:
file: old.conf
name: old
- debug:
var: old
- debug:
msg: |
petshop_new:
name: {{ old.petshop_old.petshop_data.name }}
employees:
{% for employee in old.petshop_old.employee_data %}
- name: {{ employee.name_of_employee }}
birth_year: {{ employee.date_of_birth }}
tasks:
{% for task in old.petshop_old.task_data %}
{% if employee.name_of_employee == task.by %}
- name: {{ task.name }}
time: {{ task.time }}
{% endif %}
{% endfor %}
{% endfor %}
will result into an output of
TASK [debug] *****************
ok: [localhost] =>
old:
petshop_old:
employee_data:
- date_of_birth: 2000
name_of_employee: sara
- date_of_birth: 1995
name_of_employee: john
petshop_data:
name: awesome_petshop
task_data:
- by: john
name: clean_dogs
time: morning
- by: john
name: clean_cats
time: evening
- by: sara
name: feed_birds
time: evening
TASK [debug] *****************
ok: [localhost] =>
msg: |-
petshop_new:
name: awesome_petshop
employees:
- name: sara
birth_year: 2000
tasks:
- name: feed_birds
time: evening
- name: john
birth_year: 1995
tasks:
- name: clean_dogs
time: morning
- name: clean_cats
time: evening
It can become easily written out via
- copy:
dest: new.conf
content: |
pet...