From 2210f68c70013bc1982c8e4b284294e8aa1ff3a2 Mon Sep 17 00:00:00 2001 From: Ryan Standt <52174263+rstandt@users.noreply.github.com> Date: Thu, 31 Aug 2023 02:48:31 -0700 Subject: [PATCH] apply: allow use of -destroy flag for compatible terraform versions (#292) Implement the ApplyOption interface for the DestroyFlagOption struct which enables the user to run `terraform apply -destroy` as they would using the terraform binary directly by calling `func (tf *Terraform) Apply`. --- tfexec/apply.go | 14 ++++++++++++++ tfexec/apply_test.go | 2 ++ tfexec/internal/e2etest/apply_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/tfexec/apply.go b/tfexec/apply.go index 43c8bb6f..a13ff85d 100644 --- a/tfexec/apply.go +++ b/tfexec/apply.go @@ -13,6 +13,7 @@ import ( type applyConfig struct { backup string + destroy bool dirOrPlan string lock bool @@ -32,6 +33,7 @@ type applyConfig struct { } var defaultApplyOptions = applyConfig{ + destroy: false, lock: true, parallelism: 10, refresh: true, @@ -94,6 +96,10 @@ func (opt *ReattachOption) configureApply(conf *applyConfig) { conf.reattachInfo = opt.info } +func (opt *DestroyFlagOption) configureApply(conf *applyConfig) { + conf.destroy = opt.destroy +} + // Apply represents the terraform apply subcommand. func (tf *Terraform) Apply(ctx context.Context, opts ...ApplyOption) error { cmd, err := tf.applyCmd(ctx, opts...) @@ -191,6 +197,14 @@ func (tf *Terraform) buildApplyArgs(ctx context.Context, c applyConfig) ([]strin args = append(args, "-replace="+addr) } } + if c.destroy { + err := tf.compatible(ctx, tf0_15_2, nil) + if err != nil { + return nil, fmt.Errorf("-destroy option was introduced in Terraform 0.15.2: %w", err) + } + args = append(args, "-destroy") + } + if c.targets != nil { for _, ta := range c.targets { args = append(args, "-target="+ta) diff --git a/tfexec/apply_test.go b/tfexec/apply_test.go index 28e6b58f..c226a1f6 100644 --- a/tfexec/apply_test.go +++ b/tfexec/apply_test.go @@ -38,6 +38,7 @@ func TestApplyCmd(t *testing.T) { Target("target2"), Var("var1=foo"), Var("var2=bar"), + Destroy(true), DirOrPlan("testfile"), ) if err != nil { @@ -60,6 +61,7 @@ func TestApplyCmd(t *testing.T) { "-refresh=false", "-replace=aws_instance.test", "-replace=google_pubsub_topic.test", + "-destroy", "-target=target1", "-target=target2", "-var", "var1=foo", diff --git a/tfexec/internal/e2etest/apply_test.go b/tfexec/internal/e2etest/apply_test.go index d15d11a9..03785fc9 100644 --- a/tfexec/internal/e2etest/apply_test.go +++ b/tfexec/internal/e2etest/apply_test.go @@ -15,6 +15,10 @@ import ( "github.com/hashicorp/terraform-exec/tfexec/internal/testutil" ) +var ( + applyDestroyMinVersion = version.Must(version.NewVersion("0.15.2")) +) + func TestApply(t *testing.T) { runTest(t, "basic", func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) { err := tf.Init(context.Background()) @@ -62,3 +66,25 @@ func TestApplyJSON_TF015AndLater(t *testing.T) { } }) } + +func TestApplyDestroy(t *testing.T) { + runTest(t, "basic", func(t *testing.T, tfv *version.Version, tf *tfexec.Terraform) { + if tfv.LessThan(applyDestroyMinVersion) { + t.Skip("terraform apply -destroy was added in Terraform 0.15.2, so test is not valid") + } + err := tf.Init(context.Background()) + if err != nil { + t.Fatalf("error running Init in test directory: %s", err) + } + + err = tf.Apply(context.Background()) + if err != nil { + t.Fatalf("error running Apply: %s", err) + } + + err = tf.Apply(context.Background(), tfexec.Destroy(true)) + if err != nil { + t.Fatalf("error running Apply -destroy: %s", err) + } + }) +}