@@ -4,38 +4,78 @@ const response = require('cfn-response');
44
55const secretsManager = new SecretsManagerClient ( ) ;
66
7+ /**
8+ * Lambda function to set up PostgreSQL with AWS Lambda integration
9+ * This function is called by a CloudFormation Custom Resource
10+ */
711exports . handler = async ( event , context ) => {
8- console . log ( 'Event:' , JSON . stringify ( event , null , 2 ) ) ;
12+ console . log ( 'Event received:' , JSON . stringify ( event , null , 2 ) ) ;
13+ console . log ( 'Context:' , JSON . stringify ( {
14+ functionName : context . functionName ,
15+ functionVersion : context . functionVersion ,
16+ awsRequestId : context . awsRequestId ,
17+ logGroupName : context . logGroupName ,
18+ logStreamName : context . logStreamName ,
19+ remainingTimeMs : context . getRemainingTimeInMillis ( )
20+ } , null , 2 ) ) ;
921
22+ // Handle delete event
1023 if ( event . RequestType === 'Delete' ) {
24+ console . log ( 'Delete request received - no action needed for cleanup' ) ;
1125 return response . send ( event , context , response . SUCCESS , { } , 'postgres-setup-delete' ) ;
1226 }
1327
1428 try {
29+ // Get environment variables
1530 const { DB_SECRET_ARN , DB_NAME , POSTGRES_FUNCTION_NAME , AWS_REGION } = process . env ;
31+ console . log ( 'Environment variables:' , JSON . stringify ( {
32+ DB_SECRET_ARN ,
33+ DB_NAME ,
34+ POSTGRES_FUNCTION_NAME ,
35+ AWS_REGION
36+ } , null , 2 ) ) ;
1637
17- // Get database credentials
38+ // Get database credentials from Secrets Manager
39+ console . log ( `Retrieving secret from ${ DB_SECRET_ARN } ` ) ;
1840 const secretResponse = await secretsManager . send (
1941 new GetSecretValueCommand ( { SecretId : DB_SECRET_ARN } )
2042 ) ;
43+
44+ if ( ! secretResponse . SecretString ) {
45+ throw new Error ( 'Secret string is empty or undefined' ) ;
46+ }
47+
2148 const secret = JSON . parse ( secretResponse . SecretString ) ;
49+ console . log ( 'Secret retrieved successfully. Host:' , secret . host ) ;
2250
23- // Connect to PostgreSQL
51+ // Create PostgreSQL client
52+ console . log ( `Connecting to PostgreSQL database ${ DB_NAME } at ${ secret . host } :${ secret . port } ` ) ;
2453 const client = new Client ( {
2554 host : secret . host ,
2655 port : secret . port ,
2756 database : DB_NAME ,
2857 user : secret . username ,
2958 password : secret . password ,
30- ssl : { rejectUnauthorized : false }
59+ ssl : { rejectUnauthorized : false } ,
60+ // Add connection timeout for better error handling
61+ connectionTimeoutMillis : 10000
3162 } ) ;
3263
64+ // Connect to the database
65+ console . log ( 'Attempting to connect to PostgreSQL...' ) ;
3366 await client . connect ( ) ;
67+ console . log ( 'Successfully connected to PostgreSQL' ) ;
3468
35- // Execute setup SQL
69+ // Prepare setup SQL
70+ console . log ( 'Preparing SQL setup script' ) ;
71+ const lambdaArn = `aws_commons.create_lambda_function_arn('${ POSTGRES_FUNCTION_NAME } ', '${ AWS_REGION } ')` ;
72+ console . log ( `Using Lambda ARN expression: ${ lambdaArn } ` ) ;
73+
3674 const setupSQL = `
75+ -- Create aws_lambda extension if it doesn't exist
3776 CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;
38-
77+
78+ -- Create function to process data
3979 CREATE OR REPLACE FUNCTION process_data(data JSONB)
4080 RETURNS JSONB AS $$
4181 SELECT payload FROM aws_lambda.invoke(
@@ -45,6 +85,7 @@ exports.handler = async (event, context) => {
4585 );
4686 $$ LANGUAGE SQL;
4787
88+ -- Create function to transform data
4889 CREATE OR REPLACE FUNCTION transform_data(data JSONB)
4990 RETURNS JSONB AS $$
5091 SELECT payload FROM aws_lambda.invoke(
@@ -54,6 +95,7 @@ exports.handler = async (event, context) => {
5495 );
5596 $$ LANGUAGE SQL;
5697
98+ -- Create function to validate data
5799 CREATE OR REPLACE FUNCTION validate_data(data JSONB)
58100 RETURNS JSONB AS $$
59101 SELECT payload FROM aws_lambda.invoke(
@@ -64,18 +106,41 @@ exports.handler = async (event, context) => {
64106 $$ LANGUAGE SQL;
65107 ` ;
66108
67- await client . query ( setupSQL ) ;
109+ // Execute setup SQL
110+ console . log ( 'Executing SQL setup script...' ) ;
111+ const result = await client . query ( setupSQL ) ;
112+ console . log ( 'SQL setup script executed successfully:' , JSON . stringify ( result ) ) ;
113+
114+ // Verify the functions were created
115+ console . log ( 'Verifying SQL functions were created...' ) ;
116+ const verifyResult = await client . query ( `
117+ SELECT proname, proargtypes, prosrc
118+ FROM pg_proc
119+ WHERE proname IN ('process_data', 'transform_data', 'validate_data')
120+ ` ) ;
121+ console . log ( `Found ${ verifyResult . rows . length } functions:` , JSON . stringify ( verifyResult . rows . map ( row => row . proname ) ) ) ;
122+
123+ // Close the database connection
124+ console . log ( 'Closing PostgreSQL connection' ) ;
68125 await client . end ( ) ;
126+ console . log ( 'PostgreSQL connection closed successfully' ) ;
69127
70128 // Send success response
129+ console . log ( 'Sending SUCCESS response to CloudFormation' ) ;
71130 return response . send ( event , context , response . SUCCESS , {
72- Message : 'PostgreSQL setup completed successfully'
131+ Message : 'PostgreSQL setup completed successfully' ,
132+ FunctionsCreated : verifyResult . rows . length ,
133+ LambdaFunction : POSTGRES_FUNCTION_NAME ,
134+ Region : AWS_REGION
73135 } , 'postgres-setup-' + Date . now ( ) ) ;
74136
75137 } catch ( error ) {
76- console . error ( 'Error:' , error ) ;
138+ console . error ( 'Error during PostgreSQL setup:' , error ) ;
139+ console . error ( 'Stack trace:' , error . stack ) ;
77140 return response . send ( event , context , response . FAILED , {
78- Error : error . message
141+ Error : error . message ,
142+ ErrorType : error . name ,
143+ StackTrace : error . stack
79144 } ) ;
80145 }
81146} ;
0 commit comments