-
Notifications
You must be signed in to change notification settings - Fork 786
Description
Assume a template such as:
{{ $a := file "fileA.json" | parseJSON }}
{{ $b := file "fileB.json" | parseJSON }}
{{ if $a.enabled }}
{{ if $b.foo | regexMatch "test*" }}
{{ end }}
{{ end }}
w/ fileA.json containing { "enabled": true }
and fileB.json containing { "foo": "test" }
When repeatedly run with consul-template -once ...
, this will non-deterministically succeed or fail:
- Over thousands of runs it appears to succeed ~83% of the time on my machine.
- If the two file-loading lines are reversed, the success rate drops to 36%.
My guess is that there are two things happening:
regexMatch
(and other functions) do not support nil inputs. This is clearly reproduced w/ e.g.{{ if ("{}" | parseJSON).foo | regexMatch "test*" }}{{ end }}
. This failure does NOT occur witheq
or other operators that tolerate nil inputs.- Even in Once mode, multiple rendering passes are occurring. That is, is isn't waiting for both fileA and fileB to load. The failures occur when a rendering pass occurs where fileA was loaded but fileB was not yet loaded.
I do see the following note at https://github.com/hashicorp/consul-template/blob/main/docs/templating-language.md#parsejson:
Note: Consul Template evaluates the template multiple times, and on the first evaluation the value of the key will be empty (because no data has been loaded yet). This means that templates must guard against empty responses.
That would explain the behavior here... but at https://github.com/hashicorp/consul-template/blob/main/docs/modes.md#once-mode it also says:
In Once mode, Consul Template will wait for all dependencies to be rendered.
...although perhaps a file isn't a dependency for this context.
In any case, this behavior feels extremely surprising at least for Once mode and IMO if not a bug still probably deserves a bit more than a small comment in parseJSON.
Possible suggestions:
- Change
regexMatch
and other functions to tolerance nil inputs. - Make file-loading behavior deterministic in once mode.
- If existing behavior is correct, consider further describing the behavior in
parseJSON
and also functions that may be impacted by it.