You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用CDK获取VPC终端节点关联ENI的IP及网络接口ID?

使用AWS CDK获取API Gateway VPCE关联IP的问题

背景与目标

我尝试用CDK创建目标组,包含API Gateway的VPC终端节点(VPCE)关联的IP地址。理想情况是只通过VPCE属于API Gateway服务的条件,或者直接用VPCE ID来查询关联的IP。

尝试的方法

  1. 用CDK的InterfaceVpcEndpoint静态方法fromInterfaceVpcEndpointAttributes按服务过滤,返回了需要的VPCE,但返回的IInterfaceVpcEndpoint类型没有InterfaceVpcEndpoint构造的vpceNetworkInterfaceIds属性。
  2. 参考示例代码,用AwsCustomResource查询指定VPCE网络接口ID对应的IP:
const vpceNetworkInterfaceIds = ['eniId1', 'eniId2'];
const getEniIps = new AwsCustomResource(scope, `GetEndpointIps`, {
          onUpdate: {
            service: "EC2",
            action: "describeNetworkInterfaces",
            parameters: {
               NetworkInterfaceIds: vpceNetworkInterfaceIds
              },
            physicalResourceId: PhysicalResourceId.of(Date.now().toString())
          },
          policy: AwsCustomResourcePolicy.fromSdkCalls({
            resources: AwsCustomResourcePolicy.ANY_RESOURCE
          }),
        });

const privateIpAddresses: string[] = [];
for(let i = 0; i< vpceNetworkInterfaceIds.length; i++){
  const privateIpAddress: string = getNetworkInterfaceIpAddresses.getResponseField(`NetworkInterfaces.${i}.PrivateIpAddress`).toString();
  privateIpAddresses.push(privateIpAddress);
}
return privateIpAddresses;
  1. 尝试用describeVpcEndpoints SDK调用获取NetworkInterfaceIds数组,但遇到问题:
const getNetworkInterfaceIpAddresses = new AwsCustomResource(scope, `GetVpceNetworkInterfaceIds`, {
        onUpdate: {
          service: "EC2",
          action: "describeVpcEndpoints",
          parameters: {
             Filters: [
              { 
                Name: "service-name",
                Values: ["com.amazonaws.us-east-1.execute-api"]
              }
             ]
            },
          physicalResourceId: PhysicalResourceId.of(Date.now().toString())
        },
        policy: AwsCustomResourcePolicy.fromSdkCalls({
          resources: AwsCustomResourcePolicy.ANY_RESOURCE
        }),
      });

return getNetworkInterfaceIpAddresses.getResponseFieldReference(`VpcEndpoints.0.NetworkInterfaceIds`).toJSON();

试过Reference的toJson、toString等多种变体,还是无法从自定义资源中获取数组值。

问题

  1. 如何从AWS自定义资源的SDK调用中获取数组?
  2. 是否有更直接的方法获取指定VPCE的vpceNetworkInterfaceIds?
  3. 是否有更直接的方法获取指定VPCE的IP地址?

解决方案

1. 从AWS自定义资源中获取数组

CDK的AwsCustomResource返回的是CloudFormation动态引用,无法直接在代码中作为数组遍历,可通过以下方式处理:

  • 用CloudFormation内置函数遍历:利用Fn.select和Fn.length逐个提取数组元素,再单独查询每个ENI的IP:
const eniIdsRef = getNetworkInterfaceIpAddresses.getResponseFieldReference(`VpcEndpoints.0.NetworkInterfaceIds`);
const eniCount = Fn.length(eniIdsRef);

const privateIps = [];
for (let i = 0; i < Fn.parseInt(eniCount.toString(), 10); i++) {
  const eniId = Fn.select(i, eniIdsRef);
  const getEniIp = new AwsCustomResource(scope, `GetEniIp-${i}`, {
    onUpdate: {
      service: "EC2",
      action: "describeNetworkInterfaces",
      parameters: { NetworkInterfaceIds: [eniId] },
      physicalResourceId: PhysicalResourceId.of(Date.now().toString())
    },
    policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE })
  });
  privateIps.push(getEniIp.getResponseField(`NetworkInterfaces.0.PrivateIpAddress`));
}
  • 自定义Lambda函数处理:如果数组长度不固定,写一个Lambda函数一次性返回所有IP,再用CustomResource调用该Lambda,直接获取数组结果。

2. 直接获取指定VPCE的vpceNetworkInterfaceIds

  • 若VPCE是在当前CDK栈中创建的,直接使用InterfaceVpcEndpoint实例的vpceNetworkInterfaceIds属性即可。
  • 若引用现有VPCE:可在调用fromInterfaceVpcEndpointAttributes时手动传入已知的vpceNetworkInterfaceIds;或用自定义Lambda调用describeVpcEndpoints提取ID数组,比纯CloudFormation函数更可靠。

3. 直接获取指定VPCE的IP地址

最直接的方式是用自定义Lambda完成"查询VPCE ENI ID→批量查询ENI IP"的全流程:

// 自定义Lambda函数示例
export async function handler(event: any) {
  const ec2 = new AWS.EC2();
  const vpceId = event.vpceId;
  const vpceResp = await ec2.describeVpcEndpoints({
    Filters: [{ Name: "vpc-endpoint-id", Values: [vpceId] }]
  }).promise();
  
  const eniIds = vpceResp.VpcEndpoints[0].NetworkInterfaceIds;
  const eniResp = await ec2.describeNetworkInterfaces({ NetworkInterfaceIds: eniIds }).promise();
  
  return eniResp.NetworkInterfaces.map(eni => eni.PrivateIpAddress);
}

然后在CDK中调用这个Lambda:

const getVpceIps = new CustomResource(scope, 'GetVpceIps', {
  serviceToken: LambdaFunction.fromFunctionName(scope, 'GetVpceIpsLambda', 'your-lambda-name').functionArn,
  properties: { vpceId: 'your-vpce-id' }
});

// 获取IP数组
const privateIps = getVpceIps.getAtt('Result');

内容的提问来源于stack exchange,提问作者Sarah Ganci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 17:35:23