diff --git a/backend/remote/backend_plan.go b/backend/remote/backend_plan.go index 200f7fd8d..9e73587ac 100644 --- a/backend/remote/backend_plan.go +++ b/backend/remote/backend_plan.go @@ -138,11 +138,18 @@ func (b *Remote) plan(stopCtx, cancelCtx context.Context, op *backend.Operation, var configDir string if op.ConfigDir != "" { + // De-normalize the configuration directory path. + configDir, err = filepath.Abs(op.ConfigDir) + if err != nil { + return nil, generalError( + "Failed to get absolute path of the configuration directory: %v", err) + } + // Make sure to take the working directory into account by removing // the working directory from the current path. This will result in // a path that points to the expected root of the workspace. configDir = filepath.Clean(strings.TrimSuffix( - filepath.Clean(op.ConfigDir), + filepath.Clean(configDir), filepath.Clean(w.WorkingDirectory), )) } else { diff --git a/backend/remote/backend_plan_test.go b/backend/remote/backend_plan_test.go index fb6359993..f3ae3bb83 100644 --- a/backend/remote/backend_plan_test.go +++ b/backend/remote/backend_plan_test.go @@ -622,7 +622,7 @@ func TestRemote_planWithWorkingDirectory(t *testing.T) { WorkingDirectory: tfe.String("terraform"), } - // Configure the workspace to use a custom working direcrtory. + // Configure the workspace to use a custom working directory. _, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspace, options) if err != nil { t.Fatalf("error configuring working directory: %v", err) @@ -655,6 +655,61 @@ func TestRemote_planWithWorkingDirectory(t *testing.T) { } } +func TestRemote_planWithWorkingDirectoryFromCurrentPath(t *testing.T) { + b, bCleanup := testBackendDefault(t) + defer bCleanup() + + options := tfe.WorkspaceUpdateOptions{ + WorkingDirectory: tfe.String("terraform"), + } + + // Configure the workspace to use a custom working directory. + _, err := b.client.Workspaces.Update(context.Background(), b.organization, b.workspace, options) + if err != nil { + t.Fatalf("error configuring working directory: %v", err) + } + + wd, err := os.Getwd() + if err != nil { + t.Fatalf("error getting current working directory: %v", err) + } + + // We need to change into the configuration directory to make sure + // the logic to upload the correct slug is working as expected. + if err := os.Chdir("./testdata/plan-with-working-directory/terraform"); err != nil { + t.Fatalf("error changing directory: %v", err) + } + defer os.Chdir(wd) // Make sure we change back again when were done. + + // For this test we need to give our current directory instead of the + // full path to the configuration as we already changed directories. + op, configCleanup := testOperationPlan(t, ".") + defer configCleanup() + + op.Workspace = backend.DefaultStateName + + run, err := b.Operation(context.Background(), op) + if err != nil { + t.Fatalf("error starting operation: %v", err) + } + + <-run.Done() + if run.Result != backend.OperationSuccess { + t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String()) + } + if run.PlanEmpty { + t.Fatalf("expected a non-empty plan") + } + + output := b.CLI.(*cli.MockUi).OutputWriter.String() + if !strings.Contains(output, "Running plan in the remote backend") { + t.Fatalf("expected remote backend header in output: %s", output) + } + if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") { + t.Fatalf("expected plan summery in output: %s", output) + } +} + func TestRemote_planPolicyPass(t *testing.T) { b, bCleanup := testBackendDefault(t) defer bCleanup()