Skip to content

Commit

Permalink
put lambda behind a vpc, added a endpoint that points to unirpc endpo…
Browse files Browse the repository at this point in the history
…int service(not used by lambda yet) (#881)
  • Loading branch information
melodylove-uniswap authored Nov 18, 2024
1 parent 106bd58 commit ad4c9b2
Showing 1 changed file with 76 additions and 0 deletions.
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
})

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,
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

0 comments on commit ad4c9b2

Please sign in to comment.