Skip to content

thundra-io/thundra-cdk-rds-initializer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@thundra/cdk-rds-initializer

RDS Database User Initializer and Script Runner Construct for AWS CDK

This package provides Constructs for creating database user & running database script which can be used in RDS.

This package automatically create database user and run database script.


About CDK Compatibility

@thundra/cdk-rds-initializer is currently only supported to CDK v1.

About RDS Compatibility

@thundra/cdk-rds-initializer is currently only supported to MySQL.

Installation

npm

npm i @thundra/cdk-rds-initializer

Example

import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as rds from '@aws-cdk/aws-rds';
import * as logs from '@aws-cdk/aws-logs';
import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
import * as thundra from '@thundra/cdk-rds-initializer';

    //... 
    const vpc = ec2.Vpc.fromLookup(this, `sample-vpc`, { isDefault: true });

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Security Groups
    //
    const sampleDatabaseSecurityGroup = new ec2.SecurityGroup(this, `sample-database-sg`, {
      vpc: vpc,
      securityGroupName: `sample-database-sg`,
      description: `sample-database-sg`,
      allowAllOutbound: true
    });
    cdk.Aspects.of(sampleDatabaseSecurityGroup).add(
            new cdk.Tag(
                    'Name',
                    `sample-database-sg`
            )
    );
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Secret Manager
    //
    const sampleDatabaseAdminUserSecret = new secretsmanager.Secret(this, `sample-database-admin-secret`, {
      secretName: `sample-database-admin-secret`,
      generateSecretString: {
        secretStringTemplate: JSON.stringify({
          'username': 'sample_db_admin',
        }),
        excludePunctuation: true,
        includeSpace: false,
        generateStringKey: 'password'
      }
    });
    const sampleDatabaseRWUserSecret = new secretsmanager.Secret(this, `sample-database-rw-user-secret`, {
      secretName: `sample-database-rw-user-secret`,
      generateSecretString: {
        secretStringTemplate: JSON.stringify({
          'username': 'sample_rw_user'
        }),
        excludePunctuation: true,
        includeSpace: false,
        generateStringKey: 'password'
      }
    });
    const sampleDatabaseROUserSecret = new secretsmanager.Secret(this, `sample-database-ro-user-secret`, {
      secretName: `sample-database-ro-user-secret`,
      generateSecretString: {
        secretStringTemplate: JSON.stringify({
          'username': 'sample_ro_user'
        }),
        excludePunctuation: true,
        includeSpace: false,
        generateStringKey: 'password'
      }
    });
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // DatabaseCluster
    //
    const sampleDatabaseCluster = new rds.DatabaseCluster(this, `sample-database`, {
      engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_2_10_1 }),
      instanceProps: {
        vpc: vpc,
        autoMinorVersionUpgrade: true,
        deleteAutomatedBackups: false,
        instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MEDIUM),
        publiclyAccessible: true,
        securityGroups: [sampleDatabaseSecurityGroup],
        vpcSubnets: {
          subnetType: ec2.SubnetType.PUBLIC
        }
      },
      backtrackWindow: cdk.Duration.hours(12),
      backup: {
        retention: cdk.Duration.days(7),
        preferredWindow: '01:00-02:00'
      },
      cloudwatchLogsExports: ['error', 'general', 'slowquery', 'audit'],
      cloudwatchLogsRetention: logs.RetentionDays.ONE_DAY,
      clusterIdentifier: `sample-database`,
      copyTagsToSnapshot: true,
      credentials: rds.Credentials.fromSecret(sampleDatabaseAdminUserSecret, "sample_db_admin"),
      defaultDatabaseName: 'sampledb',
      deletionProtection: false,
      iamAuthentication: true,
      instanceIdentifierBase: `sample-database-instance-`,
      instances: 1,
      monitoringInterval: cdk.Duration.seconds(60),
      port: 3306,
      preferredMaintenanceWindow: 'Sun:03:00-Sun:03:30',
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      storageEncrypted: true
    });
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Database Initializer
    //
    const userInitializer = new thundra.DatabaseUserInitializer(this, 'sample-database-user-initializer', {
        databaseAdminUserSecret: sampleDatabaseAdminUserSecret,
        databaseEngine: thundra.DatabaseEngine.MySQL,
        databaseUsers: [
            {
                username: 'sample_rw_user',
                grants: [thundra.DatabaseUserGrant.ALL_PRIVILEGES],
                secret: sampleDatabaseRWUserSecret
            },
            {
                username: 'sample_ro_user',
                grants: [thundra.DatabaseUserGrant.SELECT],
                secret: sampleDatabaseROUserSecret
            }
        ]
    });
    userInitializer.node.addDependency(sampleDatabaseCluster);
    
    const scriptRunner = new thundra.DatabaseScriptRunner(this, 'sample-database-script-runner', {
      databaseAdminUserSecret: sampleDatabaseAdminUserSecret,
      databaseEngine: thundra.DatabaseEngine.MySQL,
      script: 'select 1 from dual;'
    });
    scriptRunner.node.addDependency(sampleDatabaseCluster);
    // ...

Constructs

DatabaseScriptRunner

Initializer

new DatabaseScriptRunner(scope: cdk.Construct, id: string, props: DatabaseScriptRunnerProps);

Construct Props

/**
 * Base properties for database initializer resources.
 */
export interface DatabaseInitializerProps {
    /**
     * Prefix to be used to name custom resources.
     */
    readonly prefix?: string;
    /**
     * Postfix to be used to name custom resources.
     */
    readonly postfix?: string;
    /**
     * Secret to be used for database connection.
     * Secret must contain database information.
     */
    readonly databaseAdminUserSecret: secretsmanager.ISecret;
    /**
     * Vpc where custom resource lambda will be deployed.
     * If database is in vpc, database vpc should be given.
     */
    readonly vpc?: ec2.IVpc;
    /**
     * Subnet where custom resource lambda will be deployed.
     * Must be the same as the database subnet.
     */
    readonly vpcSubnets?: ec2.SubnetSelection;
    /**
     * SecurityGroup that custom resource lambda will use.
     * Security group must have internet access as lambda  needs access to secret manager.
     */
    readonly securityGroups?: ec2.ISecurityGroup[];
    /**
     * Database engine type. Like MySQL or PostgreSQL.
     */
    readonly databaseEngine: DatabaseEngine;
}

/**
 * Properties to run a database script on AWS RDS
 */
export interface DatabaseScriptRunnerProps extends DatabaseInitializerProps {
    /**
     * Script to run in database.
     */
    readonly script: string;
}

DatabaseUserInitializer

Initializer

new DatabaseUserInitializer(scope: cdk.Construct, id: string, props: DatabaseUserInitializerProps);

Construct Props

/**
 * Base properties for database initializer resources.
 */
export interface DatabaseInitializerProps {
    /**
     * Prefix to be used to name custom resources.
     */
    readonly prefix?: string;
    /**
     * Postfix to be used to name custom resources.
     */
    readonly postfix?: string;
    /**
     * Secret to be used for database connection.
     * Secret must contain database information.
     */
    readonly databaseAdminUserSecret: secretsmanager.ISecret;
    /**
     * Vpc where custom resource lambda will be deployed.
     * If database is in vpc, database vpc should be given.
     */
    readonly vpc?: ec2.IVpc;
    /**
     * Subnet where custom resource lambda will be deployed.
     * Must be the same as the database subnet.
     */
    readonly vpcSubnets?: ec2.SubnetSelection;
    /**
     * SecurityGroup that custom resource lambda will use.
     * Security group must have internet access as lambda  needs access to secret manager.
     */
    readonly securityGroups?: ec2.ISecurityGroup[];
    /**
     * Database engine type. Like MySQL or PostgreSQL.
     */
    readonly databaseEngine: DatabaseEngine;
}

/**
 * Properties to create a database user on AWS RDS
 */
export interface DatabaseUserInitializerProps extends DatabaseInitializerProps {
    /**
     * List of users to be creating on AWS RDS
     */
    readonly databaseUsers: (User | IAMUser)[];
}

Licensing

@thundra/cdk-rds-initializer is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •