best practices in vars organisation

Hi,

I'm an ansible beginner, sorry if these topics have been already posted
here.

I read a lot of pages on https://docs.ansible.com/ (very complete and
well done), had a look to ansible-examples (and also some github repo
ansible-role-xxx), but I've still some question about best practices for
vars organisation

I started with this structure
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#role-directory-structure

I want to describe my infrastructure into vars
(a) vm list with their ip
(b) a lot of default values (locales, ssh keys, timezone, etc.)

I read
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#organizing-host-and-group-variables
and :

(a) seems better in group_vars/all.yml

(b) seems better in the right roles/xxx/vars.yml, but for the maintenance
it's easier to put all in the same place (painfull to have some ssh keys in
roles/common/vars.yml and others in roles/webservers/vars.yml, even if each
are used only in their role)

Any advice ?

About override, I saw that it's often with a default value, sometimes
changed in a specific case, but is it possible to add item to a default
list (without replacing the list) ?

The use case could be for ssh keys, a list for all targets and some
specifics keys to add for some targets.

I guess I can define for all the vars default_ssh_keys and ssh_keys_to_add
(set to by default), then override ssh_keys_to_add for some targets then
concat in task, but perhaps there is an easier way.

I imagined also just the default_ssh_keys defined for all, and then a task
to export a ssh_keys var, which would be the concat of default_ssh_keys and
ssh_keys_extra if defined, with set_fact

What is the better way to do this ?

And for the description, I'm not really sure about the best var structure,
between

1) several dict, target as key on each dict

privates_ipv4:
  host1: 192.168.1.1
  host2: 192.168.2.1
  foo: 192.168.1.4
  bar: 192.168.2.42

publics_ipv4:
  foo: 1.2.3.4

parent_hosts
  foo: host1
  bar: host2

or
2) one dict, target as key

targets:
  host1:
    private_ipv4: 192.168.1.1
  host2:
    private_ipv4: 192.168.2.1
  foo:
    private_ipv4: 192.168.1.4
    public_ipv4: 1.2.3.4
    parent: host1
  bar:
    private_ipv4: 192.168.2.42
    parent: host2

or
3) one list of dicts, target in the "name" key

targets:
  - name: host1
    private_ipv4: 192.168.1.1
  - name: host2
    private_ipv4: 192.168.2.1
  - name: foo
    private_ipv4: 192.168.1.4
    public_ipv4: 1.2.3.4
    parent: host1
  - name: bar
    private_ipv4: 192.168.2.42
    parent: host2

I started with 1), easier for loop & filtering in tasks and templates, but
in the long term I'm wondering if others solutions are easier to maintain…

Perhaps that 2) allow to set groups on each target (better than repeating
target list in host definition), with with dynamic inventory and
constructed plugin, I'll see…

Any advice from experienced users will be appreciated :wink: