-
Notifications
You must be signed in to change notification settings - Fork 9.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement plan -out
with cloud integration
#33418
Changes from 7 commits
1e16a9e
11743d1
5c56ca9
eef35b9
f67a5da
aad14b4
fecb608
213064d
38858b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ import ( | |
version "github.com/hashicorp/go-version" | ||
|
||
"github.com/hashicorp/terraform/internal/backend" | ||
"github.com/hashicorp/terraform/internal/cloud/cloudplan" | ||
"github.com/hashicorp/terraform/internal/command/jsonformat" | ||
"github.com/hashicorp/terraform/internal/configs" | ||
"github.com/hashicorp/terraform/internal/genconfig" | ||
|
@@ -65,15 +66,6 @@ func (b *Cloud) opPlan(stopCtx, cancelCtx context.Context, op *backend.Operation | |
)) | ||
} | ||
|
||
if op.PlanOutPath != "" { | ||
diags = diags.Append(tfdiags.Sourceless( | ||
tfdiags.Error, | ||
"Saving a generated plan is currently not supported", | ||
`Terraform Cloud does not support saving the generated execution `+ | ||
`plan locally at this time.`, | ||
)) | ||
} | ||
|
||
if !op.HasConfig() && op.PlanMode != plans.DestroyMode { | ||
diags = diags.Append(tfdiags.Sourceless( | ||
tfdiags.Error, | ||
|
@@ -95,7 +87,25 @@ func (b *Cloud) opPlan(stopCtx, cancelCtx context.Context, op *backend.Operation | |
return nil, diags.Err() | ||
} | ||
|
||
return b.plan(stopCtx, cancelCtx, op, w) | ||
// If the run errored, exit before checking whether to save a plan file | ||
run, err := b.plan(stopCtx, cancelCtx, op, w) | ||
if err != nil { | ||
return run, err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we return an error, we should be make it clear that we are returning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, yeah, all right |
||
} | ||
|
||
// Maybe save plan file | ||
sebasslash marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if op.PlanOutPath != "" { | ||
bookmark := cloudplan.NewSavedPlanBookmark(run.ID, b.hostname) | ||
err = bookmark.Save(op.PlanOutPath) | ||
} | ||
|
||
// Only display next steps if everything succeeded | ||
if err == nil { | ||
// Cloud currently supports plan -out but not genconfig | ||
op.View.PlanNextStep(op.PlanOutPath, "") | ||
} | ||
sebasslash marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return run, err | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same suggestion here. I think we want to be clear about returning nil if we are also returning an error. |
||
} | ||
|
||
func (b *Cloud) plan(stopCtx, cancelCtx context.Context, op *backend.Operation, w *tfe.Workspace) (*tfe.Run, error) { | ||
|
@@ -107,9 +117,12 @@ func (b *Cloud) plan(stopCtx, cancelCtx context.Context, op *backend.Operation, | |
b.CLI.Output(b.Colorize().Color(strings.TrimSpace(header) + "\n")) | ||
} | ||
|
||
// Plan-only means they ran terraform plan without -out. | ||
planOnly := op.Type == backend.OperationTypePlan && op.PlanOutPath == "" | ||
|
||
configOptions := tfe.ConfigurationVersionCreateOptions{ | ||
AutoQueueRuns: tfe.Bool(false), | ||
Speculative: tfe.Bool(op.Type == backend.OperationTypePlan), | ||
Speculative: tfe.Bool(planOnly), | ||
} | ||
|
||
cv, err := b.client.ConfigurationVersions.Create(stopCtx, w.ID, configOptions) | ||
|
@@ -206,6 +219,7 @@ in order to capture the filesystem context the remote workspace expects: | |
Refresh: tfe.Bool(op.PlanRefresh), | ||
Workspace: w, | ||
AutoApply: tfe.Bool(op.AutoApprove), | ||
SavePlan: tfe.Bool(op.PlanOutPath != ""), | ||
} | ||
|
||
switch op.PlanMode { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love it when "currently" becomes the past 😆