How to connect a Load balancer and an Interface VPC Endpoint together using CDK?

2

Acronym legend:

  • ALB - ApplicationLoadBalancer
  • ATG - ApplicationTargetGroup aka Target Group
  • VPC - Virtual Private Cloud

Our situation: Using the AWS Console manually, it was shown that using Route 53 to an ALB (Application Load Balancer) to a private Interface VPC Endpoint to a private REST API-Gateway to a private Lambda works well. (ALB and a gateway Custom-domain-name exist due to https and the needed Certificate)

The ALB needs a Target Group which targets the IP addresses of the Interface VPC Endpoint. (We tried using InstanceIdTarget with the endpoint's vpcEndpointId, but that failed with the error Instance ID 'vpce-WITHWHATEVERHERE' is not valid )

Using CDK, we created the following (among other things) using the aws_elasticloadbalancingv2 module:

  • ApplicationLoadBalancer (ALB)
  • ApplicationTargetGroup (ATG) aka Target Group

We added a listener to the ALB. We added the Target Group to the listener. It’s not clear how to get the IP addresses from the VPC endpoint. We want to add the IP addresses to the ATG aka Target Group using the targets property.

How to get the IP addresses of the Interface VPC Endpoint via CDK?

A sample of resources we've used:

We're using the latest available as of this writing (AWS CDK 2.5.0)

1 個回答
3
已接受的答案

You'll need to use a Custom Resource to (call the API to) get the IP of the endpoint's network interface(s) as CloudFormation doesn't expose it as a return value, which means CDK can't offer it as a property.

(Note: this code was originally written for CDK ~1.40, but should still work or be easily updatable.)

Assuming you're creating the VPC Endpoint like this:

    // note: creates two endpoints because this VPC has two private subnets
    const VPCEndpoints = new ec2.InterfaceVpcEndpoint(this, "APIEndpoint", {
      vpc: my_vpc,
      service: ec2.InterfaceVpcEndpointAwsService.APIGATEWAY,
      subnets: { subnetType: ec2.SubnetType.PRIVATE },
    });

Then you can create a custom resource to call the DescribeNetworkEndpoints API on them. This will be a Lambda function which CloudFormation will deploy and then invoke, and the return value from the function will have the API response in.

CDK has a helper which makes it easy to deploy a custom resource that just calls an AWS API, so we can use that. (CDK writes a little nodeJS function for us to do it, which is why I've linked to the JS SDK above.)

    const eni = new custom_resources.AwsCustomResource(
      this,
      "DescribeNetworkInterfaces",
      {
        onCreate: {
          service: "EC2",
          action: "describeNetworkInterfaces",
          parameters: {
            NetworkInterfaceIds: VPCEndpoints.vpcEndpointNetworkInterfaceIds,
          },
          physicalResourceId: PhysicalResourceId.of(Date.now().toString()),
        },
        onUpdate: {
          service: "EC2",
          action: "describeNetworkInterfaces",
          parameters: {
            NetworkInterfaceIds: VPCEndpoints.vpcEndpointNetworkInterfaceIds,
          },
          physicalResourceId: PhysicalResourceId.of(Date.now().toString()),
        },
        policy: {
          statements: [
            new iam.PolicyStatement({
              actions: ["ec2:DescribeNetworkInterfaces"],
              resources: ["*"],
            }),
          ],
        },
      }
    );

We can now use the getResponseField() method on the eni object to read the response values from the API call, and then use them to create an ALB Target Group.

    // note: two ENIs in our endpoint as above, so we can get two IPs out of the response
    const ip1 = eni.getResponseField("NetworkInterfaces.0.PrivateIpAddress");
    const ip2 = eni.getResponseField("NetworkInterfaces.1.PrivateIpAddress");

    const ALBTargetGroup = new elbv2.ApplicationTargetGroup(this, "ALBTG", {
      port: 443,
      targetType: elbv2.TargetType.IP,
      vpc: my_vpc,
    });

    ALBTargetGroup.addTarget(new elbv2_targets.IpTarget(ip1));
    ALBTargetGroup.addTarget(new elbv2_targets.IpTarget(ip2));

The target group can then just be used in an ALB Listener as usual.

profile pictureAWS
專家
James_S
已回答 2 年前
profile picture
專家
已審閱 7 個月前

您尚未登入。 登入 去張貼答案。

一個好的回答可以清楚地回答問題並提供建設性的意見回饋,同時有助於提問者的專業成長。

回答問題指南