Skip to content

Commit

Permalink
stackruntime: Handle apply-time-specified input variables
Browse files Browse the repository at this point in the history
When the topmost stack configuration declares an ephemeral input variable,
its values must be provided separately for each of the plan and apply
phases.

Therefore here we extend the API to allow specifying input variable values
during the apply phase, and add rules to check whether all of the
apply-time-required input variables have been specified and whether any
non-ephemeral variables are either unspecified or re-specified with equal
values during the apply phase.

This also extends the FindStackConfigurationComponents response to include
more metadata about the input variables and output values so that a caller
can know which ones are ephemeral. The name of that RPC function had
already become a little too specific with the inclusion of embedded stack
information and is even moreso now; we might choose to rename it to
something more generic like "AnalyzeStackConfiguration" in future, but
that'd be a breaking change and therefore requires more coordination.
  • Loading branch information
apparentlymart committed Jun 17, 2024
1 parent 79f78b2 commit e74896b
Show file tree
Hide file tree
Showing 17 changed files with 2,190 additions and 1,560 deletions.
24 changes: 21 additions & 3 deletions internal/rpcapi/stacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ func stackConfigMetaforProto(cfgNode *stackconfig.ConfigNode, stackAddr stackadd
Components: make(map[string]*terraform1.FindStackConfigurationComponents_Component),
EmbeddedStacks: make(map[string]*terraform1.FindStackConfigurationComponents_EmbeddedStack),
InputVariables: make(map[string]*terraform1.FindStackConfigurationComponents_InputVariable),
OutputValues: make(map[string]*terraform1.FindStackConfigurationComponents_OutputValue),
}

for name, cc := range cfgNode.Stack.Components {
Expand Down Expand Up @@ -197,10 +198,21 @@ func stackConfigMetaforProto(cfgNode *stackconfig.ConfigNode, stackAddr stackadd
ret.EmbeddedStacks[name] = sProto
}

for name, iv := range cfgNode.Stack.InputVariables {
ret.InputVariables[name] = &terraform1.FindStackConfigurationComponents_InputVariable{
Optional: !iv.DefaultValue.IsNull(),
for name, vc := range cfgNode.Stack.InputVariables {
vProto := &terraform1.FindStackConfigurationComponents_InputVariable{
Optional: !vc.DefaultValue.IsNull(),
Sensitive: vc.Sensitive,
Ephemeral: vc.Ephemeral,
}
ret.InputVariables[name] = vProto
}

for name, oc := range cfgNode.Stack.OutputValues {
oProto := &terraform1.FindStackConfigurationComponents_OutputValue{
Sensitive: oc.Sensitive,
Ephemeral: oc.Ephemeral,
}
ret.OutputValues[name] = oProto
}

return ret
Expand Down Expand Up @@ -430,6 +442,11 @@ func (s *stacksServer) ApplyStackChanges(req *terraform1.ApplyStackChanges_Reque
return status.Errorf(codes.InvalidArgument, "provider dependencies are inconsistent: %s", err)
}

inputValues, err := externalInputValuesFromProto(req.InputValues)
if err != nil {
return status.Errorf(codes.InvalidArgument, "invalid input values: %s", err)
}

// We'll hook some internal events in the planning process both to generate
// tracing information if we're in an OpenTelemetry-aware context and
// to propagate a subset of the events to our client.
Expand All @@ -440,6 +457,7 @@ func (s *stacksServer) ApplyStackChanges(req *terraform1.ApplyStackChanges_Reque
diagsCh := make(chan tfdiags.Diagnostic, 2)
rtReq := stackruntime.ApplyRequest{
Config: cfg,
InputValues: inputValues,
ProviderFactories: providerFactories,
RawPlan: req.PlannedChanges,
ExperimentsAllowed: s.experimentsAllowed,
Expand Down
15 changes: 9 additions & 6 deletions internal/rpcapi/stacks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,15 @@ func TestStacksFindStackConfigurationComponents(t *testing.T) {
},
},
InputVariables: map[string]*terraform1.FindStackConfigurationComponents_InputVariable{
"unused": {
Optional: false,
},
"unused_with_default": {
Optional: true,
},
"unused": {Optional: false},
"unused_with_default": {Optional: true},
"sensitive": {Sensitive: true},
"ephemeral": {Ephemeral: true},
},
OutputValues: map[string]*terraform1.FindStackConfigurationComponents_OutputValue{
"normal": {},
"sensitive": {Sensitive: true},
"ephemeral": {Ephemeral: true},
},
}
if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" {
Expand Down
Loading

0 comments on commit e74896b

Please sign in to comment.