-
-
Save lukehoban/5c168258b641368dcccc7810dc454ca9 to your computer and use it in GitHub Desktop.
import * as pulumi from "@pulumi/pulumi"; | |
import * as aws from "@pulumi/aws"; | |
import * as awsx from "@pulumi/awsx"; | |
import * as random from "@pulumi/random"; | |
// Construct a VPC | |
const vpc = new awsx.ec2.Vpc("vpc"); | |
// Create an Aurora Serverless MySQL database | |
const dbsubnet = new aws.rds.SubnetGroup("dbsubnet", { | |
subnetIds: vpc.privateSubnetIds, | |
}); | |
const dbpassword = new random.RandomString("password", { | |
length: 20, | |
}); | |
const db = new aws.rds.Cluster("db", { | |
engine: "aurora", | |
engineMode: "serverless", | |
engineVersion: "5.6.10a", | |
dbSubnetGroupName: dbsubnet.name, | |
masterUsername: "pulumi", | |
masterPassword: dbpassword.result, | |
}); | |
// A function to run to connect to our database. | |
function queryDatabase(): Promise<void> { | |
return new Promise((resolve, reject) => { | |
var mysql = require('mysql'); | |
var connection = mysql.createConnection({ | |
host : db.endpoint.get(), | |
user : db.masterUsername.get(), | |
password : db.masterPassword.get(), | |
database : db.databaseName.get(), | |
}); | |
connection.connect(); | |
console.log("querying...") | |
connection.query('SELECT 1 + 1 AS solution', function (error: any, results: any, fields: any) { | |
if (error) { reject(error); return } | |
console.log('The solution is: ', results[0].solution); | |
resolve(); | |
}); | |
connection.end(); | |
}); | |
} | |
// Create a Lambda within the VPC to access the Aurora DB and run the code above. | |
const lambda = new aws.lambda.CallbackFunction("lambda", { | |
vpcConfig: { | |
securityGroupIds: db.vpcSecurityGroupIds, | |
subnetIds: vpc.privateSubnetIds, | |
}, | |
policies: [aws.iam.AWSLambdaVPCAccessExecutionRole, aws.iam.AWSLambdaFullAccess, aws.iam.AmazonRDSFullAccess], | |
callback: async(ev) => { | |
console.log(ev); | |
await queryDatabase(); | |
}, | |
}); | |
// Export the Function ARN | |
export const functionArn = lambda.arn; | |
// Invoke this with: | |
// $ aws lambda invoke --function-name $(pulumi stack output functionArn) out.txt | |
// $ pulumi logs -f |
policies
seems to have changed to:
policies: [
aws.iam.ManagedPolicies.AWSLambdaVPCAccessExecutionRole,
aws.iam.ManagedPolicies.AWSLambdaFullAccess,
aws.iam.ManagedPolicies.AmazonRDSFullAccess,
],
Also, seems like db.databaseName.get()
returns undefined
.
The one issue I am running into here with this example is the inconsistent timeouts of connections to RDS. Based on some research it looks like the connection needs to be outside the handler, anyway to do that with CallbackFunction resource?
Has anyone been able to solve this?
Luke, I must have missed a step. Any chance you know how to resolve the following MODULE_NOT_FOUND runtime error that is reported during the execution of the Lambda function? It appears that the mysql node module is not available from within the AWS Lambda runtime environment.
PS: I've used the above code while following the related YouTube live coding session: https://www.youtube.com/watch?v=yMhJgkKCQGM
$ pulumi version
v3.28.0
PS C:> cmd ?
Microsoft Windows [Version 10.0.19043.1586]
(c) Microsoft Corporation. All rights reserved.
$ npm -v mysql
6.14.15
$ npm -v
6.14.15
$ node -v
v14.18.0
ERROR Invoke Error {"errorType":"Error","errorMessage":"Cannot find module 'm
ysql'\nRequire stack:\n- /var/task/__index.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js","code":"MODULE_NOT_FOUND","requireStack":["/var/task/__index.js","/var/runtime/UserFunction.js","/var/runt
ime/index.js"],"stack":["Error: Cannot find module 'mysql'","Require stack:","- /var/task/__index.js","- /var/runtime/UserFunction.js","- /var/runtime/index.js"," at Function.Module._resolveFilename (interna
l/modules/cjs/loader.js:815:15)"," at Function.Module._load (internal/modules/cjs/loader.js:667:27)"," at Module.require (internal/modules/cjs/loader.js:887:19)"," at require (internal/modules/cjs/help
ers.js:74:18)"," at /var/task/__index.js:82:21"," at new Promise (<anonymous>)"," at Object.<anonymous> (/var/task/__index.js:81:12)"," at Object.__queryDatabase [as queryDatabase] (/var/task/__inde
x.js:104:34)"," at /var/task/__index.js:113:15"," at Generator.next (<anonymous>)"]}
The one issue I am running into here with this example is the inconsistent timeouts of connections to RDS. Based on some research it looks like the connection needs to be outside the handler, anyway to do that with CallbackFunction resource?