Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VPC endpoint to unirpc #881

Merged
merged 6 commits into from
Nov 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions bin/stacks/routing-lambda-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,20 @@ import * as aws_lambda from 'aws-cdk-lib/aws-lambda'
import * as aws_lambda_nodejs from 'aws-cdk-lib/aws-lambda-nodejs'
import * as aws_s3 from 'aws-cdk-lib/aws-s3'
import * as aws_sns from 'aws-cdk-lib/aws-sns'
import * as ec2 from 'aws-cdk-lib/aws-ec2'
import { Construct } from 'constructs'
import * as path from 'path'
import { DynamoDBTableProps } from './routing-database-stack'
import { RetentionDays } from 'aws-cdk-lib/aws-logs'
import * as aws_route53 from 'aws-cdk-lib/aws-route53'
import * as aws_route53_targets from 'aws-cdk-lib/aws-route53-targets'

const vpcEndpointServiceMap: Record<string, string> = {
dev: 'com.amazonaws.vpce.us-east-2.vpce-svc-0945550ad67320638',
staging: 'com.amazonaws.vpce.us-east-2.vpce-svc-00e58a4116063039d',
prod: 'com.amazonaws.vpce.us-east-2.vpce-svc-04784c683b22cfabb',
}
const privateHostedZoneName = 'unihq.org'

export interface RoutingLambdaStackProps extends cdk.NestedStackProps {
poolCacheBucket: aws_s3.Bucket
Expand Down Expand Up @@ -77,16 +87,79 @@ export class RoutingLambdaStack extends cdk.NestedStack {
new CfnOutput(this, 'jsonRpcProviders', {
value: JSON.stringify(jsonRpcProviders),
})
const stage = process.env.STAGE || 'dev' // Default to 'dev' if not set

// TODO: Add if not dev , not create
const vpc = new ec2.Vpc(this, `RoutingLambdaVPC-${stage}`, {
maxAzs: 4, // Number of availability zones
subnetConfiguration: [
{
name: `RoutingPublicSubnet-${stage}`,
subnetType: ec2.SubnetType.PUBLIC, // Public subnet with internet access
cidrMask: 24, // IP range for public subnet
},
{
name: `RoutingPrivateSubnet-${stage}`,
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, // Private subnet with access to the internet via NAT Gateway
cidrMask: 24, // IP range for private subnet
},
],
natGateways: 1, // One NAT Gateway for private subnet internet access
melodylove-uniswap marked this conversation as resolved.
Show resolved Hide resolved
})

const publicSubnets = vpc.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC })
const vpcEndpoint = new ec2.InterfaceVpcEndpoint(this, `AccessUnirpcEndpoint-${stage}`, {
vpc,
service: new ec2.InterfaceVpcEndpointService(vpcEndpointServiceMap[stage], 443),
subnets: publicSubnets,
privateDnsEnabled: false, // Enable private DNS for the endpoint
})

// Create a private hosted zone
const hostedZone = new aws_route53.PrivateHostedZone(this, 'UniHQHostedZone', {
zoneName: privateHostedZoneName,
vpc,
})

const recordName = `routing-${stage}.${privateHostedZoneName}` // e.g. routing-dev.unihq.org
new aws_route53.ARecord(this, 'RoutingRecord', {
zone: hostedZone,
recordName: recordName,
target: aws_route53.RecordTarget.fromAlias(new aws_route53_targets.InterfaceVpcEndpointTarget(vpcEndpoint)),
})

new cdk.CfnOutput(this, 'VpcEndpointId', {
value: vpcEndpoint.vpcEndpointId,
})

const lambdaRole = new aws_iam.Role(this, 'RoutingLambdaRole', {
assumedBy: new aws_iam.ServicePrincipal('lambda.amazonaws.com'),
managedPolicies: [
// Basic Lambda execution role
aws_iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
// General Lambda role
aws_iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaRole'),
// CloudWatch for logs and monitoring
aws_iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLambdaInsightsExecutionRolePolicy'),
// X-Ray for tracing
aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
],
})

// Add inline policy for EC2 permissions
lambdaRole.addToPolicy(
new aws_iam.PolicyStatement({
actions: [
'ec2:CreateNetworkInterface',
'ec2:DescribeNetworkInterfaces',
'ec2:DeleteNetworkInterface',
'ec2:AssignPrivateIpAddresses',
'ec2:UnassignPrivateIpAddresses',
],
resources: ['*'], // Adjust this to restrict to specific resources if needed
})
)

poolCacheBucket.grantRead(lambdaRole)
poolCacheBucket2.grantRead(lambdaRole)
poolCacheBucket3.grantRead(lambdaRole)
Expand All @@ -104,6 +177,7 @@ export class RoutingLambdaStack extends cdk.NestedStack {

const cachingRoutingLambda = new aws_lambda_nodejs.NodejsFunction(this, 'CachingRoutingLambda', {
role: lambdaRole,
vpc: vpc,
runtime: aws_lambda.Runtime.NODEJS_18_X,
entry: path.join(__dirname, '../../lib/handlers/index.ts'),
handler: 'quoteHandler',
Expand Down Expand Up @@ -171,6 +245,8 @@ export class RoutingLambdaStack extends cdk.NestedStack {
runtime: aws_lambda.Runtime.NODEJS_18_X,
entry: path.join(__dirname, '../../lib/handlers/index.ts'),
handler: 'quoteHandler',
vpc: vpc,
melodylove-uniswap marked this conversation as resolved.
Show resolved Hide resolved
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
// 11/8/23: URA currently calls the Routing API with a timeout of 10 seconds.
// Set this lambda's timeout to be slightly lower to give them time to
// log the response in the event of a failure on our end.
Expand Down
Loading