Skip to content

Commit 884e1fb

Browse files
terraform: Plans can be "complete" and "applyable"
These ideas are both already implied by some logic elsewhere in the system, but until now we didn't have the decision logic centralized in a single place that could therefore evolve over time without necessarily always updating every caller together. We'll now have the modules runtime produce its own boolean ruling about each characteristic, which callers can rely on for the mechanical decision-making of whether to offer the user an "approve" prompt, and whether to remind the user after apply that it was an incomplete plan that will probably therefore need at least one more plan/apply round to converge. The "Applyable" flag directly replaces the previous method Plan.CanApply, with equivalent logic. Making this a field instead of a method means that we can freeze it as part of a saved plan, rather than recalculating it when we reload the plan, and we can export the field value in our export formats like JSON while ensuring it'll always be consistent with what Terraform is using internally. Callers can (and should) still use other context in the plan to return more tailored messages for specific situations they already know about that might be useful to users, but with these flags as a baseline callers can now just fall back to a generic presentation when encountering a situation they don't yet understand, rather than making the wrong decision and causing something strange to happen. That is: a lack of awareness of a new rule will now cause just a generic message in the UI, rather than incorrect behavior. This commit mostly just deals with populating the flags, and then all of the direct consequences of that on our various tests. Further changes to actually make use of these flags elsewhere in the system will follow in later commits, both in this repository and in other repositories.
1 parent c01b4a8 commit 884e1fb

File tree

52 files changed

+1434
-1033
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1434
-1033
lines changed

internal/backend/local/backend_apply.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func (b *Local) opApply(
106106
return
107107
}
108108

109-
trivialPlan := !plan.CanApply()
109+
trivialPlan := !plan.Applyable
110110
hasUI := op.UIOut != nil && op.UIIn != nil
111111
mustConfirm := hasUI && !op.AutoApprove && !trivialPlan
112112
op.View.Plan(plan, schemas)

internal/backend/local/backend_plan.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func (b *Local) opPlan(
131131
}
132132

133133
// Record whether this plan includes any side-effects that could be applied.
134-
runningOp.PlanEmpty = !plan.CanApply()
134+
runningOp.PlanEmpty = !plan.Applyable
135135

136136
// Save the plan to disk
137137
if path := op.PlanOutPath; path != "" {

internal/command/command_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,12 @@ func testPlan(t *testing.T) *plans.Plan {
197197
Config: backendConfigRaw,
198198
},
199199
Changes: plans.NewChanges(),
200+
201+
// We'll default to the fake plan being both applyable and complete,
202+
// since that's what most tests expect. Tests can override these
203+
// back to false again afterwards if they need to.
204+
Applyable: true,
205+
Complete: true,
200206
}
201207
}
202208

internal/command/jsonplan/plan.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ type plan struct {
6363
RelevantAttributes []ResourceAttr `json:"relevant_attributes,omitempty"`
6464
Checks json.RawMessage `json:"checks,omitempty"`
6565
Timestamp string `json:"timestamp,omitempty"`
66+
Applyable bool `json:"applyable"`
67+
Complete bool `json:"complete"`
6668
Errored bool `json:"errored"`
6769
}
6870

@@ -225,6 +227,8 @@ func Marshal(
225227
output := newPlan()
226228
output.TerraformVersion = version.String()
227229
output.Timestamp = p.Timestamp.Format(time.RFC3339)
230+
output.Applyable = p.Applyable
231+
output.Complete = p.Complete
228232
output.Errored = p.Errored
229233

230234
err := output.marshalPlanVariables(p.VariableValues, config.Module.Variables)

internal/command/show_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,8 @@ type plan struct {
12071207
OutputChanges map[string]interface{} `json:"output_changes,omitempty"`
12081208
PriorState priorState `json:"prior_state,omitempty"`
12091209
Config map[string]interface{} `json:"configuration,omitempty"`
1210+
Applyable bool `json:"applyable"`
1211+
Complete bool `json:"complete"`
12101212
Errored bool `json:"errored"`
12111213
}
12121214

internal/command/testdata/show-json-sensitive/output.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"format_version": "1.0",
3+
"applyable": true,
4+
"complete": true,
35
"variables": {
46
"test_var": {
57
"value": "bar"

internal/command/testdata/show-json/basic-create/output.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"format_version": "1.0",
3+
"applyable": true,
4+
"complete": true,
35
"variables": {
46
"test_var": {
57
"value": "bar"

internal/command/testdata/show-json/basic-delete/output.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"format_version": "1.0",
3+
"applyable": true,
4+
"complete": true,
35
"variables": {
46
"test_var": {
57
"value": "bar"

internal/command/testdata/show-json/basic-update/output.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"format_version": "1.0",
3+
"applyable": false,
4+
"complete": true,
35
"variables": {
46
"test_var": {
57
"value": "bar"

internal/command/testdata/show-json/conditions/output-refresh-only.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"format_version": "1.2",
33
"terraform_version": "1.8.0-dev",
4+
"applyable": false,
5+
"complete": true,
46
"variables": {
57
"ami": {
68
"value": "bad-ami"

0 commit comments

Comments
 (0)