Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ require (
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.32.9 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6 // indirect
github.com/aws/aws-sdk-go-v2/service/elasticache v1.56.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.15 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.16 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.35 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 // indirect
github.com/aws/aws-sdk-go-v2/service/neptune v1.48.4 // indirect
github.com/aws/aws-sdk-go-v2/service/rds v1.91.0 // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,16 @@ github.com/aws/aws-sdk-go-v2/service/iam v1.53.1 h1:xNCUk9XN6Pa9PyzbEfzgRpvEIVlq
github.com/aws/aws-sdk-go-v2/service/iam v1.53.1/go.mod h1:GNQZL4JRSGH6L0/SNGOtffaB1vmlToYp3KtcUIB0NhI=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.15 h1:JJLBQxwY+AFwuPAi5ivGc1ChnTdUt4cXMv7e76m2c/Y=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.15/go.mod h1:lQknBIe78MVL0cQOQDlag8KGflMbMEVFx9mB6O8ENvk=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 h1:DIBqIrJ7hv+e4CmIk2z3pyKT+3B6qVMgRsawHiR3qso=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7/go.mod h1:vLm00xmBke75UmpNvOcZQ/Q30ZFjbczeLFqGx5urmGo=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.16 h1:8g4OLy3zfNzLV20wXmZgx+QumI9WhWHnd4GCdvETxs4=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.16/go.mod h1:5a78jwLMs7BaesU0UIhLfVy2ZmOEgOy6ewYQXKTD37Q=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.35 h1:BBEElKh4a+rKshvjrfpajTe9CbpZvrbb4Jkg2PB7RzA=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.35/go.mod h1:zaZk983w//8beSruBVec/mr4CmDwgZitW/qzGhAAX0g=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 h1:NSbvS17MlI2lurYgXnCOLvCFX38sBW4eiVER7+kkgsU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16/go.mod h1:SwT8Tmqd4sA6G1qaGdzWCJN99bUmPGHfRwwq3G5Qb+A=
github.com/aws/aws-sdk-go-v2/service/kinesis v1.42.9 h1:9Dme/lCNr7GT+n3+AsJV95g5akEhSYeJKoQOcrL8xZ4=
Expand All @@ -90,6 +94,8 @@ github.com/aws/aws-sdk-go-v2/service/kms v1.49.4 h1:2gom8MohxN0SnhHZBYAC4S8jHG+E
github.com/aws/aws-sdk-go-v2/service/kms v1.49.4/go.mod h1:HO31s0qt0lso/ADvZQyzKs8js/ku0fMHsfyXW8OPVYc=
github.com/aws/aws-sdk-go-v2/service/lambda v1.87.0 h1:E5UXxF3vK3JuViwKCHfTJBIiFjvE4aytSucZjI2UAlQ=
github.com/aws/aws-sdk-go-v2/service/lambda v1.87.0/go.mod h1:6f64Y1BEf6e1uCI+LtGbcZSKDK1GvgJ+iI4vP/bbE8s=
github.com/aws/aws-sdk-go-v2/service/neptune v1.48.4 h1:OKqe8wmRV8/b0PgfEm2xBKUdxO81uVNF2TOvLny5mVE=
github.com/aws/aws-sdk-go-v2/service/neptune v1.48.4/go.mod h1:QpgA5y9y/SywZTBw8ylR5gDS4Uc2qlVYbudXmzr/VSw=
github.com/aws/aws-sdk-go-v2/service/rds v1.91.0 h1:eqHz3Uih+gb0vLE5Cc4Xf733vOxsxDp6GFUUVQU4d7w=
github.com/aws/aws-sdk-go-v2/service/rds v1.91.0/go.mod h1:h2jc7IleH3xHY7y+h8FH7WAZcz3IVLOB6/jXotIQ/qU=
github.com/aws/aws-sdk-go-v2/service/route53 v1.46.2 h1:wmt05tPp/CaRZpPV5B4SaJ5TwkHKom07/BzHoLdkY1o=
Expand Down
4 changes: 4 additions & 0 deletions integ/aws/storage/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ elasticache.serverless-cache: ## Test ElastiCache ServerlessCache L2 (live Valke
go test -v -count 1 -timeout 30m ./... -run ^TestElasticacheServerlessCache$
.PHONY: elasticache.serverless-cache

neptune.cluster: ## Test Neptune DatabaseCluster L2 (live serverless cluster + instance)
go test -v -count 1 -timeout 45m ./... -run ^TestNeptuneCluster$
.PHONY: neptune.cluster

bucket-notifications: ## Test S3 Bucket with EventBridge Notifications
go test -v -count 1 -timeout 15m ./... -run ^TestBucketNotifications$
.PHONY: bucket-notifications
66 changes: 66 additions & 0 deletions integ/aws/storage/apps/neptune.cluster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Live test for the storage.neptune DatabaseCluster L2 (alpha port): a real
// Neptune SERVERLESS cluster (db.serverless instance) deployed through the
// ported construct in an isolated VPC. Validates the aws_neptune_cluster /
// aws_neptune_cluster_instance mapping, the native serverless_v2 scaling
// block, and grid-scoped naming against live AWS.
import { App, LocalBackend, TerraformOutput } from "cdktn";
import { aws } from "../../../../src";

const environmentName = process.env.ENVIRONMENT_NAME ?? "test";
const region = process.env.AWS_REGION ?? "us-east-1";
const outdir = process.env.OUT_DIR ?? "cdktf.out";
const stackName = process.env.STACK_NAME ?? "neptune.cluster";

const app = new App({
outdir,
});

const stack = new aws.AwsStack(app, stackName, {
gridUUID: "gbbbbbbbb-bbbb",
environmentName,
providerConfig: {
region,
},
});
new LocalBackend(stack, {
path: `${stackName}.tfstate`,
});

const vpc = new aws.compute.Vpc(stack, "Vpc", {
maxAzs: 2,
natGateways: 0,
subnetConfiguration: [
{
name: "isolated",
subnetType: aws.compute.SubnetType.PRIVATE_ISOLATED,
cidrMask: 24,
},
],
});

const cluster = new aws.storage.neptune.DatabaseCluster(stack, "Cluster", {
vpc,
vpcSubnets: { subnetType: aws.compute.SubnetType.PRIVATE_ISOLATED },
instanceType: aws.storage.neptune.InstanceType.SERVERLESS,
serverlessScalingConfiguration: {
minCapacity: 1,
maxCapacity: 2.5,
},
// Terraform-native replacement for upstream removalPolicy: allow clean destroy.
skipFinalSnapshot: true,
});

new TerraformOutput(stack, "cluster_identifier", {
value: cluster.clusterIdentifier,
staticId: true,
});
new TerraformOutput(stack, "cluster_endpoint_address", {
value: cluster.clusterEndpoint.hostname,
staticId: true,
});
new TerraformOutput(stack, "cluster_resource_identifier", {
value: cluster.clusterResourceIdentifier,
staticId: true,
});

app.synth();
71 changes: 71 additions & 0 deletions integ/aws/storage/neptune_cluster_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package test

import (
"context"
"testing"

"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/neptune"
"github.com/gruntwork-io/terratest/modules/terraform"
test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
"github.com/stretchr/testify/require"
)

// Run the apps/neptune.cluster.ts integration test: a real Neptune SERVERLESS
// cluster + db.serverless instance through the storage.neptune alpha port.
// Validates cluster read-back incl. the serverless v2 scaling configuration,
// grid-scoped naming, and the post-apply drift oracle.
func TestNeptuneCluster(t *testing.T) {
runStorageIntegrationTest(t, "neptune.cluster", "us-east-1", validateNeptuneCluster)
}

func validateNeptuneCluster(t *testing.T, tfWorkingDir string, awsRegion string) {
terraformOptions := test_structure.LoadTerraformOptions(t, tfWorkingDir)
outputs := terraform.OutputAll(t, terraformOptions)

clusterID := outputs["cluster_identifier"].(string)
endpointAddress := outputs["cluster_endpoint_address"].(string)
resourceID := outputs["cluster_resource_identifier"].(string)

ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(awsRegion))
require.NoError(t, err)
client := neptune.NewFromConfig(cfg)

// --- 1. Cluster read-back incl. serverless scaling. ---
dc, err := client.DescribeDBClusters(ctx, &neptune.DescribeDBClustersInput{
DBClusterIdentifier: &clusterID,
})
require.NoError(t, err)
require.Len(t, dc.DBClusters, 1)
c := dc.DBClusters[0]
require.Equal(t, "available", *c.Status)
require.Equal(t, "neptune", *c.Engine)
require.Equal(t, endpointAddress, *c.Endpoint)
require.Equal(t, resourceID, *c.DbClusterResourceId)
require.True(t, *c.StorageEncrypted, "storage encryption defaults to true")
require.NotNil(t, c.ServerlessV2ScalingConfiguration,
"serverless scaling configuration must reach AWS")
require.Equal(t, float64(1), *c.ServerlessV2ScalingConfiguration.MinCapacity)
require.Equal(t, 2.5, *c.ServerlessV2ScalingConfiguration.MaxCapacity)
t.Logf("neptune-cluster: %s available (neptune %s, serverless %.1f-%.1f NCU, encrypted)",
clusterID, *c.EngineVersion, *c.ServerlessV2ScalingConfiguration.MinCapacity, *c.ServerlessV2ScalingConfiguration.MaxCapacity)

// --- 2. The single instance is db.serverless with a grid-derived name. ---
require.Len(t, c.DBClusterMembers, 1)
instanceID := *c.DBClusterMembers[0].DBInstanceIdentifier
di, err := client.DescribeDBInstances(ctx, &neptune.DescribeDBInstancesInput{
DBInstanceIdentifier: &instanceID,
})
require.NoError(t, err)
require.Len(t, di.DBInstances, 1)
require.Equal(t, "db.serverless", *di.DBInstances[0].DBInstanceClass)
require.Equal(t, clusterID+"instance1", instanceID,
"instance identifier must derive from the grid-scoped cluster identifier")
t.Logf("neptune-cluster: instance %s is db.serverless", instanceID)

// --- Drift oracle: re-planning the already-applied stack must show zero changes. ---
planExitCode := terraform.PlanExitCode(t, terraformOptions)
require.Equal(t, terraform.DefaultSuccessExitCode, planExitCode,
"expected `tofu plan -detailed-exitcode` to report no drift after apply (got exit code %d)", planExitCode)
}
3 changes: 3 additions & 0 deletions src/aws/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ export * as docdb from "./docdb";

// aws-elasticache-alpha
export * as elasticache from "./elasticache";

// aws-neptune-alpha
export * as neptune from "./neptune";
Loading
Loading