diff --git a/tests/database/default-db.test.ts b/tests/database/default-db.test.ts index eaac25f..4e3a4e0 100644 --- a/tests/database/default-db.test.ts +++ b/tests/database/default-db.test.ts @@ -18,7 +18,7 @@ export function testDefaultDb(ctx: DatabaseTestContext) { assert.ok(database, 'Database should be defined'); assert.strictEqual( database.name, - `${ctx.config.appName}-default`, + `${ctx.config.appName}-default-db`, 'Database should have correct name', ); diff --git a/tests/database/index.test.ts b/tests/database/index.test.ts index f86fd7d..8339910 100644 --- a/tests/database/index.test.ts +++ b/tests/database/index.test.ts @@ -11,6 +11,7 @@ import { RDSClient } from '@aws-sdk/client-rds'; import { requireEnv } from '../util'; import { testCustomDb } from './custom-db.test'; import { testDefaultDb } from './default-db.test'; +import { testSnapshotDb } from './snapshot-db.test'; const programArgs: InlineProgramArgs = { stackName: 'dev', @@ -39,5 +40,6 @@ describe('Database component deployment', () => { describe('Default database', () => testDefaultDb(ctx)); describe('Custom database', () => testCustomDb(ctx)); + describe('Snapshot database', () => testSnapshotDb(ctx)); after(() => cleanupSnapshots(ctx)); }); diff --git a/tests/database/infrastructure/index.ts b/tests/database/infrastructure/index.ts index ada577b..85d15bb 100644 --- a/tests/database/infrastructure/index.ts +++ b/tests/database/infrastructure/index.ts @@ -5,7 +5,7 @@ import * as config from './config'; const vpc = new studion.Vpc(`${config.appName}-vpc`, {}); -const defaultDb = new DatabaseBuilder(`${config.appName}-default`) +const defaultDb = new DatabaseBuilder(`${config.appName}-default-db`) .withInstance({ dbName: config.dbName, }) @@ -15,7 +15,7 @@ const defaultDb = new DatabaseBuilder(`${config.appName}-default`) .withVpc(vpc.vpc) .build(); -const kms = new aws.kms.Key(`${config.appName}-kms`, { +const kms = new aws.kms.Key(`${config.appName}-kms-key`, { description: `${config.appName} RDS encryption key`, customerMasterKeySpec: 'SYMMETRIC_DEFAULT', isEnabled: true, @@ -33,7 +33,7 @@ const paramGroup = new aws.rds.ParameterGroup( }, ); -const customDb = new DatabaseBuilder(`${config.appName}-custom`) +const customDb = new DatabaseBuilder(`${config.appName}-custom-db`) .withInstance({ dbName: config.dbName, applyImmediately: config.applyImmediately, @@ -55,4 +55,27 @@ const customDb = new DatabaseBuilder(`${config.appName}-custom`) .withTags(config.tags) .build(); -export { vpc, defaultDb, kms, paramGroup, customDb }; +const snapshot = defaultDb.instance.dbInstanceIdentifier.apply( + dbInstanceIdentifier => { + if (!dbInstanceIdentifier) return; + return new aws.rds.Snapshot(`${config.appName}-snapshot`, { + dbInstanceIdentifier: dbInstanceIdentifier, + dbSnapshotIdentifier: `${config.appName}-snapshot-id`, + tags: config.tags, + }); + }, +); + +const snapshotDb = snapshot.apply(snapshot => { + if (!snapshot) return; + return new DatabaseBuilder(`${config.appName}-snapshot-db`) + .withInstance({ + applyImmediately: true, + }) + .withVpc(vpc.vpc) + .withTags(config.tags) + .withSnapshot(snapshot.id) + .build(); +}); + +export { vpc, defaultDb, kms, paramGroup, customDb, snapshot, snapshotDb }; diff --git a/tests/database/snapshot-db.test.ts b/tests/database/snapshot-db.test.ts new file mode 100644 index 0000000..cb2695e --- /dev/null +++ b/tests/database/snapshot-db.test.ts @@ -0,0 +1,41 @@ +import * as assert from 'node:assert'; +import { DatabaseTestContext } from './test-context'; +import { it } from 'node:test'; + +export function testSnapshotDb(ctx: DatabaseTestContext) { + it('should create and properly configure encrypted snapshot copy', () => { + const snapshotDb = ctx.outputs.snapshotDb.value; + const snapshot = ctx.outputs.snapshot.value; + + assert.ok( + snapshotDb.encryptedSnapshotCopy, + 'Encrtyped snapshot copy should exist', + ); + + assert.strictEqual( + snapshotDb.encryptedSnapshotCopy.sourceDbSnapshotIdentifier, + snapshot.dbSnapshotArn, + 'Encrtyped snapshot copy should have correct source db snapshot identifier', + ); + assert.strictEqual( + snapshotDb.encryptedSnapshotCopy.targetDbSnapshotIdentifier, + `${snapshot.id}-encrypted-copy`, + 'Encrtyped snapshot copy should have the correct target db snapshot identifier', + ); + assert.strictEqual( + snapshotDb.encryptedSnapshotCopy.kmsKeyId, + snapshotDb.kmsKeyId, + 'Encrtyped snapshot copy should have the correct ksm key id', + ); + }); + + it('should properly configure instance', () => { + const snapshotDb = ctx.outputs.snapshotDb.value; + + assert.strictEqual( + snapshotDb.instance.dbSnapshotIdentifier, + snapshotDb.encryptedSnapshotCopy.targetDbSnapshotIdentifier, + 'Db snapshot identifier should be set correctly', + ); + }); +} diff --git a/tests/database/utils/cleanup-snapshots.ts b/tests/database/utils/cleanup-snapshots.ts index c43d036..e895270 100644 --- a/tests/database/utils/cleanup-snapshots.ts +++ b/tests/database/utils/cleanup-snapshots.ts @@ -8,7 +8,11 @@ import { DatabaseTestContext } from '../test-context'; export async function cleanupSnapshots(ctx: DatabaseTestContext) { const spinner = createSpinner('Deleting snapshots...').start(); - const dbs = [ctx.outputs.defaultDb.value, ctx.outputs.customDb.value]; + const dbs = [ + ctx.outputs.defaultDb.value, + ctx.outputs.customDb.value, + ctx.outputs.snapshotDb.value, + ]; await Promise.all( dbs.map(db => deleteSnapshot(ctx, db.instance.dbInstanceIdentifier)), );