I am trying to find an execution module that will allow me to pass a file through the Jinja templating engine and supply the arguments that should be replaced. There exists a file.managed
state module that accomplishes this behavior:
my cool state:
file.managed:
- source: salt://my/cool/file.xml
- name: 'C:\Program Files\My dir\file.xml'
- template: jinja
- context:
someVar: 'some value'
another_var: 12345
However, I cannot find an execution module that can do this. There is file.manage_file but it has a bunch of required arguments that I don't care about: sfn
, ret
, source
, source_sum
, user
, group
, mode
, attrs
, saltenv
, backup
-- file.manage_file
will fail if you do not provide values for these.
The closest module function I've found is cp.get_template but it doesn't allow you to pass in context
or defaults
, so I've had to templatize my XML file to read in data from the pillar like so:
{%- from "map.jinja" import my_vars with context %}
<?xml version="1.0" encoding="UTF-8"?>
<root>
<some-element>{{ my_vars.some-element }}</some-element>
<another-thing>{{ my_vars.another-thing }}</another-thing>
</root>
This works, but then I can only render my XML with pillar data -- I want to be able to pass in variables when calling my execution module and use those variables to render my XML. Is there any way to accomplish this behavior with an execution module?
I figured this out using a combination of execution modules:
# Get template file
templateContent = __salt__['cp.get_file_str'](
'salt://my/cool/file.xml'
)
# Render file with Jinja
renderedContent = __salt__['file.apply_template_on_contents'](
contents = templateContent,
template = 'jinja',
saltenv = 'base',
defaults = defaults,
context = context
)
# Write the rendered file to disk
__salt__['file.write'](
'/opt/some/path/on/minion/file.xml',
renderedContent
)
Two things to consider:
file.apply_template_on_contents
requires that you supply both the defaults
and context
args. This actually worked out pretty well for my use-case because I set defaults using values from a pillar that is applied to all minions, and context
is the user-supplied overrides.
cp.get_file_str
returns the file contents as a string -- I don't know how this would perform on a very large file, but for smaller configuration files I don't see an issue.