diff --git a/integration_tests/cdk/app.py b/integration_tests/cdk/app.py index d54e2f0..2b8d896 100644 --- a/integration_tests/cdk/app.py +++ b/integration_tests/cdk/app.py @@ -83,6 +83,9 @@ def __init__( allocated_storage=app_config.db_allocated_storage, instance_type=aws_ec2.InstanceType(app_config.db_instance_type), add_pgbouncer=True, + pgbouncer_instance_props={ + "instanceName": "test-name", + }, removal_policy=RemovalPolicy.DESTROY, pgstac_version=PGSTAC_VERSION, ) diff --git a/lib/database/PgBouncer.ts b/lib/database/PgBouncer.ts index 3d55086..21cf562 100644 --- a/lib/database/PgBouncer.ts +++ b/lib/database/PgBouncer.ts @@ -25,11 +25,6 @@ export interface PgBouncerConfigProps { } export interface PgBouncerProps { - /** - * Name for the pgbouncer instance - */ - instanceName: string; - /** * VPC to deploy PgBouncer into */ @@ -56,15 +51,14 @@ export interface PgBouncerProps { usePublicSubnet?: boolean; /** - * Instance type for PgBouncer - * @default t3.micro + * PgBouncer configuration options */ - instanceType?: ec2.InstanceType; + pgBouncerConfig?: PgBouncerConfigProps; /** - * PgBouncer configuration options + * EC2 instance options */ - pgBouncerConfig?: PgBouncerConfigProps; + instanceProps?: Partial; } export class PgBouncer extends Construct { @@ -78,7 +72,7 @@ export class PgBouncer extends Construct { // be slightly smaller than the actual max_connections value on the RDS instance // so we perform this calculation. - private getDefaultConfig( + private getDefaultPgbouncerConfig( dbMaxConnections: number ): Required { // maxDbConnections (and maxUserConnections) are the only settings that need @@ -99,17 +93,14 @@ export class PgBouncer extends Construct { super(scope, id); // Set defaults for optional props - const defaultInstanceType = ec2.InstanceType.of( - ec2.InstanceClass.T3, - ec2.InstanceSize.MICRO - ); - const instanceType = props.instanceType ?? defaultInstanceType; - const defaultConfig = this.getDefaultConfig(props.dbMaxConnections); + const defaultPgbouncerConfig = this.getDefaultPgbouncerConfig( + props.dbMaxConnections + ); // Merge provided config with defaults const pgBouncerConfig: Required = { - ...defaultConfig, + ...defaultPgbouncerConfig, ...props.pgBouncerConfig, }; @@ -144,21 +135,21 @@ export class PgBouncer extends Construct { }); // Create PgBouncer instance - this.instance = new ec2.Instance(this, "Instance", { - vpc: props.vpc, + const defaultInstanceConfig: Omit = { + instanceName: "pgbouncer", + instanceType: ec2.InstanceType.of( + ec2.InstanceClass.T3, + ec2.InstanceSize.MICRO + ), vpcSubnets: { subnetType: props.usePublicSubnet ? ec2.SubnetType.PUBLIC : ec2.SubnetType.PRIVATE_WITH_EGRESS, }, - securityGroup: this.securityGroup, - instanceType, - instanceName: props.instanceName, machineImage: ec2.MachineImage.fromSsmParameter( "/aws/service/canonical/ubuntu/server/jammy/stable/current/amd64/hvm/ebs-gp2/ami-id", { os: ec2.OperatingSystemType.LINUX } ), - role, blockDevices: [ { deviceName: "/dev/xvda", @@ -169,9 +160,17 @@ export class PgBouncer extends Construct { }), }, ], + role, + securityGroup: this.securityGroup, userData: this.loadUserDataScript(pgBouncerConfig, props.database), userDataCausesReplacement: true, associatePublicIpAddress: props.usePublicSubnet, + }; + + this.instance = new ec2.Instance(this, "Instance", { + ...defaultInstanceConfig, + ...props.instanceProps, + vpc: props.vpc, }); // Allow PgBouncer to connect to RDS @@ -183,7 +182,7 @@ export class PgBouncer extends Construct { // Create a new secret for pgbouncer connection credentials this.pgbouncerSecret = new secretsmanager.Secret(this, "PgBouncerSecret", { - description: `Connection information for PgBouncer instance ${props.instanceName}`, + description: "Connection information for PgBouncer instance", generateSecretString: { generateStringKey: "dummy", secretStringTemplate: "{}", diff --git a/lib/database/index.ts b/lib/database/index.ts index 397f04f..2fbd8d4 100644 --- a/lib/database/index.ts +++ b/lib/database/index.ts @@ -144,14 +144,20 @@ export class PgStacDatabase extends Construct { }); // PgBouncer: connection poolercustomresource trigger on redeploy + const defaultPgbouncerInstanceProps: Partial = { + instanceName: `${Stack.of(this).stackName}-pgbouncer`, + instanceType: ec2.InstanceType.of( + ec2.InstanceClass.T3, + ec2.InstanceSize.MICRO + ), + }; const addPgbouncer = props.addPgbouncer ?? true; if (addPgbouncer) { this._pgBouncerServer = new PgBouncer(this, "pgbouncer", { - instanceName: `${Stack.of(this).stackName}-pgbouncer`, - instanceType: ec2.InstanceType.of( - ec2.InstanceClass.T3, - ec2.InstanceSize.MICRO - ), + instanceProps: { + ...defaultPgbouncerInstanceProps, + ...props.pgbouncerInstanceProps, + }, vpc: props.vpc, database: { connections: this.db.connections, @@ -258,6 +264,13 @@ export interface PgStacDatabaseProps extends rds.DatabaseInstanceProps { */ readonly addPgbouncer?: boolean; + /** + * Properties for the pgbouncer ec2 instance + * + * @default - defined in the construct + */ + readonly pgbouncerInstanceProps?: ec2.InstanceProps | any; + /** * Lambda function Custom Resource properties. A custom resource property is going to be created * to trigger the boostrapping lambda function. This parameter allows the user to specify additional properties