4

Given three states, /root/a, /root/b and /root/c, I want /root/c to execute before /root/b, and /root/b to execute before /root/a.

Given a Salt SLS file salt://ordertest/init.sls:

/root/a:
  file.managed:
    - source: salt://ordertest/a
    - user: root
    - group: root
    - mode: 600 

/root/b:
  file.managed:
    - source: salt://ordertest/b
    - user: root
    - group: root
    - mode: 600 

/root/c:
  file.managed:
    - source: salt://ordertest/c
    - user: root
    - group: root
    - mode: 600

I can test to see the order in which the listed states would be applied. You'll see /root/a precede /root/b, and /root/b preceed /root/c.

$ salt my-minion-id state.apply ordertest test=True
my-minion-id:
----------
          ID: /root/a
    Function: file.managed
      Result: None
     Comment: The file /root/a is set to be changed
     Started: 13:54:23.538144
    Duration: 31.765 ms
     Changes:
----------
          ID: /root/b
    Function: file.managed
      Result: None
     Comment: The file /root/b is set to be changed
     Started: 13:54:23.570065
    Duration: 16.632 ms
     Changes:
----------
          ID: /root/c
    Function: file.managed
      Result: None
     Comment: The file /root/c is set to be changed
     Started: 13:54:23.586831
    Duration: 17.124 ms
     Changes:

Summary for my-minion-id
------------
Succeeded: 3 (unchanged=3)
Failed:    0
------------
Total states run:     3
Total run time:  65.521 ms

If we use require to directly tell /root/b to require /root/, and /root/c to require /root/b:

/root/a:
  file.managed:
    - source: salt://ordertest/a
    - user: root
    - group: root
    - mode: 600
    - require:
      - /root/b

/root/b:
  file.managed:
    - source: salt://ordertest/b
    - user: root
    - group: root
    - mode: 600
    - require:
      - /root/c

/root/c:
  file.managed:
    - source: salt://ordertest/c
    - user: root
    - group: root
    - mode: 600

We get the ordering we want:

$ salt my-minion-id state.apply ordertest test=True
my-minion-id:
----------
          ID: /root/c
    Function: file.managed
      Result: None
     Comment: The file /root/c is set to be changed
     Started: 13:32:33.624165
    Duration: 31.807 ms
     Changes:
----------
          ID: /root/b
    Function: file.managed
      Result: None
     Comment: The file /root/b is set to be changed
     Started: 13:32:33.656166
    Duration: 17.247 ms
     Changes:
----------
          ID: /root/a
    Function: file.managed
      Result: None
     Comment: The file /root/a is set to be changed
     Started: 13:32:33.673589
    Duration: 17.126 ms
     Changes:

Summary for my-minion-id
------------
Succeeded: 3 (unchanged=3)
Failed:    0
 ------------
Total states run:     3
Total run time:  66.180 ms

But if we try to use require_in to have /root/c place itself before /root/b:

/root/a:
  file.managed:
    - source: salt://ordertest/a
    - user: root
    - group: root
    - mode: 600
    - require:
      - /root/b

/root/b:
  file.managed:
    - source: salt://ordertest/b
    - user: root
    - group: root
    - mode: 600

/root/c:
  file.managed:
    - source: salt://ordertest/c
    - user: root
    - group: root
    - mode: 600
    - require_in:
      - /root/b

It doesn't work; /root/c stays at the end of the sequence:

my-minion-id:
----------
          ID: /root/b
    Function: file.managed
      Result: None
     Comment: The file /root/b is set to be changed
     Started: 13:36:54.037214
    Duration: 32.401 ms
     Changes:
----------
          ID: /root/a
    Function: file.managed
      Result: None
     Comment: The file /root/a is set to be changed
     Started: 13:36:54.069797
    Duration: 16.968 ms
     Changes:
----------
          ID: /root/c
    Function: file.managed
      Result: None
     Comment: The file /root/c is set to be changed
     Started: 13:36:54.086908
    Duration: 17.349 ms
     Changes:

Summary for my-minion-id
------------
Succeeded: 3 (unchanged=3)
Failed:    0
------------
Total states run:     3
Total run time:  66.718 ms

Here, you can see that /root/b was ordered before /root/a as appropriate, but /root/c did not get ordered before /root/b.

So how can I get this to work? I could use order instead of require and require_in, but that would mean I couldn't use require targeting any state that uses order, which could get quite messy and poorly-defined.

  • 1
    I think you may have gotten the wrong letters here; I want /root/c to execute before /root/b, and /root/b to execute before /root/c - you have b/c twice? – Alex Apr 19 '17 at 19:02
  • 1
    Good catch. My mind went numb preparing this question, thanks to a bunch of formatting headaches. Fixed. – Michael Mol Apr 19 '17 at 19:19
5

This turns out to be a known issue:

The require_in requisite does not support everything that require does, mainly id does not support sls or state_id without specifying a state module.

So by modifying our SLS file to include the state module (specifying file: /root/b as the require_in target instead of simply /root/b), we get the correct result.

I don't know if the other requisite injectors (watch_in, etc.) have the same limitations, so I will likely standardize my coding style on explicitly including module names in such identifiers.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.