From 8151744faef98844c9897c2c4669936c732899b5 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 31 Mar 2017 17:33:09 -0700 Subject: [PATCH] core: Input walk shouldn't clobber dynamic provider config During the input walk we stash the values resulting from user input (if any) in the eval context for use when later walks need to resolve the provider config. However, this repository of input results is only able to represent literal values, since it does not retain the record of which of the keys have values that are "computed". Previously we were blindly stashing all of the results, failing to consider that some of them might be computed. That resulted in the UnknownValue placeholder being misinterpreted as a literal value when the data is used later, which ultimately resulted in it clobbering the actual expression evaluation result and thus causing the provider to fail to configure itself. Now we are careful to only retain in this repository the keys whose values are known statically during the input phase. This eventually gets merged with the dynamic evaluation results on subsequent walks, with the dynamic keys left untouched due to their absence from the stored input map. This fixes #11264. --- terraform/eval_provider.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/terraform/eval_provider.go b/terraform/eval_provider.go index 61efcc2352b3..572d1a4b30d4 100644 --- a/terraform/eval_provider.go +++ b/terraform/eval_provider.go @@ -136,7 +136,22 @@ func (n *EvalInputProvider) Eval(ctx EvalContext) (interface{}, error) { // Set the input that we received so that child modules don't attempt // to ask for input again. if config != nil && len(config.Config) > 0 { - ctx.SetProviderInput(n.Name, config.Config) + // This repository of provider input results on the context doesn't + // retain config.ComputedKeys, so we need to filter those out here + // in order that later users of this data won't try to use the unknown + // value placeholder as if it were a literal value. This map is just + // of known values we've been able to complete so far; dynamic stuff + // will be merged in by EvalBuildProviderConfig on subsequent + // (post-input) walks. + confMap := config.Config + if config.ComputedKeys != nil { + for _, key := range config.ComputedKeys { + delete(confMap, key) + } + } + + + ctx.SetProviderInput(n.Name, confMap) } else { ctx.SetProviderInput(n.Name, map[string]interface{}{}) }