Hi Stefan.
I think what you're trying to do is like what I handled in my pillar/top.sls :
-8<--
{% set host, domain = grains['id'].split('.', 1) %}
{% set hostbase = grains['id']|replace('.', '_') %}
{% set dom=domain|replace('.', '_') %}
base:
'*':
- default
{% if salt['pillar.file_exists']('hostdata/'+hostbase+'.sls') %}
- hostdata.{{hostbase}}
{% endif %}
# File init.sls must be present even if empty!
# BUG: pillar.file_exists does not detect directories :(
{% if salt['pillar.file_exists'](dom+'/init.sls') %}
'*.{{ domain }}':
- {{ dom }} # init.sls contains the domain defaults
{% if salt['pillar.file_exists']("{0}/{1}".format(dom,host)+'.sls') %}
- {{ dom }}.{{ host }} # Host-specific pillars
{% endif %}
{% endif %}
-8<--
You can have hostdata/minion_snake_id.sls for per-minion defaults, that gets overridden by domain-specific pillars, that gets overridden by hostname.sls in domain directory (I either place full minion_id in hostdata or just hostname.sls in domain directory).
You can extend it to consider extra roles, but IMVHO it's handled better from state files: pillars should just give the authoritative config. Remember that the only grain that's safe to use is 'id'.
I'm just a Salt noob, please correct me if I'm wrong.
BYtE,
Diego