Skip to content

Commit e61f108

Browse files
backend/remote: Support -target on plan and apply
Previously we did not allow -target to be used with the remote backend because there was no way to send the targets to Terraform Cloud/Enterprise via the API. There is now an attribute in the request for creating a plan that allows us to send target addresses, so we'll remove that restriction and copy the given target addresses into the API request.
1 parent 8d19739 commit e61f108

File tree

5 files changed

+42
-30
lines changed

5 files changed

+42
-30
lines changed

backend/remote/backend_apply.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,6 @@ func (b *Remote) opApply(stopCtx, cancelCtx context.Context, op *backend.Operati
6767
))
6868
}
6969

70-
if op.Targets != nil {
71-
diags = diags.Append(tfdiags.Sourceless(
72-
tfdiags.Error,
73-
"Resource targeting is currently not supported",
74-
`The "remote" backend does not support resource targeting at this time.`,
75-
))
76-
}
77-
7870
if b.hasExplicitVariableValues(op) {
7971
diags = diags.Append(tfdiags.Sourceless(
8072
tfdiags.Error,

backend/remote/backend_apply_test.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010
"time"
1111

12+
"github.com/google/go-cmp/cmp"
1213
tfe "github.com/hashicorp/go-tfe"
1314
"github.com/hashicorp/terraform/addrs"
1415
"github.com/hashicorp/terraform/backend"
@@ -278,16 +279,23 @@ func TestRemote_applyWithTarget(t *testing.T) {
278279
}
279280

280281
<-run.Done()
281-
if run.Result == backend.OperationSuccess {
282-
t.Fatal("expected apply operation to fail")
282+
if run.Result != backend.OperationSuccess {
283+
t.Fatal("expected apply operation to succeed")
283284
}
284-
if !run.PlanEmpty {
285-
t.Fatalf("expected plan to be empty")
285+
if run.PlanEmpty {
286+
t.Fatalf("expected plan to be non-empty")
286287
}
287288

288-
errOutput := b.CLI.(*cli.MockUi).ErrorWriter.String()
289-
if !strings.Contains(errOutput, "targeting is currently not supported") {
290-
t.Fatalf("expected a targeting error, got: %v", errOutput)
289+
// We should find a run inside the mock client that has the same
290+
// target address we requested above.
291+
runsAPI := b.client.Runs.(*mockRuns)
292+
if got, want := len(runsAPI.runs), 1; got != want {
293+
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
294+
}
295+
for _, run := range runsAPI.runs {
296+
if diff := cmp.Diff([]string{"null_resource.foo"}, run.TargetAddrs); diff != "" {
297+
t.Errorf("wrong TargetAddrs in the created run\n%s", diff)
298+
}
291299
}
292300
}
293301

backend/remote/backend_mock.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,7 @@ func (m *mockRuns) Create(ctx context.Context, options tfe.RunCreateOptions) (*t
757757
Permissions: &tfe.RunPermissions{},
758758
Plan: p,
759759
Status: tfe.RunPending,
760+
TargetAddrs: options.TargetAddrs,
760761
}
761762

762763
if pc != nil {

backend/remote/backend_plan.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,6 @@ func (b *Remote) opPlan(stopCtx, cancelCtx context.Context, op *backend.Operatio
7070
))
7171
}
7272

73-
if op.Targets != nil {
74-
diags = diags.Append(tfdiags.Sourceless(
75-
tfdiags.Error,
76-
"Resource targeting is currently not supported",
77-
`The "remote" backend does not support resource targeting at this time.`,
78-
))
79-
}
80-
8173
if b.hasExplicitVariableValues(op) {
8274
diags = diags.Append(tfdiags.Sourceless(
8375
tfdiags.Error,
@@ -224,6 +216,17 @@ in order to capture the filesystem context the remote workspace expects:
224216
Workspace: w,
225217
}
226218

219+
if len(op.Targets) != 0 {
220+
runOptions.TargetAddrs = make([]string, 0, len(op.Targets))
221+
for _, addr := range op.Targets {
222+
// The API client wants the normal string representation of a
223+
// target address, which will ultimately get inserted into a
224+
// -target option when Terraform CLI is launched in the
225+
// Cloud/Enterprise execution environment.
226+
runOptions.TargetAddrs = append(runOptions.TargetAddrs, addr.String())
227+
}
228+
}
229+
227230
r, err := b.client.Runs.Create(stopCtx, runOptions)
228231
if err != nil {
229232
return r, generalError("Failed to create run", err)

backend/remote/backend_plan_test.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010
"time"
1111

12+
"github.com/google/go-cmp/cmp"
1213
tfe "github.com/hashicorp/go-tfe"
1314
"github.com/hashicorp/terraform/addrs"
1415
"github.com/hashicorp/terraform/backend"
@@ -283,16 +284,23 @@ func TestRemote_planWithTarget(t *testing.T) {
283284
}
284285

285286
<-run.Done()
286-
if run.Result == backend.OperationSuccess {
287-
t.Fatal("expected plan operation to fail")
287+
if run.Result != backend.OperationSuccess {
288+
t.Fatal("expected plan operation to succeed")
288289
}
289-
if !run.PlanEmpty {
290-
t.Fatalf("expected plan to be empty")
290+
if run.PlanEmpty {
291+
t.Fatalf("expected plan to be non-empty")
291292
}
292293

293-
errOutput := b.CLI.(*cli.MockUi).ErrorWriter.String()
294-
if !strings.Contains(errOutput, "targeting is currently not supported") {
295-
t.Fatalf("expected a targeting error, got: %v", errOutput)
294+
// We should find a run inside the mock client that has the same
295+
// target address we requested above.
296+
runsAPI := b.client.Runs.(*mockRuns)
297+
if got, want := len(runsAPI.runs), 1; got != want {
298+
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
299+
}
300+
for _, run := range runsAPI.runs {
301+
if diff := cmp.Diff([]string{"null_resource.foo"}, run.TargetAddrs); diff != "" {
302+
t.Errorf("wrong TargetAddrs in the created run\n%s", diff)
303+
}
296304
}
297305
}
298306

0 commit comments

Comments
 (0)