Search code examples
salt-project

Salt State Rendering: Can I See the Output of the Jinja Phase?


Question:

Is there any way to see the output of the Jinja phase, before attempting to parse as YAML?

Background:

I was trying to debug a Salt problem where I was getting this error:

local:
Data failed to compile:
----------
Rendering SLS ':test.sls' failed: mapping values are not allowed in this context

Not very helpful: No line number? What's a 'mapping value'? etc.

The problem boiled down to something like this:

{%- for x in [1, 2] -%}
Test {{ x }}:
  cmd.run:
    - name: echo Test {{ x }}
{%- endfor -%}

A seasoned Salt person will recognize that I've messed up the whitespace so that the Jinja was producing the output below:

Test 1:
  cmd.run:
    - name: echo Test 1 Test 2:
  cmd.run:
    - name: echo Test 2

However, this was frustrating to find in a complex set of states with no information on where the problem was occurring and no clear description of what the problem even was.

In the process of debugging this I learned that you can get the YAML tree using slsutil.renderer, like this:

% salt-call --local slsutil.renderer `pwd`/test.sls 'jinja'

local:
    ----------
    Test 1:
        ----------
        cmd.run:
            |_
              ----------
              name:
                  echo Test 1
    Test 2:
        ----------
        cmd.run:
            |_
              ----------
              name:
                  echo Test 2

But this of course requires that the YAML is valid. So how can I get Salt to output the templates as in my third snippet above, AFTER the Jinja has been evaluated but BEFORE Salt tries to parse it as YAML?


Solution

  • Oh wow, as I revisit this I've learned something new. I believe the answer is cp.get_template.

    Test file:

    % cat test.sls
    
    {%- for x in [1, 2] -%}
    Test {{ x }}:
      cmd.run:
        - name: echo Test {{ x }}
    {%- endfor -%}
    

    Now cp.get_template renders the Jinja and shows the raw output:

    % salt-call --local cp.get_template `pwd`/test.sls /dev/stdout
    
    Test 1:
      cmd.run:
        - name: echo Test 1Test 2:
      cmd.run:
        - name: echo Test 2
    local:
        /dev/stdout