salt-stack
Jose Ignacio Galarza
@igalarzab
Index
Why it’s so cool?
How to use it?
Developing for salt-stack
python
+
devops
salt-stack
infrastructure
management
master
not a polling model,

PUSHING
instructions

send
to
the minions telling them what to do
PUB/SUB system on 4505
REP system on 4506
awesome diagram
master

SUB

minion

PUB

minion

REP

minion
MessagePack to
serialize the messages
everything is

encrypted
it uses first public
authentication

keys

for

master needs to know public keys of
the minions
then, it uses

AES for communication
* (symmetric, faster)
how to accept minion keys?
$ salt-key	

Unaccepted Keys:	

minion_1	

!

$ salt-key -a minion_1
let’s go!
$	

salt ‘*’ test.ping
!
!
!

minion_1:	

True
minions
controlled machines
receive instructions
via
PUB/SUB ZeroMQ
masterless
configuration
* (salt-call)
modules
they provide the

functionality
S3
pip

apt

ssh
iptables

pam

nginx
apache

aliases
mysql

mount
file
upstart

quota
execute them with the cli!
$ salt ‘*’ cmd.run ‘ls /’	

...
$ salt ‘*’ state.highstate	

...
states
manage or
configure in your
hosts

what to
salt-stack states are just
DATA
* usually in YAML
they usually map to module
functions
understanding states
!
!
!
!
!
!
!
!
!

/etc/init/nginx.conf:
file:
- managed
- template: jinja
- user: root
- require:
- p...
nginx:	

  pkg.installed:	

    - name: nginx	

  file:	

    - managed	

    - name: /etc/init/nginx.conf	

    - source: ...
there are a lot of directives
require

watch

extend

include
returners
save the
minion output
where to
mongo
stdout
redis
SQL DB
renderers
language of the state
configuration
YAML
python
JSON
...
grains
configuration of the
machine
* read-only data
** populated at the beginning
using grains...
{% if grains['os'] == 'RedHat' %}	

httpd:	

pkg:	

- installed	

{% elif grains['os'] == 'Debian' %}	

ap...
list the grains
$ salt ‘*’ grains.ls	

...

you can use them everywhere
dev:	

‘os:Debian’:	

- match: grain	

- python_se...
pillar
think of pillar as a

variable container
it’s data,
just as same as the states
create a pillar of salt...
{% if grains['os'] == 'RedHat' %}	

apache: httpd	

git: git	

{% elif grains['os'] == 'Debian'...
and use it!
apache:	

pkg:	

- installed	

- name: {{ pillar['apache'] }}
only salt-stack?
salt-bootstrap
salt-cloud
salt-vagrant
halite
developing for
salt-stack
developing
modules
it’s like developing a normal
python module!
just create a file inside the _modules dir
every callable is
exported*
* (with some exceptions)
creating a module (for the pip-tools package)
import re!
!
import salt.utils!
from salt.utils.decorators import memoize!
!...
creating a module (for the pip-tools package)
!
def review(autoinstall=False):!
command_ret = __salt__['cmd.run'](!
'pip-r...
syncing the modules
$ salt-call saltutil.sync_modules	

...

and use it!
$ salt-call piptools.review	

machine:	

--------...
useful variables like:

__salt__
__grains__
__outputter__
developing
states
it’s (also) like developing a
normal python module!
just create a file inside the _states dir
every callable is
exported*
* (with some exceptions)
the renderer structure

maps directly
to the state python module
creating a state (for the pip-tools package)
def keep_updated(name, min_version=None, max_version=None):!
updatable_packag...
creating a state (for the pip-tools package)
!
if package_info:!
ret['comment'] = 'Update {0} from {2} to {1}'.format(!
na...
mapping the file
!

Jinja2:
pip_package:
- keep_updated
- min_version: 1.0

#
#
#
#

maps
maps
maps
maps

to
to
to
to

"na...
and that’s all!
http://twitter.com/igalarzab
http://github.com/igalarzab
questions?
thank you!
Salt stack
Upcoming SlideShare
Loading in …5
×

Salt stack

3,109 views

Published on

An introduction about how to use salt-stack and how to improve it developing new modules and states with Python

Published in: Technology

Salt stack

  1. 1. salt-stack Jose Ignacio Galarza @igalarzab
  2. 2. Index Why it’s so cool? How to use it? Developing for salt-stack
  3. 3. python + devops
  4. 4. salt-stack
  5. 5. infrastructure management
  6. 6. master
  7. 7. not a polling model, PUSHING
  8. 8. instructions send to the minions telling them what to do
  9. 9. PUB/SUB system on 4505 REP system on 4506
  10. 10. awesome diagram master SUB minion PUB minion REP minion
  11. 11. MessagePack to serialize the messages
  12. 12. everything is encrypted
  13. 13. it uses first public authentication keys for master needs to know public keys of the minions
  14. 14. then, it uses AES for communication * (symmetric, faster)
  15. 15. how to accept minion keys? $ salt-key Unaccepted Keys: minion_1 ! $ salt-key -a minion_1
  16. 16. let’s go! $ salt ‘*’ test.ping ! ! ! minion_1: True
  17. 17. minions
  18. 18. controlled machines
  19. 19. receive instructions via PUB/SUB ZeroMQ
  20. 20. masterless configuration * (salt-call)
  21. 21. modules
  22. 22. they provide the functionality
  23. 23. S3 pip apt ssh iptables pam nginx apache aliases mysql mount file upstart quota
  24. 24. execute them with the cli! $ salt ‘*’ cmd.run ‘ls /’ ... $ salt ‘*’ state.highstate ...
  25. 25. states
  26. 26. manage or configure in your hosts what to
  27. 27. salt-stack states are just DATA * usually in YAML
  28. 28. they usually map to module functions
  29. 29. understanding states ! ! ! ! ! ! ! ! ! /etc/init/nginx.conf: file: - managed - template: jinja - user: root - require: - pkg: nginx
  30. 30. nginx:   pkg.installed:     - name: nginx   file:     - managed     - name: /etc/init/nginx.conf     - source: salt://nginx.conf     - require:       - pkg: nginx service:     - running     - enable: True - watch:       - file: /etc/nginx/nginx.conf
  31. 31. there are a lot of directives require watch extend include
  32. 32. returners
  33. 33. save the minion output where to
  34. 34. mongo stdout redis SQL DB
  35. 35. renderers
  36. 36. language of the state configuration
  37. 37. YAML python JSON ...
  38. 38. grains
  39. 39. configuration of the machine * read-only data ** populated at the beginning
  40. 40. using grains... {% if grains['os'] == 'RedHat' %} httpd: pkg: - installed {% elif grains['os'] == 'Debian' %} apache2: pkg: - installed {% endif %}
  41. 41. list the grains $ salt ‘*’ grains.ls ... you can use them everywhere dev: ‘os:Debian’: - match: grain - python_server
  42. 42. pillar
  43. 43. think of pillar as a variable container
  44. 44. it’s data, just as same as the states
  45. 45. create a pillar of salt... {% if grains['os'] == 'RedHat' %} apache: httpd git: git {% elif grains['os'] == 'Debian' %} apache: apache2 git: git-core {% endif %}
  46. 46. and use it! apache: pkg: - installed - name: {{ pillar['apache'] }}
  47. 47. only salt-stack?
  48. 48. salt-bootstrap salt-cloud salt-vagrant halite
  49. 49. developing for salt-stack
  50. 50. developing modules
  51. 51. it’s like developing a normal python module! just create a file inside the _modules dir
  52. 52. every callable is exported* * (with some exceptions)
  53. 53. creating a module (for the pip-tools package) import re! ! import salt.utils! from salt.utils.decorators import memoize! ! REVIEW_RE = re.compile(‘([wd_-]+)==([d.]+) is available (you have ([d.]+))’)! ! ! @memoize! def _detect_install():! return salt.utils.which('pip-review')! ! ! def __virtual__():! return 'piputils' if _detect_install() else False!
  54. 54. creating a module (for the pip-tools package) ! def review(autoinstall=False):! command_ret = __salt__['cmd.run'](! 'pip-review {0}'.format('-a' if autoinstall else '')! )! ! packages = command_ret.split('n')! updates = {}! ! for package in packages:! match = REVIEW_RE.match(package)! if match:! name, old_v, new_v = match.groups()! updates[name] = (old_v, new_v)! ! return updates!
  55. 55. syncing the modules $ salt-call saltutil.sync_modules ... and use it! $ salt-call piptools.review machine: ---------- Jinja2: - 2.7.1 - 2.6
  56. 56. useful variables like: __salt__ __grains__ __outputter__
  57. 57. developing states
  58. 58. it’s (also) like developing a normal python module! just create a file inside the _states dir
  59. 59. every callable is exported* * (with some exceptions)
  60. 60. the renderer structure maps directly to the state python module
  61. 61. creating a state (for the pip-tools package) def keep_updated(name, min_version=None, max_version=None):! updatable_packages = __salt__['piptools.review']()! pkg_info = updatable_packages.get(name, None)! ! ret = {! 'name': name,! 'result': pkg_info is not None,! }!
  62. 62. creating a state (for the pip-tools package) ! if package_info:! ret['comment'] = 'Update {0} from {2} to {1}'.format(! name, *pkg_info! )! ret['changes'] = {!          name: {! 'old': package_info[1],! 'new': package_info[0]! }! }! else:! ret['comment'] = 'Inexistent package {0}'.format(name)! ! if __opts__['test']:! ret['result'] = None!     else:! pass # Perform the update! ! return ret!
  63. 63. mapping the file ! Jinja2: pip_package: - keep_updated - min_version: 1.0 # # # # maps maps maps maps to to to to "name" argument pip_package state keep_updated funct min_version arg
  64. 64. and that’s all! http://twitter.com/igalarzab http://github.com/igalarzab
  65. 65. questions?
  66. 66. thank you!

×