Skip to content

Commit b8eacdf

Browse files
committed
fix: Allow remote state to be used with Terraform (#1242)
The Terraform Provisioner depended on the statefile content being at a specific path, which disallowed the use of external state providers. This fixes it!
1 parent 7ebc468 commit b8eacdf

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

provisioner/terraform/provision.go

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,6 @@ func (t *terraform) Provision(stream proto.DRPCProvisioner_ProvisionStream) erro
5353
}
5454
}()
5555
start := request.GetStart()
56-
statefilePath := filepath.Join(start.Directory, "terraform.tfstate")
57-
if len(start.State) > 0 {
58-
err := os.WriteFile(statefilePath, start.State, 0600)
59-
if err != nil {
60-
return xerrors.Errorf("write statefile %q: %w", statefilePath, err)
61-
}
62-
}
6356

6457
terraform, err := tfexec.NewTerraform(start.Directory, t.binaryPath)
6558
if err != nil {
@@ -246,14 +239,18 @@ func (t *terraform) Provision(stream proto.DRPCProvisioner_ProvisionStream) erro
246239
errorMessage := err.Error()
247240
// Terraform can fail and apply and still need to store it's state.
248241
// In this case, we return Complete with an explicit error message.
249-
statefileContent, err := os.ReadFile(statefilePath)
242+
state, err := terraform.Show(stream.Context())
243+
if err != nil {
244+
return xerrors.Errorf("show state: %w", err)
245+
}
246+
stateData, err := json.Marshal(state)
250247
if err != nil {
251-
return xerrors.Errorf("read file %q: %w", statefilePath, err)
248+
return xerrors.Errorf("marshal state: %w", err)
252249
}
253250
return stream.Send(&proto.Provision_Response{
254251
Type: &proto.Provision_Response_Complete{
255252
Complete: &proto.Provision_Complete{
256-
State: statefileContent,
253+
State: stateData,
257254
Error: errorMessage,
258255
},
259256
},
@@ -266,7 +263,7 @@ func (t *terraform) Provision(stream proto.DRPCProvisioner_ProvisionStream) erro
266263
if start.DryRun {
267264
resp, err = parseTerraformPlan(stream.Context(), terraform, planfilePath)
268265
} else {
269-
resp, err = parseTerraformApply(stream.Context(), terraform, statefilePath)
266+
resp, err = parseTerraformApply(stream.Context(), terraform)
270267
}
271268
if err != nil {
272269
return err
@@ -366,14 +363,10 @@ func parseTerraformPlan(ctx context.Context, terraform *tfexec.Terraform, planfi
366363
}, nil
367364
}
368365

369-
func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform, statefilePath string) (*proto.Provision_Response, error) {
370-
statefileContent, err := os.ReadFile(statefilePath)
366+
func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform) (*proto.Provision_Response, error) {
367+
state, err := terraform.Show(ctx)
371368
if err != nil {
372-
return nil, xerrors.Errorf("read file %q: %w", statefilePath, err)
373-
}
374-
state, err := terraform.ShowStateFile(ctx, statefilePath)
375-
if err != nil {
376-
return nil, xerrors.Errorf("show state file %q: %w", statefilePath, err)
369+
return nil, xerrors.Errorf("show state file: %w", err)
377370
}
378371
resources := make([]*proto.Resource, 0)
379372
if state.Values != nil {
@@ -508,6 +501,11 @@ func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform, state
508501
}
509502
}
510503

504+
statefileContent, err := json.Marshal(state)
505+
if err != nil {
506+
return nil, xerrors.Errorf("marshal state: %w", err)
507+
}
508+
511509
return &proto.Provision_Response{
512510
Type: &proto.Provision_Response_Complete{
513511
Complete: &proto.Provision_Complete{

provisioner/terraform/provision_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,13 @@ provider "coder" {
9191
"main.tf": `variable "A" {
9292
}`,
9393
},
94-
Error: true,
94+
Response: &proto.Provision_Response{
95+
Type: &proto.Provision_Response_Complete{
96+
Complete: &proto.Provision_Complete{
97+
Error: "exit status 1",
98+
},
99+
},
100+
},
95101
}, {
96102
Name: "single-resource",
97103
Files: map[string]string{
@@ -499,6 +505,8 @@ provider "coder" {
499505
resourcesWant, err := json.Marshal(testCase.Response.GetComplete().Resources)
500506
require.NoError(t, err)
501507

508+
require.Equal(t, testCase.Response.GetComplete().Error, msg.GetComplete().Error)
509+
502510
require.Equal(t, string(resourcesWant), string(resourcesGot))
503511
break
504512
}

0 commit comments

Comments
 (0)