in JavaSpringMigration/cdk/src/main/java/com/ilmlf/product/db/schemaManager/FlywayRunner.java [82:161]
public FlywayRunner(Construct scope, String id, FlywayRunnerProps options) {
super(scope, id);
@NotNull ISource sqlFilesAsset = Source.asset(options.migrationScriptsFolderAbsolutePath);
Bucket migrationFilesBucket = new Bucket(this, "MigrationFilesBucket");
BucketDeployment migrationFilesDeployment = BucketDeployment.Builder
.create(this, "DeploySQLMigrationFiles")
.sources(List.of(sqlFilesAsset))
.destinationBucket(migrationFilesBucket)
.build();
/*
* Command for building Java handler inside a container
*/
List<String> packagingInstructions =
Arrays.asList(
"/bin/sh", "-c",
"./gradlew shadowJar -x test" + "&& cp build/libs/flyway-all.jar /asset-output/"
);
BundlingOptions builderOptions =
BundlingOptions.builder()
.command(packagingInstructions)
.image(Runtime.JAVA_11.getBundlingImage())
.build();
Function flywayServiceLambda = new Function(
this,
"runner",
FunctionProps.builder()
.environment(
Map.of(
"S3_BUCKET", migrationFilesBucket.getBucketName(),
"DB_CONNECTION_STRING", String.format("jdbc:mysql://%s/%s", options.databaseInstance.getDbInstanceEndpointAddress(), options.getDatabaseName()),
"DB_SECRET", options.databaseInstance.getSecret().getSecretFullArn()))
.runtime(Runtime.JAVA_11)
.code(
Code.fromAsset(
"../../FlywayLambdaService/",
AssetOptions.builder()
.bundling(builderOptions)
.build()))
.timeout(Duration.minutes(15))
.memorySize(2048)
.handler("com.geekoosh.flyway.FlywayHandler::handleRequest")
.vpc(options.databaseInstance.getVpc())
.securityGroups(options.databaseInstance.getConnections().getSecurityGroups())
.build());
// Let Flyway Lambda get DB creds
options.databaseInstance.getSecret().grantRead(flywayServiceLambda);
// Let Flyway Lambda access the DB
options.databaseInstance.getConnections().allowDefaultPortInternally();
// Let Flyway Lambda access the migration files bucket
migrationFilesBucket.grantRead(flywayServiceLambda);
// Leverage AwsCustomResource to trigger the FlywayLambdaService on asset change
new AwsCustomResource(this, "trigger", AwsCustomResourceProps.builder()
.logRetention(options.logRetention != null ? options.logRetention : RetentionDays.ONE_DAY)
.onUpdate(AwsSdkCall.builder()
.service("Lambda")
.action("invoke")
.physicalResourceId(PhysicalResourceId.of("flywayTrigger"))
.parameters(Map.of(
"FunctionName", flywayServiceLambda.getFunctionName(),
"InvocationType", "RequestResponse",
"Payload", "{" +
"\"flywayRequest\":{\"flywayMethod\": \"migrate\"}," +
" \"assetHash\": \"" + ((Asset) migrationFilesDeployment.getNode().findChild("Asset1")).getAssetHash()+ "\"}"
)).build())
.policy(AwsCustomResourcePolicy.fromStatements(List.of(PolicyStatement.Builder.create()
.actions(List.of("lambda:InvokeFunction"))
.resources(List.of(flywayServiceLambda.getFunctionArn()))
.build())))
.build());
}