Place QBO Lambdas in VPC for static outbound IP
Puts qbo-lookup and qbo-oauth Lambdas in seahaven-vpc private subnets so all outbound traffic routes through NAT Gateway (52.202.83.13). Required for Intuit app listing IP allowlist.
This commit is contained in:
parent
266fe833fd
commit
066ff59d22
4 changed files with 72 additions and 0 deletions
|
|
@ -2,5 +2,50 @@
|
|||
"hosted-zone:account=328440206208:domainName=seahaven.com:region=us-east-1": {
|
||||
"Id": "/hostedzone/Z06652411XKH89KTZD3XA",
|
||||
"Name": "seahaven.com."
|
||||
},
|
||||
"vpc-provider:account=328440206208:filter.vpc-id=vpc-0d3d4b67bd0cf8a68:region=us-east-1:returnAsymmetricSubnets=true": {
|
||||
"vpcId": "vpc-0d3d4b67bd0cf8a68",
|
||||
"vpcCidrBlock": "10.20.0.0/16",
|
||||
"ownerAccountId": "328440206208",
|
||||
"availabilityZones": [],
|
||||
"vpnGatewayId": "vgw-073737d44762dffc2",
|
||||
"subnetGroups": [
|
||||
{
|
||||
"name": "Private",
|
||||
"type": "Private",
|
||||
"subnets": [
|
||||
{
|
||||
"subnetId": "subnet-04e38c507e96f1926",
|
||||
"cidr": "10.20.30.0/24",
|
||||
"availabilityZone": "us-east-1a",
|
||||
"routeTableId": "rtb-06a2f56f492b9b4de"
|
||||
},
|
||||
{
|
||||
"subnetId": "subnet-0a0b4fc6f296dfba5",
|
||||
"cidr": "10.20.40.0/24",
|
||||
"availabilityZone": "us-east-1b",
|
||||
"routeTableId": "rtb-01e152fe5cabca7d6"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Public",
|
||||
"type": "Public",
|
||||
"subnets": [
|
||||
{
|
||||
"subnetId": "subnet-0eea820effe1b3ae5",
|
||||
"cidr": "10.20.10.0/24",
|
||||
"availabilityZone": "us-east-1a",
|
||||
"routeTableId": "rtb-0f2232493a5c43fe8"
|
||||
},
|
||||
{
|
||||
"subnetId": "subnet-0012f5895182c1580",
|
||||
"cidr": "10.20.20.0/24",
|
||||
"availabilityZone": "us-east-1b",
|
||||
"routeTableId": "rtb-0f2232493a5c43fe8"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import * as iam from 'aws-cdk-lib/aws-iam';
|
|||
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
||||
import * as lambdaNodejs from 'aws-cdk-lib/aws-lambda-nodejs';
|
||||
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
||||
import * as bedrock from 'aws-cdk-lib/aws-bedrock';
|
||||
import * as path from 'path';
|
||||
|
|
@ -13,6 +14,8 @@ export interface BedrockAgentProps {
|
|||
region: string;
|
||||
knowledgeBaseId: string;
|
||||
knowledgeBaseArn: string;
|
||||
vpc: ec2.IVpc;
|
||||
lambdaSecurityGroup: ec2.ISecurityGroup;
|
||||
}
|
||||
|
||||
export class BedrockAgentConstruct extends Construct {
|
||||
|
|
@ -51,6 +54,9 @@ export class BedrockAgentConstruct extends Construct {
|
|||
timeout: cdk.Duration.seconds(30),
|
||||
memorySize: 256,
|
||||
environment: { QBO_SECRET_ARN: qboSecret.secretArn },
|
||||
vpc: props.vpc,
|
||||
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
||||
securityGroups: [props.lambdaSecurityGroup],
|
||||
bundling,
|
||||
});
|
||||
qboSecret.grantRead(this.qboLambda);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import * as lambdaNodejs from 'aws-cdk-lib/aws-lambda-nodejs';
|
|||
import * as apigatewayv2 from 'aws-cdk-lib/aws-apigatewayv2';
|
||||
import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations';
|
||||
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as iam from 'aws-cdk-lib/aws-iam';
|
||||
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
||||
import * as route53 from 'aws-cdk-lib/aws-route53';
|
||||
|
|
@ -19,6 +20,8 @@ export interface SlackHandlerProps {
|
|||
agentAliasId: string;
|
||||
conversationTable: dynamodb.Table;
|
||||
wildcardCertArn: string;
|
||||
vpc: ec2.IVpc;
|
||||
lambdaSecurityGroup: ec2.ISecurityGroup;
|
||||
}
|
||||
|
||||
export class SlackHandlerConstruct extends Construct {
|
||||
|
|
@ -124,6 +127,9 @@ export class SlackHandlerConstruct extends Construct {
|
|||
QBO_CLIENT_SECRET: '{{resolve:secretsmanager:seahaven/qbo/oauth:SecretString:clientSecret}}',
|
||||
REDIRECT_URI: 'https://bot.seahaven.com/qbo/callback',
|
||||
},
|
||||
vpc: props.vpc,
|
||||
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
||||
securityGroups: [props.lambdaSecurityGroup],
|
||||
bundling: {
|
||||
externalModules: ['@aws-sdk/*'],
|
||||
minify: true,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConversationLogConstruct } from './constructs/conversation-log';
|
||||
import { KnowledgeBaseConstruct } from './constructs/knowledge-base';
|
||||
|
|
@ -21,6 +22,16 @@ export class SeahavenSlackBotStack extends cdk.Stack {
|
|||
);
|
||||
}
|
||||
|
||||
// ── VPC (existing) — QBO Lambdas run here for static outbound IP ──────────
|
||||
const vpc = ec2.Vpc.fromLookup(this, 'SeahavenVpc', { vpcId: 'vpc-0d3d4b67bd0cf8a68' });
|
||||
|
||||
const lambdaSecurityGroup = new ec2.SecurityGroup(this, 'QBOLambdaSG', {
|
||||
vpc,
|
||||
securityGroupName: 'seahaven-qbo-lambda',
|
||||
description: 'QBO Lambdas - outbound HTTPS only',
|
||||
allowAllOutbound: true,
|
||||
});
|
||||
|
||||
// ── Conversation history (DynamoDB) ───────────────────────────────────────
|
||||
const conversationLog = new ConversationLogConstruct(this, 'ConversationLog');
|
||||
|
||||
|
|
@ -36,6 +47,8 @@ export class SeahavenSlackBotStack extends cdk.Stack {
|
|||
region: this.region,
|
||||
knowledgeBaseId: knowledgeBase.knowledgeBase.knowledgeBaseId,
|
||||
knowledgeBaseArn: knowledgeBase.knowledgeBase.knowledgeBaseArn,
|
||||
vpc,
|
||||
lambdaSecurityGroup,
|
||||
});
|
||||
|
||||
// ── Notion → KB daily sync (EventBridge + Lambda) ────────────────────────
|
||||
|
|
@ -70,6 +83,8 @@ export class SeahavenSlackBotStack extends cdk.Stack {
|
|||
agentAliasId: bedrockAgent.agentAlias.attrAgentAliasId,
|
||||
conversationTable: conversationLog.table,
|
||||
wildcardCertArn,
|
||||
vpc,
|
||||
lambdaSecurityGroup,
|
||||
});
|
||||
|
||||
// ── Stack outputs ─────────────────────────────────────────────────────────
|
||||
|
|
|
|||
Reference in a new issue