$ systemctl start salt-master $ systemctl enable salt-master
/etc/salt/minion.d/master.conf
et indiquer lui votre master :master: salt-master
$ systemctl start salt-minion $ systemctl enable salt-minion
salt-key -L a Accepted Keys: Denied Keys: Unaccepted Keys: portable.localdomain
salt-call key.finger --local local: 14:e6:21:3b:0c:f9:0a:96:ea:5a:69:bb:2e:82:b4:c7:18:3c:4f:09:40:d2:46:8f:f9:09:e9:81:87:15:1a:0f
salt-key -f portable.localdomain Unaccepted Keys: portable.localdomain: 14:e6:21:3b:0c:f9:0a:96:ea:5a:69:bb:2e:82:b4:c7:18:3c:4f:09:40:d2:46:8f:f9:09:e9:81:87:15:1a:0f
salt-key -a portable.localdomain The following keys are going to be accepted: Unaccepted Keys: portable.localdomain Proceed? [n/Y] Key for minion portable.localdomain accepted.
salt-key -L a [sudo] Mot de passe de gigix : Accepted Keys: portable.localdomain Denied Keys: Unaccepted Keys: Rejected Keys:
sudo salt 'portable.localdomain' test.ping portable.localdomain: True
salt-key -f master.pub Local Keys: master.pub: 1b:5e:6d:ae:20:65:dd:f1:62:0b:9b:85:eb:3a:38:8d:ec:d6:cf:98:06:3d:ca:65:fb:a7:dd:c6:86:15:bb:96
/etc/salt/minion.d/master.conf
:master: localhost master_finger: '1b:5e:6d:ae:20:65:dd:f1:62:0b:9b:85:eb:3a:38:8d:ec:d6:cf:98:06:3d:ca:65:fb:a7:dd:c6:86:15:bb:96'
systemctl restart salt-minion
salt 'portable.localdomain' test.ping portable.localdomain: True
salt-call key.finger --local local: 14:e6:21:3b:0c:f9:0a:96:ea:5a:69:bb:2e:82:b4:c7:18:3c:4f:09:40:d2:46:8f:f9:09:e9:81:87:15:1a:0f
salt-key -F Local Keys: master.pem: 83:9f:f3:37:c6:6c:f8:55:5e:84:c7:60:4d:10:59:ce:a2:81:23:47:1a:bf:df:c1:6f:f1:3f:85:48:ee:8a:b0 master.pub: 1b:5e:6d:ae:20:65:dd:f1:62:0b:9b:85:eb:3a:38:8d:ec:d6:cf:98:06:3d:ca:65:fb:a7:dd:c6:86:15:bb:96 Accepted Keys: portable.localdomain: 14:e6:21:3b:0c:f9:0a:96:ea:5a:69:bb:2e:82:b4:c7:18:3c:4f:09:40:d2:46:8f:f9:09:e9:81:87:15:1a:0f
Les pillars sont chargés quand le minion démarre, ou on peu le faire manuellement :
salt '*' saltutil.refresh_pillar salt '*' saltutil.refresh_grains
Tout resynchroniser :
salt '*' saltutil.sync_all
Client en standalone (serverless) :
salt-call --local grains.items
Exécution sur le master :
salt-run test.foo
Exécution vers un cloud provider (https://docs.saltstack.com/en/latest/topics/cloud/index.html) :
salt-cloud
Client vers serveur :
salt-call grains.items
Serveur vers clients via SSH (agentless) :
salt-ssh -i --roster-file=./roster 'node1' test.ping
Exemple de fichier roster (toutes les options du fichier roster) :
node1: host: 192.168.122.1 user: root priv: /root/.ssh/id_rsa
Serveur vers clients via client salt :
salt '*' cmd.run 'ls -l /etc' salt '*' test.ping
Autres :
salt '*' cmd.run 'echo "Hello: $FIRST_NAME"' saltenv='{FIRST_NAME: "Joe"}'
salt myminion grains.item pythonpath --out=pprint
salt '*' cp.get_file salt://vimrc /etc/vimrc salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=jinja
salt '*' -b 10 test.ping salt -G 'os:RedHat' --batch-size 25% apache.signal restart
base: 'not webserv* and G@os:Debian or E@web-dc1-srv.* and ( ms-1 or G@id:ms-3 ) or J|@foo|bar|^foo:bar$': - match: compound - webserver
States :
salt '*' sys.doc salt '*' sys.doc cmd salt '*' sys.doc cmd.run
Runner :
salt-run doc.runner
<Include Declaration>: - <Module Reference> - <Module Reference> <Extend Declaration>: <ID Declaration>: [<overrides>] # standard declaration <ID Declaration>: <State Module>: - <Function> - <Function Arg> - <Function Arg> - <Function Arg> - <Name>: <name> - <Requisite Declaration>: - <Requisite Reference> - <Requisite Reference> # inline function and names <ID Declaration>: <State Module>.<Function>: - <Function Arg> - <Function Arg> - <Function Arg> - <Names>: - <name> - <name> - <name> - <Requisite Declaration>: - <Requisite Reference> - <Requisite Reference> # multiple states for single id <ID Declaration>: <State Module>: - <Function> - <Function Arg> - <Name>: <name> - <Requisite Declaration>: - <Requisite Reference> <State Module>: - <Function> - <Function Arg> - <Names>: - <name> - <name> - <Requisite Declaration>: - <Requisite Reference>
httpd: pkg.installed: []
Ou
httpd: pkg: - installed
httpd: pkg.installed: [] service.running: []
ius: pkgrepo.managed: - humanname: IUS Community Packages for Enterprise Linux 6 - $basearch - gpgcheck: 1 - baseurl: http://mirror.rackspace.com/ius/stable/CentOS/6/$basearch - gpgkey: http://dl.iuscommunity.org/pub/ius/IUS-COMMUNITY-GPG-KEY - names: - ius - ius-devel: - baseurl: http://mirror.rackspace.com/ius/development/CentOS/6/$basearch
httpd: pkg.installed service.running
salt '*' state.apply
salt '*' state.apply gigix
salt '*' state.apply mysls1,mysls2 test=true saltenv=dev pillarenv=dev pillar='{"key": "val"}' exclude="[{'id': 'id_to_exclude'}, {'sls': 'sls_to_exclude'}]"
salt --pillar 'webserver_role:dev' state.apply
salt-call --local --file-root=$PWD state.sls_id this_state_will_return_changes test local: ---------- ID: this_state_will_return_changes Function: test.succeed_with_changes Result: True Comment: Success! Started: 00:38:08.528352 Duration: 0.287 ms Changes: ---------- testing: ---------- new: Something pretended to change old: Unchanged Summary for local ------------ Succeeded: 1 (changed=1) Failed: 0 ------------ Total states run: 1 Total run time: 0.287 ms
https://docs.saltstack.com/en/latest/ref/states/top.html#advanced-minion-targeting
salt 'web[1-5]' test.ping salt 'web[1,3]' test.ping salt '*.example.*' test.ping salt 'web?.example.net' test.ping
base: 'web[1,3]': - match: glob - webserver
salt -E 'web1-(prod|devel)' test.ping
base: 'web1-(prod|devel)': - match: pcre - webserver
salt -L 'web1,web2,web3' test.ping
base: 'web1,web2,web3': - match: list - webserver
salt -G 'os:Fedora' test.ping
'node_type:webserver': - match: grain - webserver
salt 'P@os:(RedHat|Fedora|CentOS)' test.ping
'os:Fedo.*': - match: grain_pcre - webserver
'cheese:foo': - match: pillar_exact - webserver
salt -I 'somekey:specialvalue' test.ping salt -I 'foo:bar:baz*' test.ping
'cheese:foo:baz*': - match: pillar - webserver
salt 'J@pdata:^(foo|bar)$' test.ping
'cheese:(swiss|american)': - match: pillar_pcre - webserver
/etc/salt/master
) :nodegroups: group1: 'L@foo.domain.com,bar.domain.com,baz.domain.com and bl*.domain.com' group2: 'G@os:Debian and foo.domain.com' group3: 'G@os:Debian and N@group1'
base: group1: - match: nodegroup - webserver
salt -S 192.168.40.20 test.ping salt -S 2001:db8::/64 test.ping
'172.16.0.0/12': - match: ipcidr - internal
salt -C 'G@os:Debian and webser* or E@db.*' test.ping salt -C '* and not G@kernel:Darwin' test.ping salt -C '( ms-1 or G@id:ms-3 ) and G@id:ms-3' test.ping
base: 'webserv* and G@os:Debian or E@web-dc1-srv.*': - match: compound - webserver
salt 'R@%test:APPS' test.ping
CLUSTER: host1..100.test.com APPS: - frontend - backend - mysql
salt '*' state.disable mysql
Pour lister ceux qui ont été désactivés :
salt '*' state.list_disabled
salt '*' state.enable gigix
salt '*' state.show_highstate salt '*' state.show_lowstate salt '*' state.show_low_sls foo saltenv=dev salt '*' state.show_sls core,edit.vim dev
Voir le contenu top sls des serveurs :
salt '*' state.show_top
salt '*' state.running local: - The function "state.apply" is running as PID 13972 and was started at 2018, Mar 03 13:14:07.242163 with jid 20180303131407242163
salt '*' state.show_state_usage
{{ salt['pillar.get']('foo:bar:baz', 'qux') }}
{{ salt['grains.get']('node_type', '') }}
salt '*' grains.items
salt '*' pillar.items
{% set the_node_type = salt['grains.get']('node_type', '') %}
{% set name = { 'RedHat': 'httpd', 'Debian': 'apache2', }.get(grains.os_family) %}
{{ salt['module.function_name']('argument_1', 'argument_2') }} {{ salt['cmd.run']('pgrep -f redis-server') }}
{% set ethhb = salt['pillar.get']('eth-hb', 'bond1') %} {% if grains['ip4_interfaces'][ethhb][0].startswith('192.168.1.') %} host.present: - ip: {{ grains['ip4_interfaces'][ethhb][0] }} - names: - {{ grains['host'] }}-hb {% else %} cmd.run: - name: "echo '{{ ethhb }} is not properly configured !'; exit 1" {% endif %}
{% for user, uid in pillar.get('users', {}).items() %} {{user}}: user.present: - uid: {{uid}} {% endfor %}
La maccro est une sorte de fonction :
# macro message {% macro message(name, comment, changes=False, result=False, failhard=True) -%} pacemaker-{{ sls }}-{{ name }}: test.configurable_test_state: - name: pacemaker-{{ sls }}-{{ name }} - changes: {{ changes }} - result: {{ result }} - comment: {{ comment }} - failhard: {{ failhard }} {%- endmacro %} {{ message('error-test', 'mon erreur !!!', failhard=False) }}
Avec l'option failhard :
/etc/yum.repos.d/company.repo: file.managed: - source: salt://company/yumrepo.conf - user: root - group: root - mode: 644 - order: 1 - failhard: True
L'ordonnancement est possible grâce à require ou require_in (sa dépendance inversée) :
httpd: pkg.installed: [] service.running: - require: - pkg: httpd - sls: network
vim: pkg.installed: - require_in: - file: /etc/vimrc /etc/vimrc: file.managed: - source: salt://edit/vimrc
On peu également faire appel à order
:
apache: pkg.installed: - name: httpd - order: 1
Pour désigner le dernier : order: last
ou order: -1
.
L'exécution sur changement est possible grâce à onchanges ou onchanges_in (sa dépendance inversée). S'exécute seulement si le résultat de l'exécution cible est un succès et si la cible a des changements :
Deploy server package: file.managed: - name: /usr/local/share/myapp.tar.xz - source: salt://myapp.tar.xz Extract server package: archive.extracted: - name: /usr/local/share/myapp - source: /usr/local/share/myapp.tar.xz - archive_format: tar - onchanges: - file: Deploy server package
# (Archive arguments omitted for simplicity) # Match by ID declaration Extract server package: archive.extracted: - onchanges: - file: Deploy server package # Match by name parameter Extract server package: archive.extracted: - onchanges: - file: /usr/local/share/myapp.tar.xz
Cela se fait également avec watch et watch_in. watch agit comme require, mais ajoute un comportement supplémentaire (mod_watch). C'est à dire que si le module à une fonction mod_watchalors celle-ci sera appellée. Tous les modules n'ont pas de fonction mod_watch et s'exécuteront donc comme un simple require :
ntpd: service.running: - watch: - file: /etc/ntp.conf file.managed: - name: /etc/ntp.conf - source: salt://ntp/files/ntp.conf
On peu également le faire avec listen /listen_in.
Contrairement à watch et watch_in, listen et listen_in ne modifieront pas l'ordre des états et peuvent être utilisés pour s'assurer que vos états sont exécutés dans l'ordre dans lequel ils sont définis.
restart-apache2: service.running: - name: apache2 - listen: - file: /etc/apache2/apache2.conf configure-apache2: file.managed: - name: /etc/apache2/apache2.conf - source: salt://apache2/apache2.conf
restart-apache2: service.running: - name: apache2 configure-apache2: file.managed: - name: /etc/apache2/apache2.conf - source: salt://apache2/apache2.conf - listen_in: - service: apache2
Il y a aussi prereq et prereq_in expliqué ici.
La gestion des erreurs est possible grâce à onfail ou onfail_in (sa dépendance inverse).
primary_mount: mount.mounted: - name: /mnt/share - device: 10.0.0.45:/share - fstype: nfs backup_mount: mount.mounted: - name: /mnt/share - device: 192.168.40.34:/share - fstype: nfs - onfail: - mount: primary_mount
L'héritage est possible grâce à use ou use_in (sa dépendance inverse).
Dans cet exemple /etc/bar.conf
va prendre les même arguments que /etc/foo.conf
sauf pour la source
qu'il aura redéfini:
/etc/foo.conf: file.managed: - source: salt://foo.conf - template: jinja - mkdirs: True - user: apache - group: apache - mode: 755 /etc/bar.conf file.managed: - source: salt://bar.conf - use: - file: /etc/foo.conf
L'exécution en tant que est possible grâce à runas ou runas_in (sa dépendance inverse).
django: pip.installed: - name: django >= 1.6, <= 1.7 - runas: daniel - require: - pkg: python-pip run_script: cmd.run: - name: Powershell -NonInteractive -ExecutionPolicy Bypass -File C:\\Temp\\script.ps1 - runas: frank - runas_password: supersecret
unless et onlyif lance des commandes shell.
Dans l'exemple ci-dessous, vim sera installé quand toutes les conditions seront fausses :
vim: pkg.installed: - unless: - rpm -q vim-enhanced - ls /usr/bin/vim
onlyif est l'inverse qui signifie quand toutes les conditions serons vraies.
checkcmd permet de vérifier l'état attendu :
comment-repo: file.replace: - name: /etc/yum.repos.d/fedora.repo - pattern: ^enabled=0 - repl: enabled=1 - check_cmd: - ! grep 'enabled=0' /etc/yum.repos.d/fedora.repo
L'option retry lui permet d'être exécuté plusieurs fois jusqu'à ce qu'un résultat souhaité soit obtenu ou que le nombre maximum de tentatives ait été atteint.
Le paramètre attemps contrôle le nombre maximum de fois que l'état sera exécuté. S'il n'est pas spécifié ou si une valeur non valide est spécifiée, la valeur par défaut sera 2.
Le paramètre until définit le résultat requis pour arrêter de réessayer l'état. Si non spécifié ou si une valeur non valide est spécifiée alors la valeur par défaut sera True.
Le paramètre interval définit la durée, en secondes, pendant laquelle le système attendra entre les tentatives. Si elle n'est pas spécifiée ou si une valeur non valide est spécifiée, la valeur par défaut sera 30.
Le paramètre splay permet d'étendre l'intervalle. Si elle n'est pas spécifiée ou si une valeur non valide est spécifiée, la valeur par défaut est 0 (c'est-à-dire qu'il n'y aura pas d'intervalle).
my_retried_state: pkg.installed: - name: nano - retry: attempts: 5 until: True interval: 60 splay: 10
install_nano: pkg.installed: - name: nano - retry: True
wait_for_file: file.exists: - name: /path/to/file - retry: attempts: 15 interval: 30
Fichier ssh/init.sls
:
openssh-client: pkg.installed /etc/ssh/ssh_config: file.managed: - user: root - group: root - mode: 644 - source: salt://ssh/ssh_config - require: - pkg: openssh-client
Fichier ssh/server.sls
:
include: - ssh openssh-server: pkg.installed sshd: service.running: - require: - pkg: openssh-client - pkg: openssh-server - file: /etc/ssh/banner - file: /etc/ssh/sshd_config /etc/ssh/sshd_config: file.managed: - user: root - group: root - mode: 644 - source: salt://ssh/sshd_config - require: - pkg: openssh-server /etc/ssh/banner: file: - managed - user: root - group: root - mode: 644 - source: salt://ssh/banner - require: - pkg: openssh-server
Fichier ssh/custom-server.sls
:
include: - ssh.server extend: /etc/ssh/banner: file: - source: salt://ssh/custom-banner
On peut également exclure un id ou un sls :
exclude: - sls: http - id: /etc/vimrc
Il est de changer le comportement en spécifiant un provider. Par exemple systemd est le provider par défaut pour les services. Si on souhaite passer par init, on utilisera le provider service.
httpd: service.running: - enable: True - provider: service
emacs: pkg.installed: - provider: - cmd: customcmd
Tout est lancé en parallèle et prendra donc 10 secondes à la place de 15 :
sleep 10: cmd.run: - parallel: True nginx: service.running: - parallel: True - require: - cmd: sleep 10 sleep 5: cmd.run: - parallel: True
Le fichier /etc/salt/minion
doit contenir la ligne suivant pour êtreactivé : backup_mode: minion
.
/etc/ssh/sshd_config: file.managed: - source: salt://ssh/sshd_config - backup: minion
salt foo.bar.com file.list_backups /tmp/foo.txt foo.bar.com: ---------- 0: ---------- Backup Time: Sat Jul 27 2013 17:48:41.738027 Location: /var/cache/salt/minion/file_backup/tmp/foo.txt_Sat_Jul_27_17:48:41_738027_2013 Size: 13 1: ---------- Backup Time: Sat Jul 27 2013 17:48:28.369804 Location: /var/cache/salt/minion/file_backup/tmp/foo.txt_Sat_Jul_27_17:48:28_369804_2013 Size: 35
salt foo.bar.com file.restore_backup /tmp/foo.txt 1
salt foo.bar.com file.delete_backup /tmp/foo.txt 0
Lors de la définition de formules salt dans YAML, les données représentées sont appelées High Data par le compilateur. Lorsque les données sont initialement chargées dans le compilateur, il s'agit d'un seul grand dictionnaire python, ce dictionnaire peut être vu en exécutant :
salt '*' state.show_highstate salt '*' state.show_highstate --out yaml salt '*' state.show_sls edit.vim --out pprint
Cette structure “High Data” est ensuite compilée jusqu'au “Low Data”. Les données basses correspondent à ce qui est nécessaire pour créer des exécutions individuelles dans le système de gestion de la configuration de Salt. Les données faibles sont une liste ordonnée d'appels d'état unique à exécuter. Les données faibles sont une liste ordonnée d'appels à état unique à exécuter. Une fois que les données sont compilées, l'ordre d'évaluation peut être vu. Les lowstates peuvent être visualisées en exécutant:
salt '*' state.show_lowstate salt '*' state.low '{name: vim, state: pkg, fun: installed}'
Les pillar sont à définir dans le fichier /srv/pillar/top.sls
.
Exemples :
{{ saltenv }}: '*': - common_pillar
base: '*': - apache dev: 'os:Debian': - match: grain - vim test: '* and not G@os: Debian': - match: compound - emacs
Fichier /srv/pillar/apache.sls
:
apache: lookup: name: httpd config: tmpl: salt://apache/files/httpd.conf
Exemple pour y faire appel :
{{ salt['pillar.get']('apache:lookup:name') }}
always-passes-with-any-kwarg: test.nop: - name: foo - something: else - foo: bar always-passes: test.succeed_without_changes: - name: foo always-fails: test.fail_without_changes: - name: foo always-changes-and-succeeds: test.succeed_with_changes: - name: foo always-changes-and-fails: test.fail_with_changes: - name: foo my-custom-combo: test.configurable_test_state: - name: foo - changes: True - result: False - comment: bar.baz is-pillar-foo-present-and-bar-is-int: test.check_pillar: - present: - foo - integer: - bar this_state_will_return_changes: test.succeed_with_changes this_state_will_NOT_return_changes: test.succeed_without_changes this_state_is_watching_another_state: test.succeed_without_changes: - comment: 'This is a custom comment' - watch: - test: this_state_will_return_changes - test: this_state_will_NOT_return_changes this_state_is_also_watching_another_state: test.succeed_without_changes: - watch: - test: this_state_will_NOT_return_changes
Il prend le premier et s'il ne trouve pas il passe au suivant :
file_roots: base: - /srv/salt/prod qa: - /srv/salt/qa - /srv/salt/prod dev: - /srv/salt/dev - /srv/salt/qa - /srv/salt/prod
On appellera ces fichiers map.jinja.
{% set apache = salt['grains.filter_by']({ 'Debian': { 'server': 'apache2', 'service': 'apache2', 'conf': '/etc/apache2/apache.conf', }, 'RedHat': { 'server': 'httpd', 'service': 'httpd', 'conf': '/etc/httpd/httpd.conf', }, }, merge=salt['pillar.get']('apache:lookup')) %}
{% set htop = salt['grains.filter_by']({ 'Suse': { 'pattern': salt['grains.filter_by']({ '12.3': 'htop', 'default': 'htop', }, grain='osrelease'), }, 'default': { 'pattern': 'htop' }, }, grain='os') %}
On chargera par exemple le fichier apache/map.jinja
dans un fichier sls de la façon suivante :
{% from "apache/map.jinja" import apache with context %} apache: pkg.installed: - name: {{ apache.server }} service.running: - name: {{ apache.service }} - enable: True
$ salt-run manage.status down: - portable.localdomain up:
$ salt-run manage.down - portable.localdomain
$ salt-run manage.up - portable.localdomain
$ salt-run manage.versions Master: 2017.7.3 Up to date: ---------- portable.localdomain: 2017.7.3
# /srv/salt/orch/cleanfoo.sls cmd.run: salt.function: - tgt: '*' - arg: - rm -rf /tmp/foo
salt-run state.orchestrate orch.cleanfoo
# /srv/salt/orch/webserver.sls install_nginx: salt.state: - tgt: 'web*' - sls: - nginx
salt-run state.orchestrate orch.webserver
# /srv/salt/orch/web_setup.sls webserver_setup: salt.state: - tgt: 'web*' - highstate: True
salt-run state.orchestrate orch.web_setup
# /srv/salt/orch/deploy.sls create_instance: salt.runner: - name: cloud.profile - prof: cloud-centos - provider: cloud - instances: - server1 - opts: minion: master: master1
# /srv/salt/orch/deploy.sls {% set servers = salt['pillar.get']('servers', 'test') %} {% set master = salt['pillar.get']('master', 'salt') %} create_instance: salt.runner: - name: cloud.profile - prof: cloud-centos - provider: cloud - instances: - {{ servers }} - opts: minion: master: {{ master }}
salt-run state.orchestrate orch.deploy pillar='{"servers": "newsystem1", "master": "mymaster"}'
bootstrap_servers: salt.function: - name: cmd.run - tgt: 10.0.0.0/24 - tgt_type: ipcidr - arg: - bootstrap storage_setup: salt.state: - tgt: 'role:storage' - tgt_type: grain - sls: ceph - require: - salt: webserver_setup webserver_setup: salt.state: - tgt: 'web*' - highstate: True
https://docs.saltstack.com/en/latest/topics/mine/index.html
Une mine est identique à un grains mais moins statique. En effet celui-ci va être actualisé toutes les 60 minutes par défaut contrairement à un grains qui lui est actualisé seulement au démarrage du minion.
On peut changer dans la configuration du minion /etc/salt/minion
la variable mine_interval pour modifier le temps de collecte.
La mine se déclare comme un pillar avec la fonction mine_functions.
mine_functions: test.ping: [] network.ip_addrs: interface: eth0 cidr: '10.0.0.0/8'
Pour forcer la maj de toutes les mines :
salt '*' mine.update
https://docs.saltstack.com/en/latest/topics/beacons/index.html
Les beacons permettent de placer des hook sur des événements sur les minions.
Pour créer un beacons, créer le fichier /etc/salt/minion.d/beacons.conf
:
beacons: inotify: /etc/important_file: {} /opt: {}
Un autre exemple :
beacons: inotify: /etc/important_file: {} /opt: {} interval: 5 disable_during_state_run: True load: 1m: - 0.0 - 2.0 5m: - 0.0 - 1.5 15m: - 0.1 - 1.0 interval: 10
Par exemple si on modifie le fichier /etc/important_file
, cela va créer un event que l'on peu surveiller de cette façon sur le master :
salt-run state.event pretty=true
Ce qui affichera :
salt/beacon/larry/inotify//etc/important_file { "_stamp": "2015-09-09T15:59:37.972753", "data": { "change": "IN_IGNORED", "id": "larry", "path": "/etc/important_file" }, "tag": "salt/beacon/larry/inotify//etc/important_file" }
Un [#reactor] est la réponse du master à fournir à un minion lors d'un event sur un beacons.
https://docs.saltstack.com/en/latest/topics/reactor/index.html
Le reactor est la réponse à fournir aux beacons.
Sur le master, créer le fichier /srv/reactor/revert.sls
:
revert-file: local.state.apply: - tgt: {{ data['data']['id'] }} - arg: - maintain_important_file
Il faut maintenant indiquer au reactor d'exécuter le fichier revert sls, pour cela on édite le fichier /etc/salt/master.d/reactor.conf
:
reactor: - salt/beacon/*/inotify//etc/important_file: - /srv/reactor/revert.sls
Exemple de reactor :
reactor: # Master config section "reactor" - 'salt/minion/*/start': # Match tag "salt/minion/*/start" - /srv/reactor/start.sls # Things to do when a minion starts - /srv/reactor/monitor.sls # Other things to do - 'salt/cloud/*/destroyed': # Globs can be used to match tags - /srv/reactor/destroy/*.sls # Globs can be used to match file names - 'myco/custom/event/tag': # React to custom event tags - salt://reactor/mycustom.sls # Reactor files can come from the salt fileserver
{{ opts['cachedir'] }}
{{ salt['pillar.get']('key', 'failover_value') }} {{ salt['pillar.get']('stuff:more:deeper') }}
{{ salt['grains.get']('os') }}
{{ saltenv }}
{{ sls }}
{{ slspath }}
Copie un fichier du master vers les minions :
salt-cp '*' [ options ] SOURCE [SOURCE2 SOURCE3 ...] DEST
https://docs.saltstack.com/en/latest/topics/topology/syndic.html
salt-syndic permet de compartimenter les minions avec plusieurs masters. Chacun des master gèrent un groupe de minions.
Exemple :
# salt-key -L Accepted Keys: my_syndic Denied Keys: Unaccepted Keys: Rejected Keys: # salt '*' test.ping minion_1: True minion_2: True minion_4: True minion_3: True
https://docs.saltstack.com/en/latest/topics/proxyminion/index.html
salt-proxy permet de gérer des équipements où on ne peut pas installer de minion comme un switch réseau par exemple.
https://docs.saltstack.com/en/latest/topics/jobs/ https://docs.saltstack.com/en/latest/ref/runners/all/salt.runners.jobs.html
salt-run jobs.list_jobs
On le stop avec Ctrl+c mais je job continue:
sudo salt '*' test.sleep 100 ^C Exiting gracefully on Ctrl-c This job's jid is: 20180304011226668249 The minions may not have all finished running and any remaining minions will return upon completion. To look up the return data for this job later, run the following command: salt-run jobs.lookup_jid 20180304011226668249:
Le job n'a pas fini car il ne retourne rien :
sudo salt-run jobs.lookup_jid 20180304011226668249
Le job a terminé quand il retourne quelque chose :
salt-run jobs.lookup_jid 20180304011226668249 portable.localdomain: True
https://docs.saltstack.com/en/latest/ref/peer.html https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.publish.html
Permet à un minion d'exécuter une commande sur un autre.
Créer le fichier /etc/salt/master.d/peer.conf
pour autoriser les master entre eux (cet exemple n'est pas sécurisé et est déconseillé) :
peer: .*: - .*
Redémarrer votre master et tester :
salt '*' publish.publish '*' test.ping portable.localdomain: ---------- portable.localdomain: True salt-call publish.publish '*' test.ping local: ---------- portable.localdomain: True
Pour commenter dans un sls il suffit d'utiliser le #
.
Pour commenter un block on peu passer en mode jinja avec {#
et #}
:
{# mon commentaire ligne1 mon commentaire ligne2 #}
Editer le fichier de configuration /etc/salt/master.d/gitfs.conf
:
top_file_merging_strategy: same state_top_saltenv: base fileserver_backend: #- roots - git gitfs_provider: pygit2 gitfs_remotes: - https://github.com/gigi206/salt-test.git
roots correspond aux file_roots.
Chaque tag ou branche est accessible avec saltenv :
$ salt '*' state.apply saltenv=test $ salt '*' state.apply saltenv=base
auth: - __path__ (path to your module dir) modules: - __pillar__ - __salt__ - __opts__ - __context__ ({'systemd.sd_booted': True}) - __grains__ runners: - __pillar__ - __salt__ - __opts__ - __grains__ returners: - __salt__ - __opts__ - __pillar__ - __grains__ pillars: - __salt__ (modules) - __opts__ - __pillar__ - __grains__ # nothing tops: - ['__builtins__', '__file__', 'subprocess', 'yaml', '__name__', '__package__', '__doc__'] outputters: - __opts__ - __pillar__ - __grains__ states: - __pillar__ - __low__ (lowstate structure?) - __env__ - __running__ - __lowstate__ - __salt__ - __opts__ - __grains__ log_handlers: - __path__ renderers: - __salt__ - Execution functions (i.e. __salt__['test.echo']('foo')) - __grains__ - Grains (i.e. __grains__['os']) - __pillar__ - Pillar data (i.e. __pillar__['foo']) - __opts__ - Minion configuration options - __env__ - The effective salt fileserver environment (i.e. base). Also referred to as a "saltenv". __env__ should not be modified in a pure python SLS file. To use a different environment, the environment should be set when executing the state. This can be done in a couple different ways: Using the saltenv argument on the salt CLI (i.e. salt '*' state.sls foo.bar.baz saltenv=env_name). By adding a saltenv argument to an individual state within the SLS file. In other words, adding a line like this to the state's data structure: {'saltenv': 'env_name'} - __sls__ - The SLS path of the file. For example, if the root of the base environment is /srv/salt, and the SLS file is /srv/salt/foo/bar/baz.sls, then __sls__ in that file will be foo.bar.baz. grains: - __salt__ - __opts__ - __pillar__ - __grains__
salt-call --local -l debug --file-root=$PWD state.apply test=True
salt-call --local --file-root=$PWD state.orchestrate test=True
salt-run state.event pretty=True