|
| 1 | +import { join } from 'path'; |
| 2 | +import * as cdk from 'aws-cdk-lib'; |
| 3 | +import * as rds from 'aws-cdk-lib/aws-rds'; |
| 4 | +import * as ec2 from 'aws-cdk-lib/aws-ec2'; |
| 5 | +import * as lambda from 'aws-cdk-lib/aws-lambda'; |
| 6 | +import { RustFunction } from '@cdklabs/aws-lambda-rust' |
| 7 | + |
| 8 | +class LambdaRDSStack extends cdk.Stack { |
| 9 | + constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { |
| 10 | + super(scope, id, props); |
| 11 | + |
| 12 | + // Create a VPC |
| 13 | + const vpc = new ec2.Vpc(this, 'VPC'); |
| 14 | + |
| 15 | + // Admin DB user |
| 16 | + const DB_ADMIN_USERNAME = 'root'; |
| 17 | + const DB_USERNAME = 'lambda'; |
| 18 | + |
| 19 | + // Lambda DB user |
| 20 | + const DB_NAME = 'foo'; |
| 21 | + |
| 22 | + // Create an RDS instance |
| 23 | + const db = new rds.DatabaseInstance(this, 'Postgres', { |
| 24 | + engine: rds.DatabaseInstanceEngine.POSTGRES, |
| 25 | + vpc, |
| 26 | + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), |
| 27 | + credentials: rds.Credentials.fromGeneratedSecret(DB_ADMIN_USERNAME), |
| 28 | + iamAuthentication: true, |
| 29 | + publiclyAccessible: true, |
| 30 | + databaseName: DB_NAME, |
| 31 | + deleteAutomatedBackups: true, |
| 32 | + removalPolicy: cdk.RemovalPolicy.DESTROY |
| 33 | + }) |
| 34 | + |
| 35 | + db.connections.allowFromAnyIpv4(ec2.Port.allTcp()) |
| 36 | + |
| 37 | + // RDS SSL Cert Lambda Layer alternative to loading the certificates at compile time |
| 38 | + /* |
| 39 | + const certLayer = new lambda.LayerVersion(this, 'CertLayer', { |
| 40 | + description: 'SSL Certificate Layer', |
| 41 | + code: lambda.Code.fromAsset('certs'), |
| 42 | + compatibleArchitectures: [lambda.Architecture.X86_64, lambda.Architecture.ARM_64] |
| 43 | + }); |
| 44 | + */ |
| 45 | + |
| 46 | + const lambdaSG = new ec2.SecurityGroup(this, 'LambdaSG', { |
| 47 | + securityGroupName: 'LambdaSG', |
| 48 | + allowAllOutbound: true, |
| 49 | + vpc: vpc, |
| 50 | + }) |
| 51 | + // create a rust lambda function |
| 52 | + const rustLambdaFunction = new RustFunction(this, "lambda", { |
| 53 | + entry: join(__dirname, '..', 'lambda'), |
| 54 | + vpc: vpc, |
| 55 | + securityGroups: [lambdaSG], |
| 56 | + environment: { |
| 57 | + DB_HOSTNAME: db.dbInstanceEndpointAddress, |
| 58 | + DB_PORT: db.dbInstanceEndpointPort, |
| 59 | + DB_NAME: DB_NAME, |
| 60 | + DB_USERNAME: DB_USERNAME, |
| 61 | + }, |
| 62 | + bundling: { |
| 63 | + forceDockerBundling: true, |
| 64 | + }, |
| 65 | + runtime: lambda.Runtime.PROVIDED_AL2023, |
| 66 | + timeout: cdk.Duration.seconds(60), |
| 67 | + }); |
| 68 | + |
| 69 | + // MySQL |
| 70 | + /* |
| 71 | + CREATE USER 'lambda' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'; |
| 72 | + GRANT ALL PRIVILEGES ON foo.* TO 'lambda'; |
| 73 | + ALTER USER 'lambda' REQUIRE SSL; |
| 74 | + */ |
| 75 | + |
| 76 | + // Postgres |
| 77 | + /* |
| 78 | + CREATE USER db_userx; |
| 79 | + GRANT rds_iam TO db_userx; |
| 80 | + */ |
| 81 | + db.grantConnect(rustLambdaFunction, DB_USERNAME); |
| 82 | + db.connections.allowDefaultPortFrom(rustLambdaFunction); |
| 83 | + |
| 84 | + /* |
| 85 | + Dev Instance for initialising the datbase with the above commands |
| 86 | + */ |
| 87 | + const devInstance = new ec2.Instance(this, 'dev', { |
| 88 | + vpc, |
| 89 | + vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }), |
| 90 | + machineImage: ec2.MachineImage.latestAmazonLinux2023(), |
| 91 | + instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM) |
| 92 | + }) |
| 93 | + db.grantConnect(devInstance, DB_ADMIN_USERNAME); |
| 94 | + db.grantConnect(devInstance, DB_USERNAME); |
| 95 | + db.connections.allowDefaultPortFrom(devInstance); |
| 96 | + |
| 97 | + // Output the Lambda function ARN |
| 98 | + new cdk.CfnOutput(this, 'LambdaFunctionConsole', { |
| 99 | + value: `https://${this.region}.console.aws.amazon.com/lambda/home?region=${this.region}#/functions/${rustLambdaFunction.functionName}?tab=testing` |
| 100 | + }); |
| 101 | + } |
| 102 | +} |
| 103 | + |
| 104 | +const app = new cdk.App(); |
| 105 | +new LambdaRDSStack(app, 'LambdaRDSStack'); |
0 commit comments