Suppose I have different credentials in two different environments, but that's the only thing that differs between them, and I don't want to make extra pillar files for a single item.
Suppose I attack the problem like this:
{%- set deployment = grains.get('deployment') %}
{%- load_yaml as credentials %}
prod: prodpassword
test: testpassword
dev: devpassword
{%- endload %}
some_app:
user: someuser
password: {{ credentials[deployment] }}
...more configuration here...
This works as expected. But can a minion in test theoretically get the password for prod? That depends on whether the dict lookup happens before or after data is sent to the client, I think, which in turn depends on when the jinja is rendered. Does the master render it first and then send the resulting data, or does the minion receive the pillar file as-is, then render it itself?
Pillar data is always rendered on the master, never the minion. The master does have access to the minion's grains, however, which is why your example works.
Given a Pillar SLS file with the following contents:
test: {{ grains['id'] }}
The following pillar data will result:
# salt testminion pillar.item test
testminion:
----------
test:
testminion
Source: I'm a SaltStack core developer.