2

背景: 我们正在使用 AWS 云开发工具包 (CDK) 2.5.0。

手动使用 AWS 控制台和硬编码 IP 地址,路由 53 到 ALB(应用程序负载均衡器)到私有接口 VPC 端点到私有 REST API 网关(等等..)工作。见下图。

代码: 我们正在尝试通过 CDK 编写此手动解决方案的代码,但被困在如何获取和使用 IP 地址或以某种方式将负载均衡器连接到接口 VPC 端点上。(端点有 3 个 IP 地址,区域中每个可用区一个。)

ALB 需要一个目标组,该目标组以接口 VPC 端点的 IP 地址为目标。(使用“实例”方法而不是 IP 地址,我们尝试InstanceIdTarget与端点一起使用vpcEndpointId,但失败了。我们得到了错误Instance ID 'vpce-WITHWHATEVERWASHERE' is not valid

使用 CDK,我们使用aws_elasticloadbalancingv2模块创建了以下(除其他外):

  • ApplicationLoadBalancer(ALB)
  • ApplicationTargetGroup(ATG) 又名目标集团

我们希望aws_elasticloadbalancingv2_targets类似于aws_route53_targets,但没有运气。我们知道对象数组的targets属性,但仅此而已。ApplicationTargetGroupIApplicationLoadBalancerTarget

  :
import { aws_ec2 as ec2 } from 'aws-cdk-lib';
  :
import { aws_elasticloadbalancingv2 as loadbalancing } from 'aws-cdk-lib';

// endpointSG, loadBalancerSG, vpc, ... are defined up higher
        const endpoint = new ec2.InterfaceVpcEndpoint(this, `ABCEndpoint`, {
            service: {
                name: `com.amazonaws.us-east-1.execute-api`,
                port: 443
            },
            vpc,
            securityGroups: [endpointSG],
            privateDnsEnabled: false,
            subnets: { subnetGroupName: "Private" }
        });


        const loadBalancer = new loadbalancing.ApplicationLoadBalancer(this, 'abc-${config.LEVEL}-load-balancer', {
            vpc: vpc,
            vpcSubnets: { subnetGroupName: "Private" },
            internetFacing: false,
            securityGroup: loadBalancerSG
        });

        const listenerCertificate = loadbalancing.ListenerCertificate.fromArn(config.ARNS.CERTIFICATE)
        const listener = loadBalancer.addListener('listener', {
            port: 443,
            certificates: [ listenerCertificate ]
        });

        let applicationTargetGroup = new loadbalancing.ApplicationTargetGroup(this, 'abc-${config.LEVEL}-target-group', {
            port: 443,
            vpc: vpc,
            // targets: [ HELP ], - how to get the IApplicationLoadBalancerTarget objects?  
        })
        listener.addTargetGroups( 'abc-listener-forward-to-target-groups', { 
            targetGroups: [applicationTargetGroup]
        } );

正如您在上面看到的,我们向 ALB 添加了一个侦听器。我们将目标组添加到侦听器。

我们使用的一些资源:

如果通过图像可视化设置有帮助,这里是我们想要的一个近似值。 在此处输入图像描述

任何帮助填充该targets属性的ApplicationTargetGroup对象IApplicationLoadBalancerTarget表示赞赏。谢谢!

4

1 回答 1

0

https://aws.amazon.com/blogs/networking-and-content-delivery/accessing-an-aws-api-gateway-via-static-ip-addresses-provided-by-aws-global-accelerator/

此博客展示了如何使用 AWS 控制台配置问题中给出的架构(只需禁用全局加速器选项)。关键要点是应用程序负载均衡器使用目标类型 IP 并在步骤 2 中手动解析 VPC 端点域名。其他两个选项,instance(目标是 EC2 实例)和 lambda(目标是 AWS Lambda 函数)不能用过的。

ec2.InterfaceVpcEndpoint构造没有直接给出 IP 地址的输出。底层 CloudFormation 资源也不支持它。相反,您必须在代码中使用 的vpcEndpointDnsEntries属性ec2.InterfaceVpcEndpoint并将域名解析为 IP 地址(控制台配置也需要相同的域名解析)。您可以在ApplicationTargetGroup中使用IpTarget对象。

在这一点上,由于 CDK 在后台的工作方式,您将遇到最后一个障碍。 文档中的 cdk 结构 如果您在一个 CDK 应用程序中定义了所有资源,则每个参数的值(或使用 Ref、GetAtt 等底层 CloudFormation 函数对值的引用)需要在合成步骤之前可用,因为那是所有生成模板。AWS CDK为此目的使用令牌{'Fn::GetAtt': ['EndpointResourceLogicalName', 'DnsEntries'],在综合过程中这些令牌解析为诸如. 但是,由于我们需要 DNS 条目的实际值才能解析它,因此令牌值将无用。

解决此问题的一种方法是以这种方式构建两个完全独立的 CDK 应用程序:

  • 具有 VPC 和接口端点的应用程序 A。使用CfnOutputvpcEndpointDnsEntries和 VPC-ID 定义为输出。
  • 应用程序 B 与其余资源。您必须编写代码来读取应用程序 A 创建的 CloudFormation 堆栈的输出。您可以将Fn.importValue用于 VPC ID,但不能将其用于 DnsEntries 输出,因为它会再次解析为基于 Fn::ImportValue令牌。您需要使用 AWS 开发工具包或其他选项读取堆栈输出的实际值。一旦你有了域名,你可以在你的打字稿代码中解析它(我对打字稿不是很熟悉,这可能需要第三方库)。

图片来源:

于 2022-01-12T17:47:17.397 回答