1- import { aws_lambda as lambda } from "aws-cdk-lib" ;
1+ import { aws_lambda as lambda , CustomResource } from "aws-cdk-lib" ;
22
33export type CustomLambdaFunctionProps = lambda . FunctionProps | any ;
44export const DEFAULT_PGSTAC_VERSION = "0.9.5" ;
@@ -15,17 +15,88 @@ export const DEFAULT_PGSTAC_VERSION = "0.9.5";
1515export function resolveLambdaCode (
1616 userCode ?: lambda . Code ,
1717 dockerBuildPath ?: string ,
18- dockerBuildOptions ?: lambda . DockerBuildAssetOptions
18+ dockerBuildOptions ?: lambda . DockerBuildAssetOptions ,
1919) : lambda . Code {
2020 if ( userCode ) {
2121 return userCode ;
2222 }
2323
2424 if ( ! dockerBuildPath || ! dockerBuildOptions ) {
2525 throw new Error (
26- "dockerBuildPath and dockerBuildOptions are required when no custom code is provided"
26+ "dockerBuildPath and dockerBuildOptions are required when no custom code is provided" ,
2727 ) ;
2828 }
2929
3030 return lambda . Code . fromDockerBuild ( dockerBuildPath , dockerBuildOptions ) ;
3131}
32+
33+ /**
34+ * Type guard to check if a value has the secretBootstrapper property.
35+ *
36+ * This is used to detect PgStacDatabase constructs with PgBouncer enabled,
37+ * which expose a secretBootstrapper CustomResource that completes after
38+ * the database secret is updated with PgBouncer connection information.
39+ *
40+ * @param value - Value to check
41+ * @returns true if value has a defined secretBootstrapper property
42+ */
43+ function hasSecretBootstrapper (
44+ value : any ,
45+ ) : value is { secretBootstrapper : CustomResource } {
46+ return (
47+ value &&
48+ typeof value === "object" &&
49+ "secretBootstrapper" in value &&
50+ value . secretBootstrapper !== undefined
51+ ) ;
52+ }
53+
54+ /**
55+ * Extracts database dependencies from a database construct if available.
56+ *
57+ * For PgStacDatabase with PgBouncer enabled, returns the secretBootstrapper
58+ * CustomResource which ensures the database secret is fully initialized before
59+ * dependent resources are created.
60+ *
61+ * This is critical for SnapStart Lambda functions, as the snapshot must not
62+ * be created until the secret contains the correct connection information.
63+ *
64+ * @param db - Database construct (may be PgStacDatabase, IDatabaseInstance, etc.)
65+ * @returns Array of CustomResources to depend on (empty if none available)
66+ */
67+ export function extractDatabaseDependencies ( db : any ) : CustomResource [ ] {
68+ if ( hasSecretBootstrapper ( db ) ) {
69+ return [ db . secretBootstrapper ] ;
70+ }
71+ return [ ] ;
72+ }
73+
74+ /**
75+ * Creates a Lambda version with dependencies for SnapStart.
76+ *
77+ * When SnapStart is enabled, the version creation triggers snapshot creation.
78+ * Dependencies ensure the snapshot isn't created until prerequisites are met,
79+ * such as database secrets being fully initialized.
80+ *
81+ * This prevents race conditions where the SnapStart snapshot might capture
82+ * incorrect or incomplete configuration.
83+ *
84+ * @param lambdaFunction - Lambda function to create a version from
85+ * @param dependencies - Array of resources to depend on (pass empty array if none)
86+ * @returns Lambda version with dependencies applied
87+ */
88+ export function createLambdaVersionWithDependencies (
89+ lambdaFunction : lambda . Function ,
90+ dependencies : CustomResource [ ] ,
91+ ) : lambda . Version {
92+ const version = lambdaFunction . currentVersion ;
93+
94+ // Add dependencies to the version resource to ensure proper ordering
95+ if ( dependencies && dependencies . length > 0 ) {
96+ dependencies . forEach ( ( dep ) => {
97+ version . node . addDependency ( dep ) ;
98+ } ) ;
99+ }
100+
101+ return version ;
102+ }
0 commit comments