3
votes

I need create a VPC Endpoint and an ALB to target the VPC Endpoint in CDK.

I found InterfaceVpcEndpoint can return vpcEndpointNetworkInterfaceIds attribute. So it seems the missing part is how to get private IP address from these ENI IDs in a CDK way.

I found CDK has a custom-resource package, its example shows I can use AwsCustomResource to call an AWS API (EC2/DescribeNetworkInterfaces) to get the IP Address.

I tried write a custom resource like below:

eni = AwsCustomResource(
        self, 'DescribeNetworkInterfaces',
        on_create=custom_resources.AwsSdkCall(
            service='ec2',
            action='describeNetworkInterfaces',
            parameters= {
                'NetworkInterfaceId.N': [eni_id]
            },
            physical_resource_id=str(time.time())
        )
    )
ip = eni.get_data('NetworkInterfaces.0.PrivateIpAddress')

and pass ip into elbv2.IPTarget.

But it seems I missed something, so it complains it needs a scalar not reference?

(.env) ➜  base-stack (master) ✔ cdk synth base --no-staging > template.yaml
jsii.errors.JavaScriptError: 
  Error: Expected Scalar, got {"$jsii.byref":"@aws-cdk/core.Reference@10015"}
      at Object.deserialize (/Volumes/DATA/ci/aws/base-stack/.env/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:12047:23)
      at Kernel._toSandbox (/Volumes/DATA/ci/aws/base-stack/.env/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7031:61)
      at /Volumes/DATA/ci/aws/base-stack/.env/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7084:33
      at Array.map (<anonymous>)
      at Kernel._boxUnboxParameters (/Volumes/DATA/ci/aws/base-stack/.env/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7084:19)
      at Kernel
....

Thanks!

1

1 Answers

2
votes

The AwsCustomResource.get_data-method return a Reference object, which now causes the issue. To get the CloudFormation token (!GetAtt "DescribeNetworkInterfaces"."NetworkInterfaces.0.PrivateIpAddress") the Reference.to_string method must be used explicitly.

This:

ip = eni.get_data('NetworkInterfaces.0.PrivateIpAddress')

Becomes:

ip = eni.get_data('NetworkInterfaces.0.PrivateIpAddress').to_string()