saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Get access to the Salt software package repository here:
https://repo.saltproject.io/
Apache License 2.0
14.09k stars 5.47k forks source link

Simplify Pillar #2245

Closed rnd42 closed 10 years ago

rnd42 commented 11 years ago

After using Salt in a few different scenarios I've come to believe that the Pillar system could be greatly simplified. I understand that the following change would be a backwards incompatible so I know it woldn't be an immediate change but I wanted to spark something of an interface design discussion about this to see if anyone agrees with me.

In every situation where I've used Salt I've ended up creating identical or nearly identical .sls file trees for both my States and Pillar and it's just a bit ridiculous. I was thinking it would be much simpler and more natural to treat Pillar files similar to C header files. I would suggest .pil or perhaps .slp files with the same name as the acompanying .sls file to have that data automatically and implicitly included by the salt master and not shared with minions. This would mean that only one directory structure is needed and the pillar_root configuration variable would no longer be needed. Other Pillar data that needs to be included but is not directly related to any specific .sls file could still be manually included with the 'include' directive as normal.

Thoughts?

ghost commented 11 years ago

I like this. Keeping pillar separate is probably good practice, but I already keep template files mixed in with state files, so having the flexibility to allow pillar in that space seems logical and in some cases may be preferred. It would also be helpful to give them a name of their own instead of the .SLS extension.

thatch45 commented 11 years ago

The problem is that the idea of pillar is that you can't download the files at all, and any minion can download any files in the file_roots, so it would defeat the purpose of pillar to merge it.

thekuffs commented 11 years ago

I personally don't use identical trees between my pillar and state trees. I view it as a repository for containing configuration variables that differentiates two nodes that require the same service. If you have a pillar tree that mirrors your state tree I would argue that you don't need pillar at all.

For example

states/top.sls

base:
  '^web.(qa|prod)':
    - match: pcre
    - apache 

Apply the apache state to all web nodes in qa or prod.

pillar/top.sls

base:
  '^web.prod0[12].example.com$':
    - match: pcre
    - production_core
  '^web.prod0[34].example.com$':
    - match: pcre
    - production_customer_facing

Some of the web nodes will be customer facing, others will be internal. Apply different pillar configurations appropriately.

pillar/production_core.sls

apache_vhosts:
  - {fqdn: 'somesite.example.com', root: '/exports/somesite', cgi: 'php'}
  - {fqdn: 'othersite.example.com', root: '/exports/othersite', cgi: 'python'}

pillar/production_customer_facing.sls

apache_vhosts:
  - {fqdn: 'nagios.internal.example.com', root: '/private/nagios', cgi: 'perl'}
  - {fqdn: 'ganglia.internal.example.com', root: '/usr/share/ganglia', cgi: 'php'}

Both of the pillar configs define lists of vhost dictionaries intended to be running on the system.

states/apache/init.sls

apache:
  - pkg.installed
  - service.running:
    - enable: True
    - watch:
{% for vhost in pillar['apache_vhosts'] %}
      - file: vhost-{{ vhost['fqdn'] }}
{% endfor %}

{% for vhost in pillar['apache_vhosts'] %}
vhost-{{ vhost['fqdn'] }}:
  file.managed:
    - name: /etc/apache2/sites-enabled/{{ vhost['fqdn'] }}
    - template: jinja
    - context: {{ vhost }}
    - source: 'salt://apache/files/vhost_template.jinja'
{% endfor %}

(note: I am just injecting the vhost dictionary as the whole context into vhost_template.jinja. The string representation of Python dictionaries just happens to be valid yaml)

So we have a state defined for an apache webservice that can set up different vhosts for a given node depending on pillar data. Since all of the apache configurations across this deployment are consistent, it aids debugging and makes state control much easier. It also means that apache will get installed on QA nodes, but this state won't worry about the vhosts.

Within reason, if you have an identical set of vhosts on all of your web servers, you can just loop over them right in states/apache/init.sls which eliminates the need for pillar. However, I think my example here makes a pretty good case for needing the pillar and state tree to stay distinct.

Additionally, I recommend putting your files and templates into subdirectories of each state so as to make it easier to find the sls files and sort out what will pass through your template renderer.

thekuffs commented 11 years ago

I just realized that I misunderstood the suggestion and my example doesn't really speak to the utility of it at all. In my example, the directory structures could easily be merged and still be sane - so long as the pillar top.sls was preserved in some manner.

I still take advantage of pillar data staying 'private' to a given set of nodes, so @thatch45's point is important to me.

thatch45 commented 11 years ago

Thanks for the comments @thekuffs. @rnd42 in all reality we could add this functionality as an external pillar so we could allow it to be turned on in the manner you propose without compromising security in the other cases and without causing conflicts with the pillar system as it stands

rnd42 commented 11 years ago

I understand the point of having pillar data secure, however the benefit of that security seems somewhat limited to me. Consider for instance this grossly simplified example:

/srv/salt/top.sls:

base:
    'db\d+.example.com':
        - db
    'ids\d+.example.com':
        - ids
    'mail\d+.example.com':
        -  mail
    'web\d+.example.com':
        - web

/srv/salt/db.sls:

postgresql:
    pkg.latest:
 ... more details here ...

/srv/salt/ids.sls:

snort:
    pkg.latest:
 ... more details here ...

/srv/salt/mail.sls:

postfix:
    pkg.latest:
 ... more details here ...

/srv/salt/web.sls:

apache:
    pkg.latest:
... more details here ...

In the case that an intruder compromises say web1.example.com, if they notice that salt is managing the server then they can simply browse through the files in /var/cache/salt/files/base/ and see what my naming convention for servers is (as simplistic and straigh forward as that may be in the example) as well as the software those servers are running. This really is about all the information an intruder will likely need to island hop through your network. Additionally they see that snort is being deployed as an intrusion detection system so they would know what kinds of actions might send a red flag to the security staff and what actions are likely safe. Additionally the intruder who is familiar with salt can look at /etc/salt/minion and see the ip/name of the salt master where they know all the juicy pillar secrets may be kept.

In short, it seems to me that the approach of having all minions capibable of reading all state files is already very leaky from a security perspective. It would probably be much better to have only those .sls files that are applicable to a minion and any files referenced by those .sls files via includes or salt:// URIs available to the minion to start with. In configuration management there is very little system configuration data that does not represent a possible security risk.

I do know that you can have multiple state tree roots, however I'm not aware if a minion can read state files from roots that do not apply to it, perhaps that addresses this scenario?

In any case I really love salt and just wanted to put forward an idea for consideration. I do appreciate your time and attention.

rnd42 commented 11 years ago

Sorry, didn't mean to close the ticket....

thatch45 commented 11 years ago

These are some good points, which is why you can represent configuration data in pillar and then realize it in sls files securely. I do think that having an option to clear the file cache after each run would be a good idea though.

rnd42 commented 11 years ago

Yes, that would be a good option to add. Also the external pillar approch does seem like a good compromise.

Well I've had my say, I'll stop taking up your time unless there are any other ideas/comments. Thanks for considering my suggestion and all the hard work you guys do.

On Mon, Oct 15, 2012 at 6:04 PM, Thomas S Hatch notifications@github.comwrote:

These are some good points, which is why you can represent configuration data in pillar and then realize it in sls files securely. I do think that having an option to clear the file cache after each run would be a good idea though.

— Reply to this email directly or view it on GitHubhttps://github.com/saltstack/salt/issues/2245#issuecomment-9466848.

bretep commented 10 years ago

@thatch45 @rnd42 I'm not seeing any work to be done here. Can we close this out?

ghost commented 10 years ago

oh I miss you guys so much! :) pillar is awesome. I have this vision of an expansive salt flat from which a pillar emerges and subsequently a structure of data and applications deployment rises from the crystalline lake bed (as if the salt crystals were re-arranging themselves) and a data center with clouds of content (and maybe purple lightning) appear... then submerge back into the salt flats.

Please close this issue