This gist provides a quick overview of deploying SSL certificates to servers using Salt. I use a wildcard certificate for our domain, which makes management easier.
- Start with
pillar_ssl-certificate.sls, which should be populated with your certificates and placed in Salt'spillar_rootsdirectory (typically/srv/pillar). - Place
state_ssl-certificate.slsin Salt'sfile_rootsdirectory (typically/srv/salt). - Include the contents of
top.slsin both the pillar and statetop.slsfile. (Modify for your minion IDs of course.)
Use pillars to distribute sensitive data, such as SSL certificates. Accoring to the Salt Pillar Walkthrough:
Information transferred via pillar is guaranteed to only be presented to the minions that are targeted, making Pillar suitable for managing security information, such as cryptographic keys and passwords.
Also read through Salt Best Practices: Storing Secure Data.
Make sure to match minion IDs in the pillar file, not grains! (See is targeting using grain data secure?)
I have embedded the file contents directly in the pillar SLS and used contents_pillar in the state SLS. Since I'm also defining the owning user and group, filenames, and permissions, this keeps everything together. PEM encoding works best, by the way.
You'll notice that I am maintaining symlinks (current.{crt,key}) to the certificate files. This allows me to point service configuration files to the symlinks, which in turn allows me to keep older certificate versions on the server for troubleshooting and easy roll-back without touching service config files. This also means that service.running has to watch the symlinks and the certificate files to trigger a restart under all necessary circumstances.
For service auto-restart, define ssl.services for each minion. These don't have to be assigned as pillars (they could be grains or state variables), but I find it's easiest to use pillars. I have included an example ~pillar_top.sls segment, which references ~pillar_web-server.sls. (Place under pillar_roots.) The nice thing is, ssl.services is addtive, so you can assign services to the same minion in multiple SLS files, and they will simply append to the existing list.
- If your certificate chain includes intermediate certificates, remember to include the entire chain (sans root) in
cert.contents. (See RFC 5246.) - The leading
pillar_,state_, etc. in the gist filenames should be stripped. (These are used to organize this gist.) - The exercise of deploying separate certificates to individual minions is left to the reader.