@@ -17,7 +17,6 @@ import (
17
17
"github.com/hashicorp/terraform/internal/instances"
18
18
"github.com/hashicorp/terraform/internal/lang/marks"
19
19
"github.com/hashicorp/terraform/internal/plans"
20
- "github.com/hashicorp/terraform/internal/plans/objchange"
21
20
"github.com/hashicorp/terraform/internal/promising"
22
21
"github.com/hashicorp/terraform/internal/providers"
23
22
"github.com/hashicorp/terraform/internal/stacks/stackaddrs"
@@ -91,7 +90,20 @@ func (c *ComponentInstance) CheckInputVariableValues(ctx context.Context, phase
91
90
92
91
// We actually checked the errors statically already, so we only care about
93
92
// the value here.
94
- return EvalComponentInputVariables (ctx , varDecls , wantTy , defs , decl , phase , c )
93
+ val , diags := EvalComponentInputVariables (ctx , varDecls , wantTy , defs , decl , phase , c )
94
+ if phase == ApplyPhase {
95
+ if ! val .IsWhollyKnown () {
96
+ // We can't apply a configuration that has unknown values in it.
97
+ // This means an error has occured somewhere else, while gathering
98
+ // the input variables. We return a nil value here, whatever caused
99
+ // the error should have raised an error diagnostic separately.
100
+ return cty .NilVal , diags
101
+ }
102
+
103
+ // Note, that unknown values during the planning phase are totally fine.
104
+ }
105
+
106
+ return val , diags
95
107
}
96
108
97
109
// inputValuesForModulesRuntime adapts the result of
@@ -104,17 +116,12 @@ func (c *ComponentInstance) CheckInputVariableValues(ctx context.Context, phase
104
116
//
105
117
// During the planning phase, the expectedValues should be nil, as they will
106
118
// only be checked during the apply phase.
107
- func (c * ComponentInstance ) inputValuesForModulesRuntime (ctx context.Context , previousValues map [string ]plans.DynamicValue , phase EvalPhase ) (terraform.InputValues , tfdiags.Diagnostics ) {
108
- var diags tfdiags.Diagnostics
109
-
119
+ func (c * ComponentInstance ) inputValuesForModulesRuntime (ctx context.Context , phase EvalPhase ) terraform.InputValues {
110
120
valsObj := c .InputVariableValues (ctx , phase )
111
121
if valsObj == cty .NilVal {
112
- return nil , diags
122
+ return nil
113
123
}
114
124
115
- // module is the configuration for the root module of this component.
116
- module := c .call .Config (ctx ).ModuleTree (ctx ).Module
117
-
118
125
// valsObj might be an unknown value during the planning phase, in which
119
126
// case we'll return an InputValues with all of the expected variables
120
127
// defined as unknown values of their expected type constraints. To
@@ -124,7 +131,7 @@ func (c *ComponentInstance) inputValuesForModulesRuntime(ctx context.Context, pr
124
131
if wantTy == cty .NilType {
125
132
// The configuration is too invalid for us to know what type we're
126
133
// expecting, so we'll just bail.
127
- return nil , diags
134
+ return nil
128
135
}
129
136
wantAttrs := wantTy .AttributeTypes ()
130
137
ret := make (terraform.InputValues , len (wantAttrs ))
@@ -139,71 +146,8 @@ func (c *ComponentInstance) inputValuesForModulesRuntime(ctx context.Context, pr
139
146
Value : v ,
140
147
SourceType : terraform .ValueFromCaller ,
141
148
}
142
-
143
- // While we're here, we'll just add a diagnostic if the value has
144
- // somehow changed between the planning and apply phases. All of these
145
- // diagnostics acknowledge that the root cause here is a bug in
146
- // Terraform.
147
- if phase == ApplyPhase {
148
- config := module .Variables [name ]
149
- if config .Ephemeral {
150
- // Ephemeral variables are allowed to change between the plan
151
- // and apply stages, so we won't bother checking them.
152
- continue
153
- }
154
-
155
- raw , ok := previousValues [name ]
156
- if ! ok {
157
- // This shouldn't happen because we should have a value for
158
- // every input variable that we have a value for in the plan.
159
- diags = diags .Append (& hcl.Diagnostic {
160
- Severity : hcl .DiagError ,
161
- Summary : "Missing input variable value" ,
162
- Detail : fmt .Sprintf (
163
- "The input variable %q is required but was not set in the plan for %s. This is a bug in Terraform - please report it." ,
164
- name , c .Addr (),
165
- ),
166
- Subject : c .call .Declaration (ctx ).DeclRange .ToHCL ().Ptr (),
167
- })
168
- continue
169
- }
170
-
171
- plannedValue , err := raw .Decode (cty .DynamicPseudoType )
172
- if err != nil {
173
- // Then something has gone wrong when decoding the value.
174
- diags = diags .Append (& hcl.Diagnostic {
175
- Severity : hcl .DiagError ,
176
- Summary : "Invalid planned input variable value" ,
177
- Detail : fmt .Sprintf ("Failed to decode the planned value for input variable %q: %s. This is a bug in Terraform - please report it." , name , err ),
178
- Subject : c .call .Declaration (ctx ).DeclRange .ToHCL ().Ptr (),
179
- })
180
- continue
181
- }
182
-
183
- // We're unmarking the value here so that we can compare it to the
184
- // planned value. We're only checking for equality from here on out,
185
- // so we don't need to worry about the marks.
186
- applyValue , _ := v .UnmarkDeep ()
187
-
188
- if errs := objchange .AssertValueCompatible (plannedValue , applyValue ); len (errs ) > 0 {
189
- // Then the value has changed between the planning and apply
190
- // phases. This is a bug in Terraform. We don't want to expose
191
- // the actual values here as they could contain sensitive
192
- // information. This should be a rare error message, so we
193
- // don't need to be too verbose.
194
- diags = diags .Append (& hcl.Diagnostic {
195
- Severity : hcl .DiagError ,
196
- Summary : "Planned input variable value changed" ,
197
- Detail : fmt .Sprintf (
198
- "The planned value for input variable %q has changed between the planning and apply phases for %s. This is a bug in Terraform - please report it." ,
199
- name , c .Addr (),
200
- ),
201
- Subject : c .call .Declaration (ctx ).DeclRange .ToHCL ().Ptr (),
202
- })
203
- }
204
- }
205
149
}
206
- return ret , diags
150
+ return ret
207
151
}
208
152
209
153
// Providers evaluates the "providers" argument from the component
@@ -615,8 +559,7 @@ func (c *ComponentInstance) CheckModuleTreePlan(ctx context.Context) (*plans.Pla
615
559
}
616
560
617
561
stackPlanOpts := c .main .PlanningOpts ()
618
- inputValues , inputValueDiags := c .inputValuesForModulesRuntime (ctx , nil , PlanPhase )
619
- diags = diags .Append (inputValueDiags )
562
+ inputValues := c .inputValuesForModulesRuntime (ctx , PlanPhase )
620
563
if inputValues == nil || diags .HasErrors () {
621
564
return nil , diags
622
565
}
@@ -868,9 +811,8 @@ func (c *ComponentInstance) ApplyModuleTreePlan(ctx context.Context, plan *plans
868
811
// shallow-copy it. This is NOT a deep copy, so don't modify anything
869
812
// that's reachable through any pointers without copying those first too.
870
813
modifiedPlan := * plan
871
- inputValues , inputValueDiags := c .inputValuesForModulesRuntime (ctx , plan .VariableValues , ApplyPhase )
872
- diags = diags .Append (inputValueDiags )
873
- if inputValues == nil || inputValueDiags .HasErrors () {
814
+ inputValues := c .inputValuesForModulesRuntime (ctx , ApplyPhase )
815
+ if inputValues == nil {
874
816
// inputValuesForModulesRuntime uses nil (as opposed to a
875
817
// non-nil zerolen map) to represent that the definition of
876
818
// the input variables was so invalid that we cannot do
0 commit comments