Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

LiquibaseRDS

A CDK construct for running Liquibase migrations against Amazon RDS instances and clusters using AWS CodeBuild.

Features

  • Universal RDS Support: Works with any RDS instance or Aurora cluster
  • Flexible Commands: Execute any Liquibase command (update, rollback, validate, etc.)
  • Secure: Uses IAM roles and VPC security groups for secure database access
  • Configurable: Customizable Docker images, timeouts, and environment variables
  • Monitored: Built-in CloudWatch logging with configurable retention
  • Multi-language: Available in TypeScript, Python, Java, and C#

Quick Start

Installation

Note: This construct is currently in development. Publishing to package managers is disabled until the first stable release.

For now, you can use this construct by:

  1. Cloning the repository
  2. Building locally with npm run build
  3. Installing as a local dependency
git clone https://github.com/alest314/LiquibaseRDS.git
cd LiquibaseRDS
npm install
npm run build

Then in your CDK project:

npm install /path/to/LiquibaseRDS

Basic Usage

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';// Assume you have an existing RDS instance and VPCdeclareconstdatabase: rds.DatabaseInstance;declareconstvpc: ec2.Vpc;newLiquibaseRDS(this,'MyLiquibaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,
vpc,});

Architecture

The construct creates:

  1. CodeBuild Project: Runs Liquibase commands using the official Docker image
  2. IAM Role: Provides necessary permissions for RDS access and S3 operations
  3. S3 Assets: Uploads your changelog files to S3 for CodeBuild access
  4. CloudWatch Logs: Captures execution logs (optional)
  5. Security Groups: Manages network access between CodeBuild and RDS

Configuration Options

Required Properties

PropertyTypeDescription
rdsInstancerds.IDatabaseInstance | rds.IDatabaseClusterThe RDS instance or cluster to run migrations against
liquibaseCommandstringThe Liquibase command to execute (e.g., 'update', 'rollback')
changelogPathstringLocal path to the directory containing changelog files

Optional Properties

PropertyTypeDefaultDescription
databaseUsernamestring'admin'Database username for connection
databasePasswordstring-Database password (ARN for Secrets Manager)
databaseNamestring-Specific database name to connect to
databasePortnumber5432Database port number
vpcec2.IVpc-VPC for CodeBuild execution
subnetsec2.SubnetSelection-Subnets for CodeBuild
securityGroupsec2.ISecurityGroup[]-Security groups for CodeBuild
liquibaseImagestring'liquibase/liquibase:latest'Docker image to use
additionalArgsstring[][]Additional Liquibase arguments
environmentVariablesobject{}Custom environment variables
timeoutDurationDuration.hours(1)CodeBuild timeout
enableLoggingbooleantrueEnable CloudWatch logging
logRetentionRetentionDaysONE_WEEKLog retention period

Examples

PostgreSQL with Secrets Manager

import{LiquibaseRDS}from'LiquibaseRDS';import*asrdsfrom'aws-cdk-lib/aws-rds';import*asec2from'aws-cdk-lib/aws-ec2';import{Duration}from'aws-cdk-lib';// Create RDS instance with Secrets Managerconstdatabase=newrds.DatabaseInstance(this,'Database',{engine: rds.DatabaseInstanceEngine.postgres({version: rds.PostgresEngineVersion.VER_13_13,}),instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MICRO),
vpc,credentials: rds.Credentials.fromGeneratedSecret('admin'),databaseName: 'myapp',});// Run Liquibase migrationsnewLiquibaseRDS(this,'DatabaseMigration',{rdsInstance: database,liquibaseCommand: 'update',changelogPath: './database/migrations',databaseUsername: 'admin',databasePassword: database.secret?.secretArn,databaseName: 'myapp',databasePort: 5432,
vpc,subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},timeout: Duration.minutes(30),additionalArgs: ['--log-level=INFO'],});

Aurora Cluster with Custom Configuration

// Aurora PostgreSQL clusterconstcluster=newrds.DatabaseCluster(this,'Cluster',{engine: rds.DatabaseClusterEngine.auroraPostgres({version: rds.AuroraPostgresEngineVersion.VER_13_7,}),instanceProps: {instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3,ec2.InstanceSize.MEDIUM),
vpc,},credentials: rds.Credentials.fromGeneratedSecret('admin'),});// Validation run with custom Liquibase versionnewLiquibaseRDS(this,'DatabaseValidation',{rdsInstance: cluster,liquibaseCommand: 'validate',changelogPath: './database/changelogs',databaseUsername: 'admin',databasePassword: cluster.secret?.secretArn,
vpc,liquibaseImage: 'liquibase/liquibase:4.24',environmentVariables: {LIQUIBASE_HUB_MODE: {value: 'off'},JAVA_OPTS: {value: '-Xmx1g'},},enableLogging: true,});

MySQL with Rollback

constmysqlDb=newrds.DatabaseInstance(this,'MySQLDB',{engine: rds.DatabaseInstanceEngine.mysql({version: rds.MysqlEngineVersion.VER_8_0,}),// ... other configuration});newLiquibaseRDS(this,'DatabaseRollback',{rdsInstance: mysqlDb,liquibaseCommand: 'rollback-count',changelogPath: './database/changelogs',databasePort: 3306,additionalArgs: ['1'],// Rollback 1 changeset// ... other configuration});

Changelog Structure

Your changelog directory should contain Liquibase changelog files. Here's an example structure:

changelogs/
├── changelog.xml # Master changelog
├── 001-create-users-table.xml
├── 002-create-posts-table.xml
└── 003-add-foreign-keys.xml

Example master changelog (changelog.xml):

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.0.xsd">
<includefile="001-create-users-table.xml"relativeToChangelogFile="true"/>
<includefile="002-create-posts-table.xml"relativeToChangelogFile="true"/>
<includefile="003-add-foreign-keys.xml"relativeToChangelogFile="true"/>
</databaseChangeLog>

Security Considerations

Database Credentials

  • Recommended: Use AWS Secrets Manager to store database credentials
  • Pass the secret ARN to the databasePassword property
  • The construct automatically grants the CodeBuild role permission to read the secret
// Using Secrets ManagerdatabasePassword: database.secret?.secretArn,

Network Security

  • Deploy CodeBuild in private subnets with NAT Gateway access
  • Use security groups to restrict database access
  • The construct automatically creates security group rules for RDS connectivity
// Create security group for CodeBuildconstcodeBuildSG=newec2.SecurityGroup(this,'CodeBuildSG',{ vpc });// Allow CodeBuild to connect to RDSdatabase.connections.allowFrom(codeBuildSG,ec2.Port.tcp(5432));newLiquibaseRDS(this,'Migration',{// ... other propssecurityGroups: [codeBuildSG],subnets: {subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,},});

Monitoring and Logging

The construct provides built-in CloudWatch integration:

  • Execution Logs: All Liquibase output is captured in CloudWatch Logs
  • Build Status: Monitor CodeBuild execution status
  • Custom Metrics: Add custom CloudWatch metrics as needed
newLiquibaseRDS(this,'Migration',{// ... other propsenableLogging: true,logRetention: logs.RetentionDays.ONE_MONTH,});

Common Liquibase Commands

CommandDescription
updateApply all pending changesets
validateValidate changelog syntax
statusShow pending changesets
rollback-countRollback specified number of changesets
rollback-to-tagRollback to a specific tag
generate-changelogGenerate changelog from existing database

Troubleshooting

Common Issues

  1. Connection Timeout: Ensure CodeBuild can reach RDS through security groups and NACLs
  2. Permission Denied: Verify IAM roles have necessary RDS and S3 permissions
  3. Changelog Not Found: Check that changelog files are in the specified path
  4. Database Connection: Verify database credentials and endpoint configuration

Debug Mode

Enable debug logging for troubleshooting:

newLiquibaseRDS(this,'Migration',{// ... other propsadditionalArgs: ['--log-level=DEBUG'],environmentVariables: {LIQUIBASE_LOG_LEVEL: {value: 'DEBUG'},},});

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by AlexTech314

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages