From: W. Trevor King Date: Thu, 12 Dec 2013 17:34:46 +0000 (-0800) Subject: posts:salt-stack: Add Salt post X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=1abdac106cbe7dc197482c0fb70b201f3658798d;p=blog.git posts:salt-stack: Add Salt post --- diff --git a/posts/Salt_Stack.mdwn b/posts/Salt_Stack.mdwn new file mode 100644 index 0000000..10c0b92 --- /dev/null +++ b/posts/Salt_Stack.mdwn @@ -0,0 +1,163 @@ +[Salt][] is a remote execution and automated deployment system. It's +great for running your own clusters once your website outgrows a +single box. If you get bored of running your own boxes, you can use +[salt-cloud][] to provision minions on someone else's cloud (Amazon +EC2, Linode, …). You can install Salt on [[Gentoo]] with: + + # USE=git emerge -av app-admin/salt + +[Usually][syndic] you'll have one master, and a host of minions +running salt daemons that locally execute commands sent from the +master. After setting up [[BIND]] so `salt` (the [default master +name][master-name]) resolves to your development box, you should be +able to run: + + # /etc/init.d/salt-master start + # /etc/init.d/salk-minion restart + # salt-key -L + Accepted Keys: + Unaccepted Keys: + devbox.example.net + Rejected Keys: + # salt-key -A + The following keys are going to be accepted: + Unaccepted Keys: + devbox.example.net + Proceed? [n/Y] y + Key for minion devbox.example.net accepted. + +If you were not confined to the local box, it would be wise to compare +the proposed key: + + # salt-key -p devbox.example.net + +with that on the minon itself: + + # cat /etc/salt/pki/minion/minion.pub + +before accepting the key. + +Once you have accepted the minon, ping it: + + # salt '*' test.ping + devbox.example.net: + True + +Then you can browse through all of the [available goodies][api]: + + # salt '*' sys.doc + +Once you've had some fun reading about those, it's time to [configure +your state tree][state]. For a quick intro, we can just borrow the +[salt-state example repository][salt-states]. The salt state data is +conventionally kept in `/srv/salt`, which seemed odd to me, but does +indeed follow the [FHS][FHS-srv]. + + # mkdir /srv/ + $ git clone git://github.com/saltstack/salt-states.git + # mv salt-states /srv/salt + +This leaves `/srv/salt` owned by my personal user (instead of root), +because as much as I love [[Git]], I'm not going to run it as root. + +Once you've got a state tree in `/srv/salt`, you can mock-install the +configured state for each node. It's always a good idea to [test your +commands][testing] before you run them, to make sure they won't do +something wonky. + + # salt '*' state.highstate test=True + devbox.example.net: + ---------- + State: - file + Name: /etc/hosts + Function: comment + Result: None + Comment: File /etc/hosts is set to be updated + Changes: + ---------- + State: - file + Name: /etc/hosts + Function: uncomment + Result: True + Comment: Pattern already uncommented + Changes: + ---------- + State: - cmd + Name: date > /tmp/date + Function: run + Result: None + Comment: Command "date > /tmp/date" would have been executed + Changes: + ---------- + … + +You can also install a particular sub-state on a particular minon +(again, I'm showing the testing version): + + # salt 'devbox.example.net' state.sls python,ssh.server test=True + nott.tremily.us: + ---------- + State: - pkg + Name: openssh + Function: installed + Result: False + Comment: Package category missing for "openssh" (possible matches: net-misc/openssh). + Changes: + ---------- + State: - pkg + Name: python-mako + Function: installed + Result: False + Comment: Package category missing for "python-mako" and no match found in portage tree. + Changes: + + ---------- + … + +The comments (Package category missing for…) mean that the +[salt-states][] repository hasn't been updated to [recent][3008] +[versions][3009] [of][3019] Salt (0.12+), which [require fully +qualified package names][ebuild-cat]. + +For single-box testing, you can also skip the master node, running +commands on a [masterless minion][masterless] by using `salt-call +--local` instead of `salt ''` in your Salt invocations: + + # salt-call --local state.highstate test=True + local: + ---------- + State: - file + Name: /etc/hosts + Function: comment + Result: None + Comment: File /etc/hosts is set to be updated + Changes: + ---------- + … + +Because you don't have a master passing you state, `--local` calls +require you to have the state stored on your local box (in `/srv/salt` +by default). It's hard to imagine using Salt without storing state +anywhere ;). + +It's also possible to [run Salt as a non-root user][nonroot], but I +haven't looked into that yet. + +[Salt]: http://saltstack.com/community.html +[salt-cloud]: https://github.com/saltstack/salt-cloud +[syndic]: http://docs.saltstack.com/ref/syndic.html +[master-name]: http://docs.saltstack.com/ref/configuration/minion.html#master +[api]: http://docs.saltstack.com/ref/modules/all/ +[state]: http://docs.saltstack.com/topics/tutorials/starting_states.html +[salt-states]: https://github.com/saltstack/salt-states +[FHS-srv]: http://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#SRVDATAFORSERVICESPROVIDEDBYSYSTEM +[testing]: http://docs.saltstack.com/ref/states/testing.html +[3008]: https://github.com/saltstack/salt/pull/3008 +[3009]: https://github.com/saltstack/salt/pull/3009 +[3019]: https://github.com/saltstack/salt/pull/3019 +[ebuild-cat]: http://docs.saltstack.com/ref/modules/all/salt.modules.ebuild.html +[masterless]: http://docs.saltstack.com/topics/tutorials/quickstart.html +[nonroot]: https://salt.readthedocs.org/en/v0.17.0/topics/nonroot.html + +[[!tag tags/linux]] +[[!tag tags/tools]]