Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion apigw-to-private-apig-cdk/src/api/dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

127 changes: 69 additions & 58 deletions apigw-to-private-apig-cdk/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ export class ApiStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, vpc: ec2.Vpc) {
super(scope, id);

/* Create Security group */
/* Create Security group */
const apiGatewayEndpointSG = new ec2.SecurityGroup(this, "apiGatewayEndpointSG", {
description: "Security Group for Api Gateway Endpoint",
vpc: vpc
description: "Security Group for Api Gateway Endpoint",
vpc: vpc
});
apiGatewayEndpointSG.addIngressRule(ec2.Peer.ipv4('10.0.0.0/8'), ec2.Port.tcp(443));

/* Create API Gateway Interface VPC Endpoint */
/* Create API Gateway Interface VPC Endpoint */
const endpointAPIGateway = new ec2.InterfaceVpcEndpoint(this, "endpointAPIGateway", {
service: ec2.InterfaceVpcEndpointAwsService.APIGATEWAY,
vpc: vpc,
subnets: vpc.selectSubnets({
subnetType: ec2.SubnetType.PRIVATE
}),
privateDnsEnabled: true,
securityGroups: [apiGatewayEndpointSG]
service: ec2.InterfaceVpcEndpointAwsService.APIGATEWAY,
vpc: vpc,
subnets: vpc.selectSubnets({
subnetType: ec2.SubnetType.PRIVATE
}),
privateDnsEnabled: true,
securityGroups: [apiGatewayEndpointSG]
});

const handler = new lambda.Function(this, "handler", {
Expand All @@ -41,11 +41,22 @@ export class ApiStack extends cdk.Stack {
})
});

/* Grant api gateway invoke permission on lambda */
/* Grant api gateway invoke permission on lambda */
handler.grantInvoke(new iam.ServicePrincipal('apigateway.amazonaws.com'));

const apiResourcePolicy = new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
effect: iam.Effect.DENY,
actions: ['execute-api:Invoke'],
principals: [new iam.AnyPrincipal()],
resources: ['execute-api:/*/*/*'],
conditions: {
StringNotEquals: {
"aws:sourceVpce": endpointAPIGateway.vpcEndpointId
}
}
}),
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['execute-api:Invoke'],
Expand All @@ -54,67 +65,67 @@ export class ApiStack extends cdk.Stack {
})
]
});
const restapi = new apigateway.LambdaRestApi(this, config.prefix, {

const restapi = new apigateway.LambdaRestApi(this, config.prefix, {
handler,
description: config.description,
endpointConfiguration: {types: [apigateway.EndpointType.PRIVATE], vpcEndpoints: [endpointAPIGateway]},
endpointConfiguration: { types: [apigateway.EndpointType.PRIVATE], vpcEndpoints: [endpointAPIGateway] },
policy: apiResourcePolicy
});

/* Create Load Balancer Target Group */
/* Create Load Balancer Target Group */
const targetGroup = new elb.NetworkTargetGroup(this, 'TargetGroup', {
port: 443,
port: 443,
vpc,
targetType: elb.TargetType.IP
});

for (let counter = 0; counter < vpc.availabilityZones.length; counter++) {
const getEndpointIp = new customResource.AwsCustomResource(this, `GetEndpointIp${counter}`, {
onUpdate: {
service: 'EC2',
action: 'describeNetworkInterfaces',
outputPath: `NetworkInterfaces.${counter}.PrivateIpAddress`,
parameters: { NetworkInterfaceIds: endpointAPIGateway.vpcEndpointNetworkInterfaceIds },
physicalResourceId: customResource.PhysicalResourceId.of(`NetworkInterfaces.${counter}.PrivateIpAddress`)
},
policy: customResource.AwsCustomResourcePolicy.fromSdkCalls({resources: customResource.AwsCustomResourcePolicy.ANY_RESOURCE})
onUpdate: {
service: 'EC2',
action: 'describeNetworkInterfaces',
outputPath: `NetworkInterfaces.${counter}.PrivateIpAddress`,
parameters: { NetworkInterfaceIds: endpointAPIGateway.vpcEndpointNetworkInterfaceIds },
physicalResourceId: customResource.PhysicalResourceId.of(`NetworkInterfaces.${counter}.PrivateIpAddress`)
},
policy: customResource.AwsCustomResourcePolicy.fromSdkCalls({ resources: customResource.AwsCustomResourcePolicy.ANY_RESOURCE })
});
targetGroup.addTarget(new elbTarget.IpTarget(cdk.Token.asString(getEndpointIp.getResponseField(`NetworkInterfaces.${counter}.PrivateIpAddress`)), 443));
}
/* End Create Load Balancer Target Group */
/* Start Create Private Network Load Balancer */
let privateAPGNLB = new elb.NetworkLoadBalancer(this, 'internalAPIGNLB', {
vpc: vpc,
internetFacing: false,
});
}
/* End Create Load Balancer Target Group */
/* Start Create Private Network Load Balancer */
let privateAPGNLB = new elb.NetworkLoadBalancer(this, 'internalAPIGNLB', {
vpc: vpc,
internetFacing: false,
});

privateAPGNLB.addListener('listner',{
port: 443,
protocol: elb.Protocol.TCP,
defaultTargetGroups: [targetGroup]
}
privateAPGNLB.addListener('listner', {
port: 443,
protocol: elb.Protocol.TCP,
defaultTargetGroups: [targetGroup]
}
);
/* End Create Private Network Load Balancer */
/* Create VPC Link in API Gateway */
let vpcLink = new apigateway.VpcLink(this, 'vpclink', {
targets: [privateAPGNLB],
vpcLinkName: 'apigconnectvpclink'
});
/* End Create VPC Link in API Gateway */
/* Create Public API Gateway */
const publicapi = new apigateway.RestApi(this, 'public-api');
const integration = new apigateway.Integration({
integrationHttpMethod: "ANY",
type: apigateway.IntegrationType.HTTP_PROXY,
uri: `https://${restapi.restApiId}-${endpointAPIGateway.vpcEndpointId}.execute-api.${this.region}.amazonaws.com/prod`,
options: {
connectionType: apigateway.ConnectionType.VPC_LINK,
vpcLink: vpcLink,
},
});
publicapi.root.addMethod('GET', integration);
/* End Create Public API Gateway */
/* End Create Private Network Load Balancer */
/* Create VPC Link in API Gateway */
let vpcLink = new apigateway.VpcLink(this, 'vpclink', {
targets: [privateAPGNLB],
vpcLinkName: 'apigconnectvpclink'
});
/* End Create VPC Link in API Gateway */
/* Create Public API Gateway */
const publicapi = new apigateway.RestApi(this, 'public-api');
const integration = new apigateway.Integration({
integrationHttpMethod: "ANY",
type: apigateway.IntegrationType.HTTP_PROXY,
uri: `https://${restapi.restApiId}-${endpointAPIGateway.vpcEndpointId}.execute-api.${this.region}.amazonaws.com/prod`,
options: {
connectionType: apigateway.ConnectionType.VPC_LINK,
vpcLink: vpcLink,
},
});
publicapi.root.addMethod('GET', integration);
/* End Create Public API Gateway */

const tags = config.tags

Expand Down