Skip to content

Commit

Permalink
Syncing Lambda IP ranges to RDS SG & running DB health check every min
Browse files Browse the repository at this point in the history
  • Loading branch information
heythisischris committed Jun 17, 2024
1 parent a53efb9 commit e97d101
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 8 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Deploy to Lambda
run: |
npm install
npx esbuild ./*.ts --bundle --platform=node --outdir=dist --external:@aws-sdk
npx esbuild index.ts --bundle --platform=node --outdir=dist --external:@aws-sdk
cd dist
zip -r lambda.zip * > /dev/null
zip -r lambda.zip index.js > /dev/null
aws lambda update-function-code --function-name heythisischris-api --zip-file fileb://lambda.zip > /dev/null
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "heythisischris",
"name": "heythisischris-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "esbuild ./*.ts --bundle --platform=node --outdir=dist --external:@aws-sdk && cd dist && zip -r lambda.zip * > /dev/null && aws --profile heythisischris lambda update-function-code --function-name heythisischris-api --zip-file \"fileb://lambda.zip\" > /dev/null && rm -rf lambda.zip"
"build": "esbuild index.ts --bundle --platform=node --outdir=dist --external:@aws-sdk && cd dist && zip -r lambda.zip index.js > /dev/null && aws --profile heythisischris lambda update-function-code --function-name heythisischris-api --zip-file \"fileb://lambda.zip\" > /dev/null && rm -rf lambda.zip"
},
"author": "",
"license": "ISC",
Expand Down
3 changes: 2 additions & 1 deletion routes/scheduled/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './syncGithub'
export * from './syncCalendar'
export * from './syncNotion'
export * from './syncNotion'
export * from './runEveryMinute'
53 changes: 53 additions & 0 deletions routes/scheduled/runEveryMinute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { graphqlQuery } from '#src/utils';
import { EC2Client, DescribeSecurityGroupsCommand, RevokeSecurityGroupIngressCommand, AuthorizeSecurityGroupIngressCommand } from "@aws-sdk/client-ec2";
const ec2Client = new EC2Client();

export const runEveryMinute = async () => {
// Sync IP Ranges
const newIps = (await (await fetch(`https://ip-ranges.amazonaws.com/ip-ranges.json`)).json()).prefixes
.filter(({ region, service }) => region === 'us-east-2' && service === 'EC2').map(obj => obj.ip_prefix);
const existingIps = (await ec2Client.send(new DescribeSecurityGroupsCommand({ GroupIds: [process.env.DB_SECURITY_GROUP] })))
.SecurityGroups?.map(securityGroup => securityGroup?.IpPermissions?.map(ipPermission => ipPermission.IpRanges?.map(ipRange => ipRange.CidrIp)).flat()).flat();
const addedIps = newIps.filter(newIp => !existingIps.includes(newIp));
const removedIps = existingIps.filter(existingIp => !newIps.includes(existingIp));
if (removedIps.length > 0) {
await ec2Client.send(new RevokeSecurityGroupIngressCommand({
GroupId: process.env.DB_SECURITY_GROUP,
IpPermissions: removedIps.map(ip => ({
FromPort: 5432,
IpProtocol: 'tcp',
IpRanges: [{
CidrIp: ip,
Description: 'Lambda'
}],
ToPort: 5432,
}))
}));
}
if (addedIps.length > 0) {
await ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
GroupId: process.env.DB_SECURITY_GROUP,
IpPermissions: addedIps.map(ip => ({
FromPort: 5432,
IpProtocol: 'tcp',
IpRanges: [{
CidrIp: ip,
Description: 'Lambda'
}],
ToPort: 5432,
}))
}));
}

// Perform health check
const response = await graphqlQuery({ query: `{apps(limit:1){id}}` });
if (!response?.apps?.[0]?.id) {
await fetch(process.env.SLACK_WEBHOOK, {
method: 'POST',
body: JSON.stringify({
text: `*heythisischris* - Database connection failure detected`
})
})
}
return;
}
4 changes: 2 additions & 2 deletions utils/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export const client = new ServerlessClient({
host: process.env.DB_HOST,
database: process.env.DB_NAME,
password: process.env.DB_PASSWORD,
port: '5432',
ssl: true,
port: 5432,
ssl: { rejectUnauthorized: false },
});
17 changes: 17 additions & 0 deletions utils/graphqlQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { event, isStaging } from '.';

export const graphqlQuery = async ({ query, variables = {} }) => {
const Authorization = event?.headers?.authorization;
const response = (await (await fetch(`https://graphql${isStaging ? '-staging' : ''}.heythisischris.com/v1/graphql`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...Authorization ? { Authorization } : { 'x-hasura-admin-secret': process.env.DB_PASSWORD },
},
body: JSON.stringify({ query, variables }),
})).json());
if (!response?.data) {
console.log(JSON.stringify({ graphqlError: response }));
}
return response?.data;
}
4 changes: 3 additions & 1 deletion utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ export * from './notion'
export * from './sleep'
export * from './getMimeType'
export * from './openai'
export * from './bedrock'
export * from './bedrock'
export * from './graphqlQuery'
export * from './isStaging'
1 change: 1 addition & 0 deletions utils/isStaging.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const isStaging = process.env.STAGING ? '-staging' : '';

0 comments on commit e97d101

Please sign in to comment.