Skip to content

Instantly share code, notes, and snippets.

@twork
Last active March 1, 2017 01:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twork/70a1a7d4225c5e0c1f3a91165beb115b to your computer and use it in GitHub Desktop.
Save twork/70a1a7d4225c5e0c1f3a91165beb115b to your computer and use it in GitHub Desktop.
TL;DR: is there some way to have a set of pillar data appear under differentent
names depending on the context? So:
minion-X gets a pillar titled "users:";
but minion-Y gets the same data, titled, oh, "user_record:"
...?
Longer:
I have a set of minions that provide a service: production minions, and test/dev
minions.
I use ext_pillar to govern the accounts on all my minions, these and others, using
the 'users' formula: https://github.com/saltstack-formulas/users-formula
minion-a gets mapped to pillar files "all.yml" and "file-a.yml";
minion-b gets mapped to pillar files "all.yml" and "file-b.yml";
...and so forth.
In all of those files are pillars we know and love:
users:
tom:
[...]
dick:
[...]
Simple so far.
I have a state that I've writtin, that we use for keeping an independent record
of our service's accounts. Simple, writes a dumb CSV file:
{% for name, user in pillar.get('users', {}).items() if user.absent is not defined or not user.absent %}
{% if 'service_user' in user %}
{{ name }}_account_record:
file.append:
- name: /root/userlist
- text: {{ user.get('fullname') }},{{ name }},{{ user.get('key') }}
{% endif %}
{% endfor %}
That state gets assigned to dev and stage instances of minions, not the production
instances. So far, that's how we've kept a record of accounts registered to use
this service: when a new set of accounts gets deployed, first we update our
minions, then we take a copy of that file and store it in another location.
It works but that two-stage process is brittle, clumsy, and not automatic.
Now:
I have a different minion, where I want to keep a record of users just like the
column described above, but where I do not want those users to have logins
on the host itself (in /etc/passwd and friends).
I could assign that {{ name }}_account_record state to my new minion, but I'd have
to map my account pillar files there, and the "users" formula will deploy those
accounts there when my new minion goes to highstate and I haven't solved anything.
My latest idea for fixing this (which I know is wrong) has been to do something
like:
account_record_file.yml [is a symlink to] account_pillar_file.yml
And, map "account_record_file" to my new minion. But that obviously misses the
mark. Both sets of minions are still getting the same "users:" pillars and
I still haven't solved anything.
But, is there some way to do essentially the same thing, but instead of a
symlink to a file, instead have a pillar -- oh, call it "user_records:" -- that
doesn't contain any data itself, but is really just a new name for an existing
pillar?
Then my state would change to:
{% for name, user in pillar.get('user_records', {}).items() if user.absent is not defined or not user.absent %}
{% if 'service_user' in user %}
{{ name }}_account_record:
file.append:
- name: /root/userlist
- text: {{ user.get('fullname') }},{{ name }},{{ user.get('key') }}
{% endif %}
{% endfor %}
I map that state to my new minion and it's Miller time.
But I don't know of any method for doing that kind of thing -- make a pillar
appear under different names depending on the context. I thought ext_pillar might
provie a way, but so far I haven't been able to figure that out.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment