-->

SaltStack: how do I repeat other states with conte

2019-05-21 11:11发布

问题:

I created a complex state for API service, it involves git checkouts, python venv, uwsgi, nginx, etc etc. It works fine.

Now I would like to turn it into a template and execute it several times per minion, with variables supplied from pillar - i.e something like.

    {% for apiserver in pillar.apiservers %}
      include apiserver_template.sls, locals: apiserver.config
    {% endfor %}

where apiserver_template will work with context supplied to it, with apiserver.config having all config data for each API instance. I know syntax is wrong but hopefully I am communicating the idea - ideally, something like executing ruby partials with supplying local variables.

How is it done properly in saltland?

回答1:

It sounds to me like Jinja Macro is something you want to use for this. You can find more information about usage here: https://docs.saltstack.com/en/2015.8/topics/development/conventions/formulas.html#jinja-macros

In short what you will have in your case may look like:

{% macro api_server(git_repo, python_venv_path, python_venv_requirements) %}
{{python_venv_path}}:
  virtualenv.managed:
    - system_site_packages: False
    - requirements: salt://{{python_venv_requirements}}

{{git_repo}}:
  git.latest:
    - name: {{git_repo}}
{% endmacro %}

Assuming you have a pillar apiservers where each api server has git_repo, python_venv_path and python_venv_requirements values, you can use the macro like this:

{% for server in salt.pillar.get('apiservers', []) %}
{{ api_server(server['git_repo'], server['python_venv_path'], server['python_venv_requirements']) }}
{% endfor %}

If you want - you can also put a macro in a separate state file and then import a marco as a regular salt resource.

Please also not that instead of pillar.apiservers I used salt.pillar.get('apiservers', []). This is a safer way to get data from pillar. If for some reason a pillar is unavailable - the later code will result in empty dict instead of failure in first case.