From aacc2291b31aaad17428f49af96d527329c795c2 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 2 Dec 2025 15:54:30 +0100 Subject: [PATCH 01/30] Create db v2 component # Conflicts: # src/v2/components/database/index.ts --- src/v2/components/database/index.ts | 193 +++++++++++++++------------- 1 file changed, 107 insertions(+), 86 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 695d12a..24802c3 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -6,44 +6,34 @@ import { Password } from '../../../components/password'; import { commonTags } from '../../../constants'; export namespace Database { - export type Instance = { + export type Args = { dbName?: pulumi.Input; - engineVersion?: pulumi.Input; + username?: pulumi.Input; + password?: pulumi.Input; + vpc: pulumi.Input; multiAz?: pulumi.Input; + applyImmediately?: pulumi.Input; + allocatedStorage?: pulumi.Input; + maxAllocatedStorage?: pulumi.Input; instanceClass?: pulumi.Input; allowMajorVersionUpgrade?: pulumi.Input; autoMinorVersionUpgrade?: pulumi.Input; - }; - - export type Credentials = { - username?: pulumi.Input; - password?: pulumi.Input; - }; - - export type Storage = { - allocatedStorage?: pulumi.Input; - maxAllocatedStorage?: pulumi.Input; kmsKeyId?: pulumi.Input; + parameterGroupName?: pulumi.Input; + customParameterGroupArgs?: pulumi.Input; + snapshotIdentifier?: pulumi.Input; + enableMonitoring?: pulumi.Input; + engineVersion?: pulumi.Input; + tags?: pulumi.Input<{ + [key: string]: pulumi.Input; + }>; }; - - export type Args = Instance & - Credentials & - Storage & { - vpc: pulumi.Input; - enableMonitoring?: pulumi.Input; - applyImmediately?: pulumi.Input; - snapshotIdentifier?: pulumi.Input; - parameterGroupName?: pulumi.Input; - tags?: pulumi.Input<{ - [key: string]: pulumi.Input; - }>; - }; } const defaults = { multiAz: false, applyImmediately: false, - allocatedStorage: 20, + allocatedStorage: '20', maxAllocatedStorage: 100, instanceClass: 'db.t4g.micro', enableMonitoring: false, @@ -55,13 +45,13 @@ const defaults = { export class Database extends pulumi.ComponentResource { name: string; instance: awsNative.rds.DbInstance; - vpc: pulumi.Output; dbSubnetGroup: aws.rds.SubnetGroup; dbSecurityGroup: aws.ec2.SecurityGroup; password: Password; - kmsKeyId: pulumi.Output; - monitoringRole?: aws.iam.Role; encryptedSnapshotCopy?: aws.rds.SnapshotCopy; + monitoringRole?: aws.iam.Role; + kmsKeyId: pulumi.Input; + parameterGroupName?: pulumi.Input; constructor( name: string, @@ -73,12 +63,20 @@ export class Database extends pulumi.ComponentResource { this.name = name; const argsWithDefaults = Object.assign({}, defaults, args); - const { vpc, kmsKeyId, enableMonitoring, snapshotIdentifier } = - argsWithDefaults; + const { + kmsKeyId, + snapshotIdentifier, + enableMonitoring, + parameterGroupName, + customParameterGroupArgs, + } = argsWithDefaults; - this.vpc = pulumi.output(vpc); - this.dbSubnetGroup = this.createSubnetGroup(); - this.dbSecurityGroup = this.createSecurityGroup(); + const vpc = pulumi.output(argsWithDefaults.vpc); + this.dbSubnetGroup = this.createSubnetGroup(vpc.isolatedSubnetIds); + this.dbSecurityGroup = this.createSecurityGroup( + vpc.vpcId, + vpc.vpc.cidrBlock, + ); this.password = new Password( `${this.name}-database-password`, @@ -86,9 +84,11 @@ export class Database extends pulumi.ComponentResource { { parent: this }, ); - this.kmsKeyId = kmsKeyId - ? pulumi.output(kmsKeyId) - : this.createEncryptionKey().arn; + this.kmsKeyId = kmsKeyId || this.createEncryptionKey().arn; + + this.parameterGroupName = customParameterGroupArgs + ? this.createParameterGroup(customParameterGroupArgs).name + : parameterGroupName; if (enableMonitoring) { this.monitoringRole = this.createMonitoringRole(); @@ -99,43 +99,50 @@ export class Database extends pulumi.ComponentResource { this.createEncryptedSnapshotCopy(snapshotIdentifier); } - this.instance = this.createDatabaseInstance(argsWithDefaults); + this.instance = this.createDatabaseInstance(args); this.registerOutputs(); } - private createSubnetGroup() { - return new aws.rds.SubnetGroup( + private createSubnetGroup( + isolatedSubnetIds: awsx.ec2.Vpc['isolatedSubnetIds'], + ) { + const dbSubnetGroup = new aws.rds.SubnetGroup( `${this.name}-subnet-group`, { - subnetIds: this.vpc.isolatedSubnetIds, + subnetIds: isolatedSubnetIds, tags: commonTags, }, { parent: this }, ); + return dbSubnetGroup; } - private createSecurityGroup() { - return new aws.ec2.SecurityGroup( + private createSecurityGroup( + vpcId: awsx.ec2.Vpc['vpcId'], + vpcCidrBlock: pulumi.Input, + ) { + const dbSecurityGroup = new aws.ec2.SecurityGroup( `${this.name}-security-group`, { - vpcId: this.vpc.vpcId, + vpcId, ingress: [ { protocol: 'tcp', fromPort: 5432, toPort: 5432, - cidrBlocks: [this.vpc.vpc.cidrBlock], + cidrBlocks: [vpcCidrBlock], }, ], tags: commonTags, }, { parent: this }, ); + return dbSecurityGroup; } private createEncryptionKey() { - return new aws.kms.Key( + const kms = new aws.kms.Key( `${this.name}-rds-key`, { description: `${this.name} RDS encryption key`, @@ -148,27 +155,24 @@ export class Database extends pulumi.ComponentResource { }, { parent: this }, ); + return kms; } private createMonitoringRole() { - const monitoringRole = new aws.iam.Role( - `${this.name}-rds-monitoring`, - { - assumeRolePolicy: { - Version: '2012-10-17', - Statement: [ - { - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: 'monitoring.rds.amazonaws.com', - }, + const monitoringRole = new aws.iam.Role(`${this.name}-rds-monitoring`, { + assumeRolePolicy: { + Version: '2012-10-17', + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'monitoring.rds.amazonaws.com', }, - ], - }, + }, + ], }, - { parent: this }, - ); + }); new aws.iam.RolePolicyAttachment( `${this.name}-rds-monitoring-role-attachment`, @@ -177,14 +181,13 @@ export class Database extends pulumi.ComponentResource { policyArn: 'arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole', }, - { parent: this }, ); return monitoringRole; } private createEncryptedSnapshotCopy( - snapshotIdentifier: Database.Args['snapshotIdentifier'], + snapshotIdentifier: pulumi.Input, ) { const sourceDbSnapshotIdentifier = pulumi .output(snapshotIdentifier) @@ -192,22 +195,42 @@ export class Database extends pulumi.ComponentResource { aws.rds.getSnapshot({ dbSnapshotIdentifier: snapshotIdentifier, }), - ).dbSnapshotArn; + ) + .apply(snapshot => snapshot.dbSnapshotArn); - return new aws.rds.SnapshotCopy( + const encryptedSnapshotCopy = new aws.rds.SnapshotCopy( `${this.name}-encrypted-snapshot-copy`, { sourceDbSnapshotIdentifier, - targetDbSnapshotIdentifier: pulumi.interpolate`${snapshotIdentifier}-encrypted-copy`, + targetDbSnapshotIdentifier: `${snapshotIdentifier}-encrypted-copy`, kmsKeyId: this.kmsKeyId, }, { parent: this }, ); + return encryptedSnapshotCopy; + } + + private createParameterGroup( + customParameterGroupArgs: pulumi.Input, + ) { + const parameterGroup = pulumi + .output(customParameterGroupArgs) + .apply(args => { + return new aws.rds.ParameterGroup( + `${this.name}-parameter-group`, + args, + { parent: this }, + ); + }); + + return parameterGroup; } private createDatabaseInstance(args: Database.Args) { + const argsWithDefaults = Object.assign({}, defaults, args); + const monitoringOptions = - args.enableMonitoring && this.monitoringRole + argsWithDefaults.enableMonitoring && this.monitoringRole ? { monitoringInterval: 60, monitoringRoleArn: this.monitoringRole.arn, @@ -221,19 +244,19 @@ export class Database extends pulumi.ComponentResource { { dbInstanceIdentifier: `${this.name}-db-instance`, engine: 'postgres', - engineVersion: args.engineVersion, - dbInstanceClass: args.instanceClass, - dbName: args.dbName, - masterUsername: args.username, + engineVersion: argsWithDefaults.engineVersion, + dbInstanceClass: argsWithDefaults.instanceClass, + dbName: argsWithDefaults.dbName, + masterUsername: argsWithDefaults.username, masterUserPassword: this.password.value, dbSubnetGroupName: this.dbSubnetGroup.name, vpcSecurityGroups: [this.dbSecurityGroup.id], - allocatedStorage: args.allocatedStorage?.toString(), - maxAllocatedStorage: args.maxAllocatedStorage, - multiAz: args.multiAz, - applyImmediately: args.applyImmediately, - allowMajorVersionUpgrade: args.allowMajorVersionUpgrade, - autoMinorVersionUpgrade: args.autoMinorVersionUpgrade, + allocatedStorage: argsWithDefaults.allocatedStorage, + maxAllocatedStorage: argsWithDefaults.maxAllocatedStorage, + multiAz: argsWithDefaults.multiAz, + applyImmediately: argsWithDefaults.applyImmediately, + allowMajorVersionUpgrade: argsWithDefaults.allowMajorVersionUpgrade, + autoMinorVersionUpgrade: argsWithDefaults.autoMinorVersionUpgrade, kmsKeyId: this.kmsKeyId, storageEncrypted: true, publiclyAccessible: false, @@ -241,17 +264,15 @@ export class Database extends pulumi.ComponentResource { preferredBackupWindow: '06:00-06:30', backupRetentionPeriod: 14, caCertificateIdentifier: 'rds-ca-rsa2048-g1', - dbParameterGroupName: args.parameterGroupName, + dbParameterGroupName: this.parameterGroupName, dbSnapshotIdentifier: this.encryptedSnapshotCopy?.targetDbSnapshotIdentifier, ...monitoringOptions, - tags: pulumi - .output(args.tags) - .apply(tags => [ - ...Object.entries({ ...commonTags, ...tags }).map( - ([key, value]) => ({ key, value }), - ), - ]), + tags: [ + ...Object.entries({ ...commonTags, ...argsWithDefaults.tags }).map( + ([key, value]) => ({ key, value }), + ), + ], }, { parent: this, dependsOn: [this.password] }, ); From ccdc0daa8e5980adb83fb545862b0b0ff2ac783a Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 10:31:48 +0100 Subject: [PATCH 02/30] Remove ability to create custom parameter group --- src/v2/components/database/index.ts | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 24802c3..8e037af 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -20,7 +20,6 @@ export namespace Database { autoMinorVersionUpgrade?: pulumi.Input; kmsKeyId?: pulumi.Input; parameterGroupName?: pulumi.Input; - customParameterGroupArgs?: pulumi.Input; snapshotIdentifier?: pulumi.Input; enableMonitoring?: pulumi.Input; engineVersion?: pulumi.Input; @@ -51,7 +50,6 @@ export class Database extends pulumi.ComponentResource { encryptedSnapshotCopy?: aws.rds.SnapshotCopy; monitoringRole?: aws.iam.Role; kmsKeyId: pulumi.Input; - parameterGroupName?: pulumi.Input; constructor( name: string, @@ -67,8 +65,6 @@ export class Database extends pulumi.ComponentResource { kmsKeyId, snapshotIdentifier, enableMonitoring, - parameterGroupName, - customParameterGroupArgs, } = argsWithDefaults; const vpc = pulumi.output(argsWithDefaults.vpc); @@ -86,10 +82,6 @@ export class Database extends pulumi.ComponentResource { this.kmsKeyId = kmsKeyId || this.createEncryptionKey().arn; - this.parameterGroupName = customParameterGroupArgs - ? this.createParameterGroup(customParameterGroupArgs).name - : parameterGroupName; - if (enableMonitoring) { this.monitoringRole = this.createMonitoringRole(); } @@ -210,22 +202,6 @@ export class Database extends pulumi.ComponentResource { return encryptedSnapshotCopy; } - private createParameterGroup( - customParameterGroupArgs: pulumi.Input, - ) { - const parameterGroup = pulumi - .output(customParameterGroupArgs) - .apply(args => { - return new aws.rds.ParameterGroup( - `${this.name}-parameter-group`, - args, - { parent: this }, - ); - }); - - return parameterGroup; - } - private createDatabaseInstance(args: Database.Args) { const argsWithDefaults = Object.assign({}, defaults, args); @@ -264,7 +240,7 @@ export class Database extends pulumi.ComponentResource { preferredBackupWindow: '06:00-06:30', backupRetentionPeriod: 14, caCertificateIdentifier: 'rds-ca-rsa2048-g1', - dbParameterGroupName: this.parameterGroupName, + dbParameterGroupName: argsWithDefaults.parameterGroupName, dbSnapshotIdentifier: this.encryptedSnapshotCopy?.targetDbSnapshotIdentifier, ...monitoringOptions, From 08829e095c37d02194e3cfc592beccb3fff5574e Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 10:34:46 +0100 Subject: [PATCH 03/30] Cleanup --- src/v2/components/database/index.ts | 30 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 8e037af..297227d 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -91,7 +91,7 @@ export class Database extends pulumi.ComponentResource { this.createEncryptedSnapshotCopy(snapshotIdentifier); } - this.instance = this.createDatabaseInstance(args); + this.instance = this.createDatabaseInstance(argsWithDefaults); this.registerOutputs(); } @@ -203,10 +203,8 @@ export class Database extends pulumi.ComponentResource { } private createDatabaseInstance(args: Database.Args) { - const argsWithDefaults = Object.assign({}, defaults, args); - const monitoringOptions = - argsWithDefaults.enableMonitoring && this.monitoringRole + args.enableMonitoring && this.monitoringRole ? { monitoringInterval: 60, monitoringRoleArn: this.monitoringRole.arn, @@ -220,19 +218,19 @@ export class Database extends pulumi.ComponentResource { { dbInstanceIdentifier: `${this.name}-db-instance`, engine: 'postgres', - engineVersion: argsWithDefaults.engineVersion, - dbInstanceClass: argsWithDefaults.instanceClass, - dbName: argsWithDefaults.dbName, - masterUsername: argsWithDefaults.username, + engineVersion: args.engineVersion, + dbInstanceClass: args.instanceClass, + dbName: args.dbName, + masterUsername: args.username, masterUserPassword: this.password.value, dbSubnetGroupName: this.dbSubnetGroup.name, vpcSecurityGroups: [this.dbSecurityGroup.id], - allocatedStorage: argsWithDefaults.allocatedStorage, - maxAllocatedStorage: argsWithDefaults.maxAllocatedStorage, - multiAz: argsWithDefaults.multiAz, - applyImmediately: argsWithDefaults.applyImmediately, - allowMajorVersionUpgrade: argsWithDefaults.allowMajorVersionUpgrade, - autoMinorVersionUpgrade: argsWithDefaults.autoMinorVersionUpgrade, + allocatedStorage: args.allocatedStorage, + maxAllocatedStorage: args.maxAllocatedStorage, + multiAz: args.multiAz, + applyImmediately: args.applyImmediately, + allowMajorVersionUpgrade: args.allowMajorVersionUpgrade, + autoMinorVersionUpgrade: args.autoMinorVersionUpgrade, kmsKeyId: this.kmsKeyId, storageEncrypted: true, publiclyAccessible: false, @@ -240,12 +238,12 @@ export class Database extends pulumi.ComponentResource { preferredBackupWindow: '06:00-06:30', backupRetentionPeriod: 14, caCertificateIdentifier: 'rds-ca-rsa2048-g1', - dbParameterGroupName: argsWithDefaults.parameterGroupName, + dbParameterGroupName: args.parameterGroupName, dbSnapshotIdentifier: this.encryptedSnapshotCopy?.targetDbSnapshotIdentifier, ...monitoringOptions, tags: [ - ...Object.entries({ ...commonTags, ...argsWithDefaults.tags }).map( + ...Object.entries({ ...commonTags, ...args.tags }).map( ([key, value]) => ({ key, value }), ), ], From 003dbc22d640e990a652987ec3e94ac1300c8fb3 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 10:36:28 +0100 Subject: [PATCH 04/30] Fix kms key id type --- src/v2/components/database/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 297227d..689be95 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -49,7 +49,7 @@ export class Database extends pulumi.ComponentResource { password: Password; encryptedSnapshotCopy?: aws.rds.SnapshotCopy; monitoringRole?: aws.iam.Role; - kmsKeyId: pulumi.Input; + kmsKeyId: pulumi.Output; constructor( name: string, @@ -80,7 +80,9 @@ export class Database extends pulumi.ComponentResource { { parent: this }, ); - this.kmsKeyId = kmsKeyId || this.createEncryptionKey().arn; + this.kmsKeyId = kmsKeyId + ? pulumi.output(kmsKeyId) + : this.createEncryptionKey().arn; if (enableMonitoring) { this.monitoringRole = this.createMonitoringRole(); From ceb3a781dc46557b0093bb0d626f6f31f846b8ab Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:16:19 +0100 Subject: [PATCH 05/30] Cleanup --- src/v2/components/database/index.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 689be95..4f53246 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -101,7 +101,7 @@ export class Database extends pulumi.ComponentResource { private createSubnetGroup( isolatedSubnetIds: awsx.ec2.Vpc['isolatedSubnetIds'], ) { - const dbSubnetGroup = new aws.rds.SubnetGroup( + return new aws.rds.SubnetGroup( `${this.name}-subnet-group`, { subnetIds: isolatedSubnetIds, @@ -109,14 +109,13 @@ export class Database extends pulumi.ComponentResource { }, { parent: this }, ); - return dbSubnetGroup; } private createSecurityGroup( vpcId: awsx.ec2.Vpc['vpcId'], vpcCidrBlock: pulumi.Input, ) { - const dbSecurityGroup = new aws.ec2.SecurityGroup( + return new aws.ec2.SecurityGroup( `${this.name}-security-group`, { vpcId, @@ -132,11 +131,10 @@ export class Database extends pulumi.ComponentResource { }, { parent: this }, ); - return dbSecurityGroup; } private createEncryptionKey() { - const kms = new aws.kms.Key( + return new aws.kms.Key( `${this.name}-rds-key`, { description: `${this.name} RDS encryption key`, @@ -149,7 +147,6 @@ export class Database extends pulumi.ComponentResource { }, { parent: this }, ); - return kms; } private createMonitoringRole() { @@ -166,7 +163,9 @@ export class Database extends pulumi.ComponentResource { }, ], }, - }); + }, + { parent: this }, + ); new aws.iam.RolePolicyAttachment( `${this.name}-rds-monitoring-role-attachment`, @@ -175,6 +174,7 @@ export class Database extends pulumi.ComponentResource { policyArn: 'arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole', }, + { parent: this }, ); return monitoringRole; @@ -189,8 +189,7 @@ export class Database extends pulumi.ComponentResource { aws.rds.getSnapshot({ dbSnapshotIdentifier: snapshotIdentifier, }), - ) - .apply(snapshot => snapshot.dbSnapshotArn); + ).dbSnapshotArn; const encryptedSnapshotCopy = new aws.rds.SnapshotCopy( `${this.name}-encrypted-snapshot-copy`, From 7cbd0b6cd3f6df5bb6b7abe7e15ea14095f0d8e1 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:23:04 +0100 Subject: [PATCH 06/30] Cleanup vpc parameters --- src/v2/components/database/index.ts | 32 ++++++++++++----------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 4f53246..e121cd5 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -44,12 +44,13 @@ const defaults = { export class Database extends pulumi.ComponentResource { name: string; instance: awsNative.rds.DbInstance; + vpc: pulumi.Output; dbSubnetGroup: aws.rds.SubnetGroup; dbSecurityGroup: aws.ec2.SecurityGroup; password: Password; - encryptedSnapshotCopy?: aws.rds.SnapshotCopy; - monitoringRole?: aws.iam.Role; kmsKeyId: pulumi.Output; + monitoringRole?: aws.iam.Role; + encryptedSnapshotCopy?: aws.rds.SnapshotCopy; constructor( name: string, @@ -62,17 +63,15 @@ export class Database extends pulumi.ComponentResource { const argsWithDefaults = Object.assign({}, defaults, args); const { + vpc, kmsKeyId, - snapshotIdentifier, enableMonitoring, + snapshotIdentifier, } = argsWithDefaults; - const vpc = pulumi.output(argsWithDefaults.vpc); - this.dbSubnetGroup = this.createSubnetGroup(vpc.isolatedSubnetIds); - this.dbSecurityGroup = this.createSecurityGroup( - vpc.vpcId, - vpc.vpc.cidrBlock, - ); + this.vpc = pulumi.output(vpc); + this.dbSubnetGroup = this.createSubnetGroup(); + this.dbSecurityGroup = this.createSecurityGroup(); this.password = new Password( `${this.name}-database-password`, @@ -98,33 +97,28 @@ export class Database extends pulumi.ComponentResource { this.registerOutputs(); } - private createSubnetGroup( - isolatedSubnetIds: awsx.ec2.Vpc['isolatedSubnetIds'], - ) { + private createSubnetGroup() { return new aws.rds.SubnetGroup( `${this.name}-subnet-group`, { - subnetIds: isolatedSubnetIds, + subnetIds: this.vpc.isolatedSubnetIds, tags: commonTags, }, { parent: this }, ); } - private createSecurityGroup( - vpcId: awsx.ec2.Vpc['vpcId'], - vpcCidrBlock: pulumi.Input, - ) { + private createSecurityGroup() { return new aws.ec2.SecurityGroup( `${this.name}-security-group`, { - vpcId, + vpcId: this.vpc.vpcId, ingress: [ { protocol: 'tcp', fromPort: 5432, toPort: 5432, - cidrBlocks: [vpcCidrBlock], + cidrBlocks: [this.vpc.vpc.cidrBlock], }, ], tags: commonTags, From 96e1045634093ca496e2545e8ac2bc428d482ed6 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:31:58 +0100 Subject: [PATCH 07/30] Cleanup types --- src/v2/components/database/index.ts | 36 +++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index e121cd5..7ab620c 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -6,23 +6,41 @@ import { Password } from '../../../components/password'; import { commonTags } from '../../../constants'; export namespace Database { - export type Args = { + export type Instance = { dbName?: pulumi.Input; - username?: pulumi.Input; - password?: pulumi.Input; + engineVersion?: pulumi.Input; + instanceClass?: pulumi.Input; + allowMajorVersionUpgrade?: pulumi.Input; + autoMinorVersionUpgrade?: pulumi.Input; + }; + + export type Networking = { vpc: pulumi.Input; multiAz?: pulumi.Input; - applyImmediately?: pulumi.Input; + }; + + export type Credentials = { + username?: pulumi.Input; + password?: pulumi.Input; + }; + + export type Storage = { allocatedStorage?: pulumi.Input; maxAllocatedStorage?: pulumi.Input; - instanceClass?: pulumi.Input; - allowMajorVersionUpgrade?: pulumi.Input; - autoMinorVersionUpgrade?: pulumi.Input; kmsKeyId?: pulumi.Input; - parameterGroupName?: pulumi.Input; snapshotIdentifier?: pulumi.Input; + }; + + export type Monitoring = { enableMonitoring?: pulumi.Input; - engineVersion?: pulumi.Input; + applyImmediately?: pulumi.Input; + }; + + export type ParameterGroup = { + parameterGroupName?: pulumi.Input; + }; + + export type Args = Instance & Networking & Credentials & Storage & Monitoring & ParameterGroup & { tags?: pulumi.Input<{ [key: string]: pulumi.Input; }>; From 41465b48124bf1648001338f327ea4a1bdb01d59 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:32:30 +0100 Subject: [PATCH 08/30] Fix formatting --- src/v2/components/database/index.ts | 53 +++++++++++++++-------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 7ab620c..07b0d54 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -40,11 +40,16 @@ export namespace Database { parameterGroupName?: pulumi.Input; }; - export type Args = Instance & Networking & Credentials & Storage & Monitoring & ParameterGroup & { - tags?: pulumi.Input<{ - [key: string]: pulumi.Input; - }>; - }; + export type Args = Instance & + Networking & + Credentials & + Storage & + Monitoring & + ParameterGroup & { + tags?: pulumi.Input<{ + [key: string]: pulumi.Input; + }>; + }; } const defaults = { @@ -80,12 +85,8 @@ export class Database extends pulumi.ComponentResource { this.name = name; const argsWithDefaults = Object.assign({}, defaults, args); - const { - vpc, - kmsKeyId, - enableMonitoring, - snapshotIdentifier, - } = argsWithDefaults; + const { vpc, kmsKeyId, enableMonitoring, snapshotIdentifier } = + argsWithDefaults; this.vpc = pulumi.output(vpc); this.dbSubnetGroup = this.createSubnetGroup(); @@ -162,22 +163,24 @@ export class Database extends pulumi.ComponentResource { } private createMonitoringRole() { - const monitoringRole = new aws.iam.Role(`${this.name}-rds-monitoring`, { - assumeRolePolicy: { - Version: '2012-10-17', - Statement: [ - { - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: 'monitoring.rds.amazonaws.com', + const monitoringRole = new aws.iam.Role( + `${this.name}-rds-monitoring`, + { + assumeRolePolicy: { + Version: '2012-10-17', + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'monitoring.rds.amazonaws.com', + }, }, - }, - ], + ], + }, }, - }, - { parent: this }, - ); + { parent: this }, + ); new aws.iam.RolePolicyAttachment( `${this.name}-rds-monitoring-role-attachment`, From e9b7ea69cd3876a044fbc098275b2fe82c11f06d Mon Sep 17 00:00:00 2001 From: mandryllo Date: Mon, 8 Dec 2025 10:55:58 +0100 Subject: [PATCH 09/30] Cleanup --- src/v2/components/database/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 07b0d54..ff48e7a 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -206,7 +206,7 @@ export class Database extends pulumi.ComponentResource { }), ).dbSnapshotArn; - const encryptedSnapshotCopy = new aws.rds.SnapshotCopy( + return new aws.rds.SnapshotCopy( `${this.name}-encrypted-snapshot-copy`, { sourceDbSnapshotIdentifier, @@ -215,7 +215,6 @@ export class Database extends pulumi.ComponentResource { }, { parent: this }, ); - return encryptedSnapshotCopy; } private createDatabaseInstance(args: Database.Args) { From d08a2f0ef8203b46b40dbc1070abf2d873b5a267 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 2 Dec 2025 17:35:43 +0100 Subject: [PATCH 10/30] Create db builder component --- src/v2/components/database/builder.ts | 122 ++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/v2/components/database/builder.ts diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts new file mode 100644 index 0000000..fefb3c3 --- /dev/null +++ b/src/v2/components/database/builder.ts @@ -0,0 +1,122 @@ +import * as pulumi from '@pulumi/pulumi'; +import * as aws from '@pulumi/aws'; +import * as awsx from '@pulumi/awsx'; +import { Database } from '.'; + +export namespace DatabaseBuilder { + export type Config = Omit< + Database.Args, + | 'vpc' + | 'enableMonitoring' + | 'parameterGroupName' + | 'customParameterGroupArgs' + | 'kmsKeyId' + | 'snapshotIdentifier' + >; +} + +export class DatabaseBuilder { + private _name: string; + private _config?: DatabaseBuilder.Config; + private _vpc?: Database.Args['vpc']; + private _enableMonitoring?: Database.Args['enableMonitoring']; + private _parameterGroupName?: Database.Args['parameterGroupName']; + private _customParameterGroupArgs?: Database.Args['customParameterGroupArgs']; + private _kmsKeyId?: Database.Args['kmsKeyId']; + private _snapshotIdentifier?: Database.Args['snapshotIdentifier']; + + constructor(name: string) { + this._name = name; + } + + public configure( + dbName: DatabaseBuilder.Config['dbName'], + username: DatabaseBuilder.Config['username'], + config: Omit = {}, + ): this { + this._config = { + dbName, + username, + ...config, + }; + + return this; + } + + public withVpc(vpc: pulumi.Input): this { + this._vpc = pulumi.output(vpc); + + return this; + } + + public withMonitoring(): this { + this._enableMonitoring = true; + + return this; + } + + public createFromSnapshot(snapshotIdentifier: pulumi.Input): this { + this._snapshotIdentifier = snapshotIdentifier; + + return this; + } + + public useExistingParameterGroup( + parameterGroupName: pulumi.Input, + ): this { + this._parameterGroupName = parameterGroupName; + + return this; + } + + public withCustomParameterGroup( + customParameterGroupArgs: pulumi.Input, + ): this { + this._customParameterGroupArgs = customParameterGroupArgs; + + return this; + } + + public useExitingKms(kmsKeyId: pulumi.Input): this { + this._kmsKeyId = kmsKeyId; + + return this; + } + + public build(opts: pulumi.ComponentResourceOptions = {}): Database { + if (!this._config && !this._snapshotIdentifier) { + throw new Error( + `Database is not configured. Make sure to call DatabaseBuilder.configure() + or create it from a snapshot with DatabaseBuilder.createFromSnapshot().`, + ); + } + + if (!this._vpc) { + throw new Error( + 'VPC not provided. Make sure to call DatabaseBuilder.withVpc().', + ); + } + + if (this._parameterGroupName && this._customParameterGroupArgs) { + throw new Error( + `You can't both use existing parameter group and create a custom one. + Make sure to call either DatabaseBuilder.useExistingParameterGroup() + or DatabaseBuilder.withCustomParameterGroup(), but not both.`, + ); + } + + return new Database( + this._name, + { + ...this._config, + vpc: this._vpc, + enableMonitoring: this._enableMonitoring, + snapshotIdentifier: this._snapshotIdentifier, + parameterGroupName: this._parameterGroupName, + customParameterGroupArgs: this._customParameterGroupArgs, + kmsKeyId: this._kmsKeyId, + }, + opts, + ); + } +} From e200c4b248e0130767cbb275b5637a92d2934a01 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Wed, 3 Dec 2025 10:46:00 +0100 Subject: [PATCH 11/30] Fix typo --- src/v2/components/database/builder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index fefb3c3..4630d28 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -77,7 +77,7 @@ export class DatabaseBuilder { return this; } - public useExitingKms(kmsKeyId: pulumi.Input): this { + public useExistingKms(kmsKeyId: pulumi.Input): this { this._kmsKeyId = kmsKeyId; return this; From d7a4436b19c7eff23e9678cf60967a9c664d4dec Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:33:24 +0100 Subject: [PATCH 12/30] Remove custom parameter group args --- src/v2/components/database/builder.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 4630d28..be232ba 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -21,7 +21,6 @@ export class DatabaseBuilder { private _vpc?: Database.Args['vpc']; private _enableMonitoring?: Database.Args['enableMonitoring']; private _parameterGroupName?: Database.Args['parameterGroupName']; - private _customParameterGroupArgs?: Database.Args['customParameterGroupArgs']; private _kmsKeyId?: Database.Args['kmsKeyId']; private _snapshotIdentifier?: Database.Args['snapshotIdentifier']; @@ -69,14 +68,6 @@ export class DatabaseBuilder { return this; } - public withCustomParameterGroup( - customParameterGroupArgs: pulumi.Input, - ): this { - this._customParameterGroupArgs = customParameterGroupArgs; - - return this; - } - public useExistingKms(kmsKeyId: pulumi.Input): this { this._kmsKeyId = kmsKeyId; @@ -97,14 +88,6 @@ export class DatabaseBuilder { ); } - if (this._parameterGroupName && this._customParameterGroupArgs) { - throw new Error( - `You can't both use existing parameter group and create a custom one. - Make sure to call either DatabaseBuilder.useExistingParameterGroup() - or DatabaseBuilder.withCustomParameterGroup(), but not both.`, - ); - } - return new Database( this._name, { @@ -113,7 +96,6 @@ export class DatabaseBuilder { enableMonitoring: this._enableMonitoring, snapshotIdentifier: this._snapshotIdentifier, parameterGroupName: this._parameterGroupName, - customParameterGroupArgs: this._customParameterGroupArgs, kmsKeyId: this._kmsKeyId, }, opts, From 1e447d8d72dcd879b544e18342c2e81debeb0aa2 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:34:14 +0100 Subject: [PATCH 13/30] Cleanup private props --- src/v2/components/database/builder.ts | 46 +++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index be232ba..1821517 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -16,16 +16,16 @@ export namespace DatabaseBuilder { } export class DatabaseBuilder { - private _name: string; - private _config?: DatabaseBuilder.Config; - private _vpc?: Database.Args['vpc']; - private _enableMonitoring?: Database.Args['enableMonitoring']; - private _parameterGroupName?: Database.Args['parameterGroupName']; - private _kmsKeyId?: Database.Args['kmsKeyId']; - private _snapshotIdentifier?: Database.Args['snapshotIdentifier']; + private name: string; + private config?: DatabaseBuilder.Config; + private vpc?: Database.Args['vpc']; + private enableMonitoring?: Database.Args['enableMonitoring']; + private parameterGroupName?: Database.Args['parameterGroupName']; + private kmsKeyId?: Database.Args['kmsKeyId']; + private snapshotIdentifier?: Database.Args['snapshotIdentifier']; constructor(name: string) { - this._name = name; + this.name = name; } public configure( @@ -33,7 +33,7 @@ export class DatabaseBuilder { username: DatabaseBuilder.Config['username'], config: Omit = {}, ): this { - this._config = { + this.config = { dbName, username, ...config, @@ -43,19 +43,19 @@ export class DatabaseBuilder { } public withVpc(vpc: pulumi.Input): this { - this._vpc = pulumi.output(vpc); + this.vpc = pulumi.output(vpc); return this; } public withMonitoring(): this { - this._enableMonitoring = true; + this.enableMonitoring = true; return this; } public createFromSnapshot(snapshotIdentifier: pulumi.Input): this { - this._snapshotIdentifier = snapshotIdentifier; + this.snapshotIdentifier = snapshotIdentifier; return this; } @@ -63,40 +63,40 @@ export class DatabaseBuilder { public useExistingParameterGroup( parameterGroupName: pulumi.Input, ): this { - this._parameterGroupName = parameterGroupName; + this.parameterGroupName = parameterGroupName; return this; } public useExistingKms(kmsKeyId: pulumi.Input): this { - this._kmsKeyId = kmsKeyId; + this.kmsKeyId = kmsKeyId; return this; } public build(opts: pulumi.ComponentResourceOptions = {}): Database { - if (!this._config && !this._snapshotIdentifier) { + if (!this.config && !this.snapshotIdentifier) { throw new Error( `Database is not configured. Make sure to call DatabaseBuilder.configure() or create it from a snapshot with DatabaseBuilder.createFromSnapshot().`, ); } - if (!this._vpc) { + if (!this.vpc) { throw new Error( 'VPC not provided. Make sure to call DatabaseBuilder.withVpc().', ); } return new Database( - this._name, + this.name, { - ...this._config, - vpc: this._vpc, - enableMonitoring: this._enableMonitoring, - snapshotIdentifier: this._snapshotIdentifier, - parameterGroupName: this._parameterGroupName, - kmsKeyId: this._kmsKeyId, + ...this.config, + vpc: this.vpc, + enableMonitoring: this.enableMonitoring, + snapshotIdentifier: this.snapshotIdentifier, + parameterGroupName: this.parameterGroupName, + kmsKeyId: this.kmsKeyId, }, opts, ); From 5ec75165aa29a3d03bc53ce48218200ea9014165 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:34:53 +0100 Subject: [PATCH 14/30] Remove parameter group name from builder --- src/v2/components/database/builder.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 1821517..478847b 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -8,7 +8,6 @@ export namespace DatabaseBuilder { Database.Args, | 'vpc' | 'enableMonitoring' - | 'parameterGroupName' | 'customParameterGroupArgs' | 'kmsKeyId' | 'snapshotIdentifier' @@ -20,7 +19,6 @@ export class DatabaseBuilder { private config?: DatabaseBuilder.Config; private vpc?: Database.Args['vpc']; private enableMonitoring?: Database.Args['enableMonitoring']; - private parameterGroupName?: Database.Args['parameterGroupName']; private kmsKeyId?: Database.Args['kmsKeyId']; private snapshotIdentifier?: Database.Args['snapshotIdentifier']; @@ -60,14 +58,6 @@ export class DatabaseBuilder { return this; } - public useExistingParameterGroup( - parameterGroupName: pulumi.Input, - ): this { - this.parameterGroupName = parameterGroupName; - - return this; - } - public useExistingKms(kmsKeyId: pulumi.Input): this { this.kmsKeyId = kmsKeyId; @@ -95,7 +85,6 @@ export class DatabaseBuilder { vpc: this.vpc, enableMonitoring: this.enableMonitoring, snapshotIdentifier: this.snapshotIdentifier, - parameterGroupName: this.parameterGroupName, kmsKeyId: this.kmsKeyId, }, opts, From 9a8f4762ec6762b37b433b04bc76c535f71907dd Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:36:31 +0100 Subject: [PATCH 15/30] Cleanup naming --- src/v2/components/database/builder.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 478847b..9378b7a 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -8,7 +8,6 @@ export namespace DatabaseBuilder { Database.Args, | 'vpc' | 'enableMonitoring' - | 'customParameterGroupArgs' | 'kmsKeyId' | 'snapshotIdentifier' >; @@ -52,23 +51,22 @@ export class DatabaseBuilder { return this; } - public createFromSnapshot(snapshotIdentifier: pulumi.Input): this { + public withSnapshot(snapshotIdentifier: pulumi.Input): this { this.snapshotIdentifier = snapshotIdentifier; return this; } - public useExistingKms(kmsKeyId: pulumi.Input): this { + public withKms(kmsKeyId: pulumi.Input): this { this.kmsKeyId = kmsKeyId; return this; } public build(opts: pulumi.ComponentResourceOptions = {}): Database { - if (!this.config && !this.snapshotIdentifier) { + if (!this.config) { throw new Error( - `Database is not configured. Make sure to call DatabaseBuilder.configure() - or create it from a snapshot with DatabaseBuilder.createFromSnapshot().`, + `Database is not configured. Make sure to call DatabaseBuilder.configure().`, ); } From d1470a64ffe3a1f57182fcafe853af647789c864 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Fri, 5 Dec 2025 18:36:57 +0100 Subject: [PATCH 16/30] Fix formatting --- src/v2/components/database/builder.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 9378b7a..50b7eec 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -6,10 +6,7 @@ import { Database } from '.'; export namespace DatabaseBuilder { export type Config = Omit< Database.Args, - | 'vpc' - | 'enableMonitoring' - | 'kmsKeyId' - | 'snapshotIdentifier' + 'vpc' | 'enableMonitoring' | 'kmsKeyId' | 'snapshotIdentifier' >; } From 0406006a3a840228ac4ec36a40c6f448d45f7bad Mon Sep 17 00:00:00 2001 From: mandryllo Date: Mon, 8 Dec 2025 11:02:29 +0100 Subject: [PATCH 17/30] Cleanup --- src/v2/components/database/builder.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 50b7eec..2ed2af2 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -22,16 +22,8 @@ export class DatabaseBuilder { this.name = name; } - public configure( - dbName: DatabaseBuilder.Config['dbName'], - username: DatabaseBuilder.Config['username'], - config: Omit = {}, - ): this { - this.config = { - dbName, - username, - ...config, - }; + public withConfiguration(config: DatabaseBuilder.Config = {}): this { + this.config = config; return this; } @@ -63,7 +55,7 @@ export class DatabaseBuilder { public build(opts: pulumi.ComponentResourceOptions = {}): Database { if (!this.config) { throw new Error( - `Database is not configured. Make sure to call DatabaseBuilder.configure().`, + `Database is not configured. Make sure to call DatabaseBuilder.withConfiguration().`, ); } @@ -73,6 +65,15 @@ export class DatabaseBuilder { ); } + if ( + this.snapshotIdentifier && + (this.config.dbName || this.config.username) + ) { + throw new Error( + `You can't set dbName or username when using snapshotIdentifier.`, + ); + } + return new Database( this.name, { From 4c9c426020b4dc7ae675bc59c4eb6b86eb2c0bb8 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Wed, 10 Dec 2025 10:22:54 +0100 Subject: [PATCH 18/30] Cleanup database types --- src/v2/components/database/index.ts | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index ff48e7a..76c7af0 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -9,16 +9,12 @@ export namespace Database { export type Instance = { dbName?: pulumi.Input; engineVersion?: pulumi.Input; + multiAz?: pulumi.Input; instanceClass?: pulumi.Input; allowMajorVersionUpgrade?: pulumi.Input; autoMinorVersionUpgrade?: pulumi.Input; }; - export type Networking = { - vpc: pulumi.Input; - multiAz?: pulumi.Input; - }; - export type Credentials = { username?: pulumi.Input; password?: pulumi.Input; @@ -28,24 +24,16 @@ export namespace Database { allocatedStorage?: pulumi.Input; maxAllocatedStorage?: pulumi.Input; kmsKeyId?: pulumi.Input; - snapshotIdentifier?: pulumi.Input; - }; - - export type Monitoring = { - enableMonitoring?: pulumi.Input; - applyImmediately?: pulumi.Input; - }; - - export type ParameterGroup = { - parameterGroupName?: pulumi.Input; }; export type Args = Instance & - Networking & Credentials & - Storage & - Monitoring & - ParameterGroup & { + Storage & { + vpc: pulumi.Input; + enableMonitoring?: pulumi.Input; + applyImmediately?: pulumi.Input; + snapshotIdentifier?: pulumi.Input; + parameterGroupName?: pulumi.Input; tags?: pulumi.Input<{ [key: string]: pulumi.Input; }>; From d067ec5294e0ed7ac567436488d5ad4dde8d34c6 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Wed, 10 Dec 2025 14:58:51 +0100 Subject: [PATCH 19/30] Cleanup --- src/v2/components/database/builder.ts | 70 ++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 2ed2af2..f5003fe 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -4,15 +4,27 @@ import * as awsx from '@pulumi/awsx'; import { Database } from '.'; export namespace DatabaseBuilder { + export type InstanceConfig = Database.Instance; + export type CredentialsConfig = Database.Credentials; + export type StorageConfig = Omit; export type Config = Omit< Database.Args, - 'vpc' | 'enableMonitoring' | 'kmsKeyId' | 'snapshotIdentifier' + | keyof Database.Instance + | keyof Database.Credentials + | keyof Database.Storage + | 'vpc' + | 'enableMonitoring' + | 'kmsKeyId' + | 'snapshotIdentifier' >; } export class DatabaseBuilder { private name: string; private config?: DatabaseBuilder.Config; + private instanceConfig?: DatabaseBuilder.InstanceConfig; + private credentialsConfig?: DatabaseBuilder.CredentialsConfig; + private storageConfig?: DatabaseBuilder.StorageConfig; private vpc?: Database.Args['vpc']; private enableMonitoring?: Database.Args['enableMonitoring']; private kmsKeyId?: Database.Args['kmsKeyId']; @@ -28,7 +40,29 @@ export class DatabaseBuilder { return this; } - public withVpc(vpc: pulumi.Input): this { + public withInstance( + instanceConfig: DatabaseBuilder.InstanceConfig = {}, + ): this { + this.instanceConfig = instanceConfig; + + return this; + } + + public withCredentials( + credentialsConfig: DatabaseBuilder.CredentialsConfig = {}, + ): this { + this.credentialsConfig = credentialsConfig; + + return this; + } + + public withStorage(storageConfig: DatabaseBuilder.StorageConfig = {}): this { + this.storageConfig = storageConfig; + + return this; + } + + public withVpc(vpc: Database.Args['vpc']): this { this.vpc = pulumi.output(vpc); return this; @@ -40,37 +74,44 @@ export class DatabaseBuilder { return this; } - public withSnapshot(snapshotIdentifier: pulumi.Input): this { + public withSnapshot( + snapshotIdentifier: Database.Args['snapshotIdentifier'], + ): this { this.snapshotIdentifier = snapshotIdentifier; return this; } - public withKms(kmsKeyId: pulumi.Input): this { + public withKms(kmsKeyId: Database.Args['kmsKeyId']): this { this.kmsKeyId = kmsKeyId; return this; } public build(opts: pulumi.ComponentResourceOptions = {}): Database { - if (!this.config) { + if (!this.snapshotIdentifier && !this.instanceConfig?.dbName) { throw new Error( - `Database is not configured. Make sure to call DatabaseBuilder.withConfiguration().`, + 'DbName not provided. Make sure to call DatabaseBuilder.withInstance() and set dbName.', ); } - if (!this.vpc) { + if (!this.snapshotIdentifier && !this.credentialsConfig?.username) { throw new Error( - 'VPC not provided. Make sure to call DatabaseBuilder.withVpc().', + 'Username not provided. Make sure to call DatabaseBuilder.withCredentials() and set username.', ); } - if ( - this.snapshotIdentifier && - (this.config.dbName || this.config.username) - ) { + if (this.snapshotIdentifier && !this.instanceConfig?.dbName) { + throw new Error(`You can't set dbName when using snapshotIdentifier.`); + } + + if (this.snapshotIdentifier && !this.credentialsConfig?.username) { + throw new Error(`You can't set username when using snapshotIdentifier.`); + } + + if (!this.vpc) { throw new Error( - `You can't set dbName or username when using snapshotIdentifier.`, + 'VPC not provided. Make sure to call DatabaseBuilder.withVpc().', ); } @@ -78,6 +119,9 @@ export class DatabaseBuilder { this.name, { ...this.config, + ...this.instanceConfig, + ...this.credentialsConfig, + ...this.storageConfig, vpc: this.vpc, enableMonitoring: this.enableMonitoring, snapshotIdentifier: this.snapshotIdentifier, From 31cbcd14dd3e2d7187d05638833b3379cab7af11 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Wed, 10 Dec 2025 15:00:28 +0100 Subject: [PATCH 20/30] Revert allocatedStorage type to number --- src/v2/components/database/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 76c7af0..388740d 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -21,7 +21,7 @@ export namespace Database { }; export type Storage = { - allocatedStorage?: pulumi.Input; + allocatedStorage?: pulumi.Input; maxAllocatedStorage?: pulumi.Input; kmsKeyId?: pulumi.Input; }; @@ -43,7 +43,7 @@ export namespace Database { const defaults = { multiAz: false, applyImmediately: false, - allocatedStorage: '20', + allocatedStorage: 20, maxAllocatedStorage: 100, instanceClass: 'db.t4g.micro', enableMonitoring: false, @@ -228,7 +228,7 @@ export class Database extends pulumi.ComponentResource { masterUserPassword: this.password.value, dbSubnetGroupName: this.dbSubnetGroup.name, vpcSecurityGroups: [this.dbSecurityGroup.id], - allocatedStorage: args.allocatedStorage, + allocatedStorage: args.allocatedStorage?.toString(), maxAllocatedStorage: args.maxAllocatedStorage, multiAz: args.multiAz, applyImmediately: args.applyImmediately, From d94a98e147fe40d4cafbcc1ee3806380efff9231 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Wed, 10 Dec 2025 15:06:33 +0100 Subject: [PATCH 21/30] Remove withKms method from builder --- src/v2/components/database/builder.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index f5003fe..f1c8641 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -6,7 +6,7 @@ import { Database } from '.'; export namespace DatabaseBuilder { export type InstanceConfig = Database.Instance; export type CredentialsConfig = Database.Credentials; - export type StorageConfig = Omit; + export type StorageConfig = Database.Storage; export type Config = Omit< Database.Args, | keyof Database.Instance @@ -14,7 +14,6 @@ export namespace DatabaseBuilder { | keyof Database.Storage | 'vpc' | 'enableMonitoring' - | 'kmsKeyId' | 'snapshotIdentifier' >; } @@ -27,7 +26,6 @@ export class DatabaseBuilder { private storageConfig?: DatabaseBuilder.StorageConfig; private vpc?: Database.Args['vpc']; private enableMonitoring?: Database.Args['enableMonitoring']; - private kmsKeyId?: Database.Args['kmsKeyId']; private snapshotIdentifier?: Database.Args['snapshotIdentifier']; constructor(name: string) { @@ -82,12 +80,6 @@ export class DatabaseBuilder { return this; } - public withKms(kmsKeyId: Database.Args['kmsKeyId']): this { - this.kmsKeyId = kmsKeyId; - - return this; - } - public build(opts: pulumi.ComponentResourceOptions = {}): Database { if (!this.snapshotIdentifier && !this.instanceConfig?.dbName) { throw new Error( @@ -125,7 +117,6 @@ export class DatabaseBuilder { vpc: this.vpc, enableMonitoring: this.enableMonitoring, snapshotIdentifier: this.snapshotIdentifier, - kmsKeyId: this.kmsKeyId, }, opts, ); From b64d94c94654bc025ad3f0b33b57da0f74c4cc9e Mon Sep 17 00:00:00 2001 From: mandryllo Date: Wed, 10 Dec 2025 16:55:39 +0100 Subject: [PATCH 22/30] fix tags --- src/v2/components/database/index.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 388740d..93549d8 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -245,11 +245,13 @@ export class Database extends pulumi.ComponentResource { dbSnapshotIdentifier: this.encryptedSnapshotCopy?.targetDbSnapshotIdentifier, ...monitoringOptions, - tags: [ - ...Object.entries({ ...commonTags, ...args.tags }).map( - ([key, value]) => ({ key, value }), - ), - ], + tags: pulumi + .output(args.tags) + .apply(tags => [ + ...Object.entries({ ...commonTags, ...tags }).map( + ([key, value]) => ({ key, value }), + ), + ]), }, { parent: this, dependsOn: [this.password] }, ); From 62206a3e7b6b8bdb81f7420806257d6e760bb107 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Wed, 10 Dec 2025 16:55:51 +0100 Subject: [PATCH 23/30] Fix snapshot id --- src/v2/components/database/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 93549d8..695d12a 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -184,7 +184,7 @@ export class Database extends pulumi.ComponentResource { } private createEncryptedSnapshotCopy( - snapshotIdentifier: pulumi.Input, + snapshotIdentifier: Database.Args['snapshotIdentifier'], ) { const sourceDbSnapshotIdentifier = pulumi .output(snapshotIdentifier) @@ -198,7 +198,7 @@ export class Database extends pulumi.ComponentResource { `${this.name}-encrypted-snapshot-copy`, { sourceDbSnapshotIdentifier, - targetDbSnapshotIdentifier: `${snapshotIdentifier}-encrypted-copy`, + targetDbSnapshotIdentifier: pulumi.interpolate`${snapshotIdentifier}-encrypted-copy`, kmsKeyId: this.kmsKeyId, }, { parent: this }, From a77022b72f9e965513fbab57c7cafd4c6696223d Mon Sep 17 00:00:00 2001 From: mandryllo Date: Thu, 11 Dec 2025 13:09:14 +0100 Subject: [PATCH 24/30] Fix wrong condition --- src/v2/components/database/builder.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index f1c8641..a9fda6d 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -93,11 +93,11 @@ export class DatabaseBuilder { ); } - if (this.snapshotIdentifier && !this.instanceConfig?.dbName) { + if (this.snapshotIdentifier && this.instanceConfig?.dbName) { throw new Error(`You can't set dbName when using snapshotIdentifier.`); } - if (this.snapshotIdentifier && !this.credentialsConfig?.username) { + if (this.snapshotIdentifier && this.credentialsConfig?.username) { throw new Error(`You can't set username when using snapshotIdentifier.`); } From 02235d549cb83dc913f76e1766209f2ca523f81b Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 16 Dec 2025 11:41:06 +0100 Subject: [PATCH 25/30] Update database builder --- src/v2/components/database/builder.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index a9fda6d..566088c 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -6,7 +6,7 @@ import { Database } from '.'; export namespace DatabaseBuilder { export type InstanceConfig = Database.Instance; export type CredentialsConfig = Database.Credentials; - export type StorageConfig = Database.Storage; + export type StorageConfig = Omit; export type Config = Omit< Database.Args, | keyof Database.Instance @@ -15,6 +15,7 @@ export namespace DatabaseBuilder { | 'vpc' | 'enableMonitoring' | 'snapshotIdentifier' + | 'parameterGroupName' >; } @@ -27,6 +28,8 @@ export class DatabaseBuilder { private vpc?: Database.Args['vpc']; private enableMonitoring?: Database.Args['enableMonitoring']; private snapshotIdentifier?: Database.Args['snapshotIdentifier']; + private kmsKeyId?: Database.Args['kmsKeyId']; + private parameterGroupName?: Database.Args['parameterGroupName']; constructor(name: string) { this.name = name; @@ -80,6 +83,20 @@ export class DatabaseBuilder { return this; } + public withKms(kmsKeyId: Database.Args['kmsKeyId']): this { + this.kmsKeyId = kmsKeyId; + + return this; + } + + public withParameterGroup( + parameterGroupName: Database.Args['parameterGroupName'], + ): this { + this.parameterGroupName = parameterGroupName; + + return this; + } + public build(opts: pulumi.ComponentResourceOptions = {}): Database { if (!this.snapshotIdentifier && !this.instanceConfig?.dbName) { throw new Error( @@ -117,6 +134,8 @@ export class DatabaseBuilder { vpc: this.vpc, enableMonitoring: this.enableMonitoring, snapshotIdentifier: this.snapshotIdentifier, + kmsKeyId: this.kmsKeyId, + parameterGroupName: this.parameterGroupName, }, opts, ); From 63c1af757531bbd54a7b6c26dd10e645540ae685 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 16 Dec 2025 11:41:47 +0100 Subject: [PATCH 26/30] Cleanup --- src/v2/components/database/builder.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 566088c..90c03d7 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -1,7 +1,5 @@ -import * as pulumi from '@pulumi/pulumi'; -import * as aws from '@pulumi/aws'; -import * as awsx from '@pulumi/awsx'; import { Database } from '.'; +import * as pulumi from '@pulumi/pulumi'; export namespace DatabaseBuilder { export type InstanceConfig = Database.Instance; From 78c8231c4cde1c37e68593f06dd1b73e3ceaa3ee Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 16 Dec 2025 13:26:15 +0100 Subject: [PATCH 27/30] Move applyImmediately to instance config --- src/v2/components/database/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 695d12a..461f922 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -13,6 +13,7 @@ export namespace Database { instanceClass?: pulumi.Input; allowMajorVersionUpgrade?: pulumi.Input; autoMinorVersionUpgrade?: pulumi.Input; + applyImmediately?: pulumi.Input; }; export type Credentials = { @@ -31,7 +32,6 @@ export namespace Database { Storage & { vpc: pulumi.Input; enableMonitoring?: pulumi.Input; - applyImmediately?: pulumi.Input; snapshotIdentifier?: pulumi.Input; parameterGroupName?: pulumi.Input; tags?: pulumi.Input<{ From 3137cdd4adda91f7dca4dbbe405e50018be2cdcf Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 16 Dec 2025 13:28:43 +0100 Subject: [PATCH 28/30] Update builder methods --- src/v2/components/database/builder.ts | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 90c03d7..7762734 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -5,21 +5,10 @@ export namespace DatabaseBuilder { export type InstanceConfig = Database.Instance; export type CredentialsConfig = Database.Credentials; export type StorageConfig = Omit; - export type Config = Omit< - Database.Args, - | keyof Database.Instance - | keyof Database.Credentials - | keyof Database.Storage - | 'vpc' - | 'enableMonitoring' - | 'snapshotIdentifier' - | 'parameterGroupName' - >; } export class DatabaseBuilder { private name: string; - private config?: DatabaseBuilder.Config; private instanceConfig?: DatabaseBuilder.InstanceConfig; private credentialsConfig?: DatabaseBuilder.CredentialsConfig; private storageConfig?: DatabaseBuilder.StorageConfig; @@ -28,17 +17,12 @@ export class DatabaseBuilder { private snapshotIdentifier?: Database.Args['snapshotIdentifier']; private kmsKeyId?: Database.Args['kmsKeyId']; private parameterGroupName?: Database.Args['parameterGroupName']; + private tags?: Database.Args['tags']; constructor(name: string) { this.name = name; } - public withConfiguration(config: DatabaseBuilder.Config = {}): this { - this.config = config; - - return this; - } - public withInstance( instanceConfig: DatabaseBuilder.InstanceConfig = {}, ): this { @@ -95,6 +79,12 @@ export class DatabaseBuilder { return this; } + public withTags(tags: Database.Args['tags']): this { + this.tags = tags; + + return this; + } + public build(opts: pulumi.ComponentResourceOptions = {}): Database { if (!this.snapshotIdentifier && !this.instanceConfig?.dbName) { throw new Error( @@ -125,7 +115,6 @@ export class DatabaseBuilder { return new Database( this.name, { - ...this.config, ...this.instanceConfig, ...this.credentialsConfig, ...this.storageConfig, @@ -134,6 +123,7 @@ export class DatabaseBuilder { snapshotIdentifier: this.snapshotIdentifier, kmsKeyId: this.kmsKeyId, parameterGroupName: this.parameterGroupName, + tags: this.tags, }, opts, ); From da11c61f1efcc21d114c3aefe9d1b44c67a06cb9 Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 16 Dec 2025 13:54:15 +0100 Subject: [PATCH 29/30] Move kms key from storage type --- src/v2/components/database/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2/components/database/index.ts b/src/v2/components/database/index.ts index 461f922..bb97184 100644 --- a/src/v2/components/database/index.ts +++ b/src/v2/components/database/index.ts @@ -24,7 +24,6 @@ export namespace Database { export type Storage = { allocatedStorage?: pulumi.Input; maxAllocatedStorage?: pulumi.Input; - kmsKeyId?: pulumi.Input; }; export type Args = Instance & @@ -34,6 +33,7 @@ export namespace Database { enableMonitoring?: pulumi.Input; snapshotIdentifier?: pulumi.Input; parameterGroupName?: pulumi.Input; + kmsKeyId?: pulumi.Input; tags?: pulumi.Input<{ [key: string]: pulumi.Input; }>; From 390c04d7e1ad2f001d01d72179cdd5561e75c5ec Mon Sep 17 00:00:00 2001 From: mandryllo Date: Tue, 16 Dec 2025 13:55:53 +0100 Subject: [PATCH 30/30] Update builder --- src/v2/components/database/builder.ts | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/v2/components/database/builder.ts b/src/v2/components/database/builder.ts index 7762734..9cd343c 100644 --- a/src/v2/components/database/builder.ts +++ b/src/v2/components/database/builder.ts @@ -1,17 +1,11 @@ import { Database } from '.'; import * as pulumi from '@pulumi/pulumi'; -export namespace DatabaseBuilder { - export type InstanceConfig = Database.Instance; - export type CredentialsConfig = Database.Credentials; - export type StorageConfig = Omit; -} - export class DatabaseBuilder { private name: string; - private instanceConfig?: DatabaseBuilder.InstanceConfig; - private credentialsConfig?: DatabaseBuilder.CredentialsConfig; - private storageConfig?: DatabaseBuilder.StorageConfig; + private instanceConfig?: Database.Instance; + private credentialsConfig?: Database.Credentials; + private storageConfig?: Database.Storage; private vpc?: Database.Args['vpc']; private enableMonitoring?: Database.Args['enableMonitoring']; private snapshotIdentifier?: Database.Args['snapshotIdentifier']; @@ -23,23 +17,19 @@ export class DatabaseBuilder { this.name = name; } - public withInstance( - instanceConfig: DatabaseBuilder.InstanceConfig = {}, - ): this { + public withInstance(instanceConfig: Database.Instance = {}): this { this.instanceConfig = instanceConfig; return this; } - public withCredentials( - credentialsConfig: DatabaseBuilder.CredentialsConfig = {}, - ): this { + public withCredentials(credentialsConfig: Database.Credentials = {}): this { this.credentialsConfig = credentialsConfig; return this; } - public withStorage(storageConfig: DatabaseBuilder.StorageConfig = {}): this { + public withStorage(storageConfig: Database.Storage = {}): this { this.storageConfig = storageConfig; return this;