Skip to content
This repository has been archived by the owner on Dec 20, 2023. It is now read-only.

Commit

Permalink
Update example to use Aurora Serverless (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
jplock authored Nov 24, 2019
1 parent d0307ed commit 35694c6
Show file tree
Hide file tree
Showing 12 changed files with 573 additions and 918 deletions.
96 changes: 13 additions & 83 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -1,103 +1,33 @@
const https = require('https');

const AWS = require('aws-sdk');
const { Client } = require('pg');

const { default: CERT_DATA } = require('./rds-combined-ca-bundle.pem');

const { SECRET_NAME } = process.env;

/**
* Return a new HTTPS Agent with keep-alives enabled
*
* @return {Agent}
* @see https://github.com/aws/aws-sdk-js/blob/v2.437.0/lib/http/node.js#L141
* @see https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-configuring-maxsockets.html
*/
function getKeepAliveAgent() {
const options = {
keepAlive: true,
rejectUnauthorized: true, // from aws-sdk
maxSockets: 50, // from aws-sdk
};
const agent = new https.Agent(options);
agent.setMaxListeners(0); // from aws-sdk
return agent;
}
const { SECRET_ARN, RESOURCE_ARN, DATABASE_NAME, SCHEMA_NAME } = process.env;

AWS.config.logger = console;

AWS.config.update({
httpOptions: {
agent: getKeepAliveAgent(),
},
});

/**
* Get a secret from Secrets Manager
*
* @param {String} SecretId
* @return {Promise<Object>}
*/
async function getSecret(SecretId) {
const secretsmanager = new AWS.SecretsManager();

const params = {
SecretId,
VersionStage: 'AWSCURRENT',
};

let data;
try {
data = await secretsmanager.getSecretValue(params).promise();
if (data.SecretString) {
data = JSON.parse(data.SecretString);
}
} catch (err) {
console.error(`Unable to get secret ${SecretId}:`, err);
throw err;
}
return data;
}

let SECRET_DATA;

/**
* Postgres Handler
* PostgreSQL Handler
*
* @param {Object} event
* @param {Object} context
* @return {Promise}
*/
// eslint-disable-next-line no-unused-vars
exports.handler = async (event, context) => {
if (!SECRET_DATA) {
SECRET_DATA = await getSecret(SECRET_NAME);
}
const rds = new AWS.RDSDataService();

const config = {
user: SECRET_DATA.username,
password: SECRET_DATA.password,
database: 'postgres',
host: SECRET_DATA.host,
port: SECRET_DATA.port,
// this object will be passed to the TLSSocket constructor
ssl: {
rejectUnauthorized: true,
ca: CERT_DATA,
cert: CERT_DATA,
},
statement_timeout: 5000, // milliseconds
const params = {
resourceArn: RESOURCE_ARN,
secretArn: SECRET_ARN,
sql: 'SELECT NOW()',
database: DATABASE_NAME,
schema: SCHEMA_NAME,
};

const client = new Client(config);
await client.connect();

const res = await client.query('SELECT NOW()');
const response = await rds.executeStatement(params).promise();

const [now] = res.rows || [];
const { records = [] } = response;

await client.end();
const [row] = records || [];

return now;
return row[0].stringValue;
};
10 changes: 3 additions & 7 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,12 @@
"remove": "sls remove -v",
"test": "sls invoke -f rds"
},
"dependencies": {
"pg": "7.12.1"
},
"devDependencies": {
"aws-sdk": "2.521.0",
"raw-loader": "3.1.0",
"serverless": "1.51.0",
"aws-sdk": "2.578.0",
"serverless": "1.58.0",
"serverless-vpc-plugin": "smoketurner/serverless-vpc-plugin#master",
"serverless-webpack": "5.3.1",
"webpack": "4.39.3",
"webpack": "4.41.2",
"webpack-node-externals": "1.7.2"
}
}
432 changes: 0 additions & 432 deletions example/rds-combined-ca-bundle.pem

This file was deleted.

36 changes: 18 additions & 18 deletions example/resources/iam_cf.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
---
Resources:

ExampleLambdaRole:
Type: 'AWS::IAM::Role'
Type: "AWS::IAM::Role"
Properties:
Path: '/${self:service}/${self:provider.stage}/'
RoleName: '${self:service}-${self:provider.stage}-${self:provider.region}-ExampleLambdaRole'
RoleName: "${self:service}-${self:provider.stage}-${self:provider.region}-ExampleLambdaRole"
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: 'lambda.amazonaws.com'
Action: 'sts:AssumeRole'
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: ExampleLambdaPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'secretsmanager:GetSecretValue'
Resource:
'Fn::Join':
- ':'
- - 'arn:aws:secretsmanager'
- Ref: 'AWS::Region'
- Ref: 'AWS::AccountId'
- 'secret:${self:custom.secretName}-*'
Statement:
- Effect: Allow
Action: "secretsmanager:GetSecretValue"
Resource:
Ref: DBSecret
- Effect: Allow
Action:
- "rds-data:BatchExecuteStatement"
- "rds-data:BeginTransaction"
- "rds-data:CommitTransaction"
- "rds-data:ExecuteStatement"
- "rds-data:RollbackTransaction"
Resource: "*"
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole'
- "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
79 changes: 15 additions & 64 deletions example/resources/rds_cf.yml
Original file line number Diff line number Diff line change
@@ -1,61 +1,16 @@
---
Resources:

DBSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Access to Postgres
VpcId:
Ref: VPC
SecurityGroupIngress:
- SourceSecurityGroupId:
Ref: BastionSecurityGroup
Description: Bastion access to Postgres
IpProtocol: tcp
FromPort: 5432
ToPort: 5432
- SourceSecurityGroupId:
Ref: LambdaExecutionSecurityGroup
Description: Lambda access to Postgres
IpProtocol: tcp
FromPort: 5432
ToPort: 5432
Tags:
- Key: Name
Value:
'Fn::Join':
- '-'
- - Ref: 'AWS::StackName'
- rds

PostgresParameterGroup:
Type: 'AWS::RDS::DBParameterGroup'
Properties:
Description: Require SSL Connections
Family: postgres11
Parameters:
"rds.force_ssl": 1

DBInstance:
Type: 'AWS::RDS::DBInstance'
DBCluster:
Type: 'AWS::RDS::DBCluster'
Properties:
AllocatedStorage: 20
AllowMajorVersionUpgrade: true
AutoMinorVersionUpgrade: true
AvailabilityZone:
'Fn::Select':
- 0
- 'Fn::GetAZs': ''
BackupRetentionPeriod: 1
CopyTagsToSnapshot: true
DBInstanceClass: 'db.t2.micro'
DBParameterGroupName:
Ref: PostgresParameterGroup
DatabaseName: ${self:custom.databaseName}
DBClusterIdentifier: '${self:service}-${self:provider.stage}'
DBSubnetGroupName:
Ref: RDSSubnetGroup
EnableIAMDatabaseAuthentication: true
Engine: postgres
EngineVersion: '11.4'
EnableHttpEndpoint: true
Engine: aurora-postgresql
EngineMode: serverless
EngineVersion: '10.7'
MasterUsername:
'Fn::Join':
- ''
Expand All @@ -68,30 +23,26 @@ Resources:
- - '{{resolve:secretsmanager:'
- Ref: DBSecret
- ':SecretString:password}}'
MultiAZ: false
PubliclyAccessible: false
StorageType: gp2
StorageEncrypted: true
Tags:
- Key: Name
Value:
'Fn::Join':
- '-'
- - Ref: 'AWS::StackName'
- rds
VPCSecurityGroups:
- Ref: DBSecurityGroup

Outputs:
DBInstanceAddress:
Description: RDS Instance Address
DBClusterAddress:
Description: RDS Cluster Address
Value:
'Fn::GetAtt':
- DBInstance
- DBCluster
- 'Endpoint.Address'

DBInstancePort:
Description: RDS Instance Port
DBClusterPort:
Description: RDS Cluster Port
Value:
'Fn::GetAtt':
- DBInstance
- DBCluster
- 'Endpoint.Port'
45 changes: 0 additions & 45 deletions example/resources/s3_cf.yml

This file was deleted.

7 changes: 3 additions & 4 deletions example/resources/secretsmanager_cf.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
Resources:

DBSecret:
Type: 'AWS::SecretsManager::Secret'
Properties:
Expand All @@ -12,11 +11,11 @@ Resources:
PasswordLength: 16
ExcludeCharacters: '"@/\'

SecretDBInstanceAttachment:
DBClusterSecretTargetAttachment:
Type: 'AWS::SecretsManager::SecretTargetAttachment'
Properties:
SecretId:
Ref: DBSecret
TargetId:
Ref: DBInstance
TargetType: 'AWS::RDS::DBInstance'
Ref: DBCluster
TargetType: 'AWS::RDS::DBCluster'
Loading

0 comments on commit 35694c6

Please sign in to comment.