|
import * as cdk from '@aws-cdk/core'; |
|
import * as apigateway from '@aws-cdk/aws-apigateway' |
|
import { InterfaceVpcEndpoint, Vpc, Subnet, SecurityGroup, Peer, Port } from '@aws-cdk/aws-ec2' |
|
import * as lambda from '@aws-cdk/aws-lambda' |
|
import * as iam from '@aws-cdk/aws-iam' |
|
import path = require('path'); |
|
|
|
export class PrivateApiGatewayStack extends cdk.Stack { |
|
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { |
|
super(scope, id, props); |
|
|
|
const vpc = Vpc.fromLookup(this, 'PrimaryVPC', { |
|
vpcName: '<vpcid>' |
|
}) |
|
|
|
const a = Subnet.fromSubnetAttributes(this, 'ASubnet', { |
|
availabilityZone: 'eu-central-1a', |
|
subnetId: 'subnet-<id>' |
|
}) |
|
|
|
const b = Subnet.fromSubnetAttributes(this, 'BSubnet', { |
|
availabilityZone: 'eu-central-1b', |
|
subnetId: 'subnet-<id>' |
|
}) |
|
|
|
const sg = new SecurityGroup(this, 'SecurityGroup', { |
|
vpc, |
|
allowAllOutbound: true, |
|
securityGroupName: 'VpcEndpoint' |
|
}); |
|
|
|
sg.addIngressRule(Peer.ipv4("<CIDR>"), Port.tcp(443)) |
|
|
|
const vpcEndpoint = new InterfaceVpcEndpoint(this, 'ApiVpcEndpoint', { |
|
vpc, |
|
service: { |
|
name: 'com.amazonaws.eu-central-1.execute-api', |
|
port: 443 |
|
}, |
|
subnets: { |
|
subnets: [a, b] |
|
}, |
|
privateDnsEnabled: true, |
|
securityGroups: [sg] |
|
}) |
|
|
|
const fn = new lambda.Function(this, 'PrivateLambda', { |
|
runtime: lambda.Runtime.NODEJS_10_X, |
|
handler: 'index.handler', |
|
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda')), |
|
}); |
|
|
|
new apigateway.LambdaRestApi(this, 'PrivateLambdaRestApi', { |
|
endpointTypes: [apigateway.EndpointType.PRIVATE], |
|
handler: fn, |
|
policy: new iam.PolicyDocument({ |
|
statements: [ |
|
new iam.PolicyStatement({ |
|
principals: [new iam.AnyPrincipal], |
|
actions: ['execute-api:Invoke'], |
|
resources: ['execute-api:/*'], |
|
effect: iam.Effect.DENY, |
|
conditions: { |
|
StringNotEquals: { |
|
"aws:SourceVpce": vpcEndpoint.vpcEndpointId |
|
} |
|
} |
|
}), |
|
new iam.PolicyStatement({ |
|
principals: [new iam.AnyPrincipal], |
|
actions: ['execute-api:Invoke'], |
|
resources: ['execute-api:/*'], |
|
effect: iam.Effect.ALLOW |
|
}) |
|
] |
|
}) |
|
}) |
|
} |
|
} |
@akshay-nm I did read that you can add a custom domain on a private hosted zone...
"If you want, you can set your own DNS name to the endpoint with Amazon Route53 private hosted zones when you enable “Enable DNS name” option. With this option enabled, any request to Lambda from your public subnet does not go through the Internet Gateway. All requests to Lambda go through the VPC endpoints."
Source: https://aws.amazon.com/blogs/aws/new-use-aws-privatelink-to-access-aws-lambda-over-private-aws-network/