Skip to content

Commit d918483

Browse files
Enable Destroy (#112)
This pull request adds the capability to destroy resources.
1 parent d8fcf6a commit d918483

File tree

7 files changed

+146
-3
lines changed

7 files changed

+146
-3
lines changed

pkg/modprovider/server.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ func (s *server) Delete(
311311
) (*emptypb.Empty, error) {
312312
switch {
313313
case req.GetType() == string(moduleStateTypeToken(s.packageName)):
314-
return s.moduleStateHandler.Delete(ctx, req)
314+
return s.moduleStateHandler.Delete(ctx, req, s.params.TFModuleSource, s.params.TFModuleVersion)
315315
case isChildResourceType(req.GetType()):
316316
return s.childHandler.Delete(ctx, req)
317317
default:

pkg/modprovider/state.go

+38-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go"
3232

3333
"github.com/pulumi/pulumi-terraform-module/pkg/property"
34+
"github.com/pulumi/pulumi-terraform-module/pkg/tfsandbox"
3435
)
3536

3637
const (
@@ -201,9 +202,44 @@ func (h *moduleStateHandler) Update(
201202

202203
// Delete does not do anything. This could be reused to trigger deletion support in the future
203204
func (h *moduleStateHandler) Delete(
204-
_ context.Context,
205-
_ *pulumirpc.DeleteRequest,
205+
ctx context.Context,
206+
req *pulumirpc.DeleteRequest,
207+
moduleSource TFModuleSource,
208+
moduleVersion TFModuleVersion,
206209
) (*emptypb.Empty, error) {
210+
oldState := moduleState{}
211+
oldState.Unmarshal(req.GetProperties())
212+
213+
tf, err := tfsandbox.NewTofu(ctx)
214+
if err != nil {
215+
return nil, fmt.Errorf("Sandbox construction failed: %w", err)
216+
}
217+
218+
// For Destroy, Terraform needs the module source and version as specified in the json file, but it doesn't
219+
// need the exact name of the moduleComponent resource.
220+
// TODO: https://github.com/pulumi/pulumi-terraform-module/issues/118
221+
tfName := "platypus"
222+
err = tfsandbox.CreateTFFile(tfName, moduleSource, moduleVersion, tf.WorkingDir(), resource.PropertyMap{})
223+
if err != nil {
224+
return nil, fmt.Errorf("Seed file generation failed: %w", err)
225+
}
226+
227+
err = tf.Init(ctx)
228+
if err != nil {
229+
return nil, fmt.Errorf("Init failed: %w", err)
230+
}
231+
232+
err = tf.PushState(ctx, oldState.rawState)
233+
if err != nil {
234+
return nil, fmt.Errorf("PushState failed: %w", err)
235+
}
236+
237+
err = tf.Destroy(ctx)
238+
if err != nil {
239+
return nil, fmt.Errorf("Delete failed: %w", err)
240+
}
241+
242+
// Send back empty pb if no error.
207243
return &emptypb.Empty{}, nil
208244
}
209245

schema-terraform-module-provider.json

+1
Large diffs are not rendered by default.

tests/acc_test.go

+77
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"context"
66
"encoding/json"
77
"fmt"
8+
"math/rand"
89
"os"
910
"os/exec"
1011
"path/filepath"
12+
"strconv"
1113
"strings"
1214
"testing"
1315

@@ -305,6 +307,72 @@ func TestAwsLambdaModuleIntegration(t *testing.T) {
305307
})
306308
}
307309

310+
// TODO: Ensure Delete truly deletes from the cloud https://github.com/pulumi/pulumi-terraform-module/issues/119
311+
312+
func TestIntegration(t *testing.T) {
313+
314+
type testCase struct {
315+
name string // Must be same as project folder in testdata/programs/ts
316+
moduleName string
317+
moduleVersion string
318+
moduleNamespace string
319+
previewExpect map[apitype.OpType]int
320+
upExpect map[string]int
321+
deleteExpect map[string]int
322+
}
323+
324+
testcases := []testCase{
325+
{
326+
name: "s3bucketmod",
327+
moduleName: "terraform-aws-modules/s3-bucket/aws",
328+
moduleVersion: "4.5.0",
329+
moduleNamespace: "bucket",
330+
previewExpect: map[apitype.OpType]int{
331+
apitype.OpType("create"): 5,
332+
},
333+
upExpect: map[string]int{
334+
"create": 8,
335+
},
336+
deleteExpect: map[string]int{
337+
"delete": 8,
338+
},
339+
},
340+
}
341+
342+
for _, tc := range testcases {
343+
tc := tc
344+
localProviderBinPath := ensureCompiledProvider(t)
345+
skipLocalRunsWithoutCreds(t)
346+
t.Run(tc.name, func(t *testing.T) {
347+
testProgram := filepath.Join("testdata", "programs", "ts", tc.name)
348+
localPath := opttest.LocalProviderPath("terraform-module", filepath.Dir(localProviderBinPath))
349+
integrationTest := pulumitest.NewPulumiTest(t, testProgram, localPath)
350+
351+
prefix := generateTestResourcePrefix()
352+
353+
// Get a prefix for resource names
354+
integrationTest.SetConfig(t, "prefix", prefix)
355+
356+
// Generate package
357+
pulumiPackageAdd(t, integrationTest, localProviderBinPath, tc.moduleName, tc.moduleVersion, tc.moduleNamespace)
358+
359+
// Preview
360+
previewResult := integrationTest.Preview(t)
361+
autogold.Expect(tc.previewExpect).Equal(t, previewResult.ChangeSummary)
362+
363+
// Up
364+
upResult := integrationTest.Up(t)
365+
autogold.Expect(&tc.upExpect).Equal(t, upResult.Summary.ResourceChanges)
366+
367+
// Delete
368+
destroyResult := integrationTest.Destroy(t)
369+
autogold.Expect(&tc.deleteExpect).Equal(t, destroyResult.Summary.ResourceChanges)
370+
371+
})
372+
}
373+
374+
}
375+
308376
func getRoot(t *testing.T) string {
309377
wd, err := os.Getwd()
310378
require.NoError(t, err)
@@ -405,3 +473,12 @@ func pulumiPackageAdd(
405473
require.NoError(t, err)
406474
require.Equal(t, 0, exitCode)
407475
}
476+
477+
//nolint:gosec
478+
func generateTestResourcePrefix() string {
479+
low := 100000
480+
high := 999999
481+
482+
num := low + rand.Intn(high-low)
483+
return strconv.Itoa(num)
484+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: ts-s3bucketmod-program
2+
runtime:
3+
name: nodejs
4+
options:
5+
packagemanager: npm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as pulumi from "@pulumi/pulumi";
2+
import * as bucket from "@pulumi/bucket";
3+
4+
5+
const config = new pulumi.Config();
6+
const prefix = config.get('prefix') ?? pulumi.getStack();
7+
8+
const testbucket = new bucket.Module("test-bucket", {
9+
bucket: `${prefix}-test-bucket`,
10+
})
11+
12+
export const bucketARN = testbucket.s3_bucket_arn
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "ts-s3bucketmod-program",
3+
"main": "index.ts",
4+
"devDependencies": {
5+
"@types/node": "^18",
6+
"typescript": "^5.0.0"
7+
},
8+
"dependencies": {
9+
"@pulumi/aws": "^6.0.0",
10+
"@pulumi/pulumi": "^3.113.0"
11+
}
12+
}

0 commit comments

Comments
 (0)