UNPKG

@studion/infra-code-blocks

Version:
198 lines (197 loc) 8.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Database = void 0; const aws = require("@pulumi/aws"); const pulumi = require("@pulumi/pulumi"); const common_tags_1 = require("../../shared/common-tags"); const database_replica_1 = require("./database-replica"); const ec2_ssm_connect_1 = require("./ec2-ssm-connect"); const merge_with_defaults_1 = require("../../shared/merge-with-defaults"); const password_1 = require("../password"); const defaults = { multiAz: false, applyImmediately: false, skipFinalSnapshot: false, allocatedStorage: 20, maxAllocatedStorage: 100, instanceClass: 'db.t4g.micro', enableMonitoring: false, allowMajorVersionUpgrade: false, autoMinorVersionUpgrade: true, engineVersion: '18', }; class Database extends pulumi.ComponentResource { name; instance; vpc; dbSubnetGroup; dbSecurityGroup; password; kmsKeyId; monitoringRole; encryptedSnapshotCopy; replicas; ec2SSMConnect; constructor(name, args, opts = {}) { super('studion:database:Database', name, {}, { ...opts, aliases: [...(opts.aliases || []), { type: 'studion:Database' }], }); this.name = name; const argsWithDefaults = (0, merge_with_defaults_1.mergeWithDefaults)(defaults, args); const { vpc, kmsKeyId, enableMonitoring, snapshotIdentifier, replicaConfigs, enableSSMConnect, ssmConnectConfig = {}, } = argsWithDefaults; this.vpc = pulumi.output(vpc); this.dbSubnetGroup = this.createSubnetGroup(); this.dbSecurityGroup = this.createSecurityGroup(); this.password = new password_1.Password(`${this.name}-database-password`, { value: args.password }, { parent: this }); this.kmsKeyId = kmsKeyId ? pulumi.output(kmsKeyId) : this.createEncryptionKey().arn; if (enableMonitoring) { this.monitoringRole = this.createMonitoringRole(); } if (snapshotIdentifier) { this.encryptedSnapshotCopy = this.createEncryptedSnapshotCopy(snapshotIdentifier); } this.instance = this.createDatabaseInstance(argsWithDefaults); if (replicaConfigs?.size) { this.replicas = []; let previous = this.instance; for (const [name, config] of replicaConfigs) { this.replicas.push(this.createDatabaseReplica(name, config, { dependsOn: [previous] })); previous = this.replicas.at(-1).instance; } } if (enableSSMConnect) { this.ec2SSMConnect = this.createEc2SSMConnect(ssmConnectConfig); } this.registerOutputs(); } createSubnetGroup() { return new aws.rds.SubnetGroup(`${this.name}-subnet-group`, { subnetIds: this.vpc.isolatedSubnetIds, tags: common_tags_1.commonTags, }, { parent: this }); } createSecurityGroup() { return new aws.ec2.SecurityGroup(`${this.name}-security-group`, { vpcId: this.vpc.vpcId, ingress: [ { protocol: 'tcp', fromPort: 5432, toPort: 5432, cidrBlocks: [this.vpc.vpc.cidrBlock], }, ], tags: common_tags_1.commonTags, }, { parent: this }); } createEncryptionKey() { return new aws.kms.Key(`${this.name}-rds-key`, { description: `${this.name} RDS encryption key`, customerMasterKeySpec: 'SYMMETRIC_DEFAULT', isEnabled: true, keyUsage: 'ENCRYPT_DECRYPT', multiRegion: false, enableKeyRotation: true, tags: common_tags_1.commonTags, }, { parent: this }); } 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', }, }, ], }, }, { parent: this }); new aws.iam.RolePolicyAttachment(`${this.name}-rds-monitoring-role-attachment`, { role: monitoringRole.name, policyArn: 'arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole', }, { parent: this }); return monitoringRole; } createEncryptedSnapshotCopy(snapshotIdentifier) { const sourceDbSnapshotIdentifier = pulumi .output(snapshotIdentifier) .apply(snapshotIdentifier => aws.rds.getSnapshot({ dbSnapshotIdentifier: snapshotIdentifier, })).dbSnapshotArn; return new aws.rds.SnapshotCopy(`${this.name}-encrypted-snapshot-copy`, { sourceDbSnapshotIdentifier, targetDbSnapshotIdentifier: pulumi.interpolate `${snapshotIdentifier}-encrypted-copy`, kmsKeyId: this.kmsKeyId, }, { parent: this }); } createDatabaseReplica(name, config, opts = {}) { const { enableMonitoring, monitoringRole, ...args } = config; const resolvedMonitoringRole = enableMonitoring ? monitoringRole || this.monitoringRole : undefined; const replica = new database_replica_1.DatabaseReplica(name, { replicateSourceDb: this.instance.identifier.apply(id => id), dbSecurityGroup: this.dbSecurityGroup, monitoringRole: resolvedMonitoringRole, ...args, }, { ...opts, parent: this }); return replica; } createEc2SSMConnect(config = {}) { return new ec2_ssm_connect_1.Ec2SSMConnect(`${this.name}-ssm-connect`, { vpc: this.vpc, ...config, }, { parent: this }); } createDatabaseInstance(args) { const stack = pulumi.getStack(); const monitoringOptions = args.enableMonitoring && this.monitoringRole ? { monitoringInterval: 60, monitoringRoleArn: this.monitoringRole.arn, performanceInsightsEnabled: true, performanceInsightsRetentionPeriod: 7, } : {}; const instance = new aws.rds.Instance(`${this.name}-rds`, { identifierPrefix: `${this.name}-`, engine: 'postgres', engineVersion: args.engineVersion, instanceClass: args.instanceClass, dbName: args.dbName, username: args.username, password: this.password.value, dbSubnetGroupName: this.dbSubnetGroup.name, vpcSecurityGroupIds: [this.dbSecurityGroup.id], 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, skipFinalSnapshot: args.skipFinalSnapshot, maintenanceWindow: 'Mon:07:00-Mon:07:30', finalSnapshotIdentifier: `${this.name}-final-snapshot-${stack}`, backupWindow: '06:00-06:30', backupRetentionPeriod: 14, caCertIdentifier: 'rds-ca-rsa2048-g1', parameterGroupName: args.parameterGroupName, snapshotIdentifier: this.encryptedSnapshotCopy?.targetDbSnapshotIdentifier, ...monitoringOptions, tags: { ...common_tags_1.commonTags, ...args.tags }, }, { parent: this, dependsOn: [this.password] }); return instance; } } exports.Database = Database;