使用 AWS CDK,如何将 AWS 负载均衡器和 AWS 接口 VPC 端点连接在一起
Using AWS CDK, How to connect an AWS Load balancer and an AWS Interface VPC Endpoint together
背景:
我们正在使用 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
相似,但没有运气。我们知道 ApplicationTargetGroup
的 targets
属性 接受一个 IApplicationLoadBalancerTarget
对象的数组,但仅此而已。
:
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 添加了一个侦听器。我们将目标组添加到侦听器。
我们使用的一些资源:
- https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer.html
- https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationTargetGroup.html
- https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.InterfaceVpcEndpoint.html
- https://docs.aws.amazon.com/cdk/api/v2//docs/aws-cdk-lib.aws_elasticloadbalancingv2_targets.InstanceIdTarget.html 及相关。
- How to get PrivateIPAddress of VPC Endpoint in CDK?但这并没有帮助。
如果通过图像可视化设置有帮助,这里是我们想要的近似值。
任何帮助使用 IApplicationLoadBalancerTarget
对象填充 ApplicationTargetGroup
的 targets
属性 的帮助都将受到赞赏。谢谢!
此博客展示了如何使用 AWS 控制台配置问题中给出的架构(只需禁用全局加速器选项)。关键要点是应用程序负载均衡器使用目标类型 IP 并在步骤 2 中手动解析 VPC 端点域名。其他两个选项实例(目标是 EC2 实例)和 lambda(目标是 AWS Lambda 函数)不能用过。
ec2.InterfaceVpcEndpoint
构造没有直接给出 IP 地址的输出。底层 CloudFormation 资源也不支持它。相反,您将不得不使用 ec2.InterfaceVpcEndpoint
的 vpcEndpointDnsEntries
属性 并将域名解析为代码中的 IP 地址(控制台配置也需要相同的域名解析)。您可以使用 IpTarget object in your ApplicationTargetGroup.
此时,您将 运行 由于 CDK 在幕后的工作方式而遇到最后一个障碍。
如果您在一个 CDK 应用程序中定义了所有资源,则每个参数的值(或使用底层 CloudFormation 函数(如 Ref、GetAtt 等)对值的引用)需要在综合步骤之前可用,因为那是所有生成模板。 AWS CDK 为此目的使用 tokens,它在综合过程中解析为 {'Fn::GetAtt': ['EndpointResourceLogicalName', 'DnsEntries']
等值。但是,由于我们需要 DNS 条目的实际值才能解析它,因此令牌值将无用。
解决此问题的一种方法是让两个完全独立的 CDK 应用程序以这种方式构建:
- 具有 VPC 和接口端点的应用程序 A。使用 CfnOutput.
将 vpcEndpointDnsEntries
和 VPC-ID 定义为输出
- 具有其余资源的应用程序 B。您将必须编写代码来读取应用程序 A 创建的 CloudFormation 堆栈的输出。您可以将 Fn.importValue 用于 VPC ID,但不能将其用于 DnsEntries 输出,因为它会再次解析为 Fn::ImportValue 基于令牌。您需要使用 AWS 开发工具包或其他一些选项来读取堆栈输出的实际值。一旦你有了域名,你就可以在你的 typescript 代码中解析它(我对 typescript 不是很熟悉,这可能需要第三方库)。
图片来源:
背景: 我们正在使用 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
相似,但没有运气。我们知道 ApplicationTargetGroup
的 targets
属性 接受一个 IApplicationLoadBalancerTarget
对象的数组,但仅此而已。
:
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 添加了一个侦听器。我们将目标组添加到侦听器。
我们使用的一些资源:
- https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer.html
- https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationTargetGroup.html
- https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.InterfaceVpcEndpoint.html
- https://docs.aws.amazon.com/cdk/api/v2//docs/aws-cdk-lib.aws_elasticloadbalancingv2_targets.InstanceIdTarget.html 及相关。
- How to get PrivateIPAddress of VPC Endpoint in CDK?但这并没有帮助。
如果通过图像可视化设置有帮助,这里是我们想要的近似值。
任何帮助使用 IApplicationLoadBalancerTarget
对象填充 ApplicationTargetGroup
的 targets
属性 的帮助都将受到赞赏。谢谢!
此博客展示了如何使用 AWS 控制台配置问题中给出的架构(只需禁用全局加速器选项)。关键要点是应用程序负载均衡器使用目标类型 IP 并在步骤 2 中手动解析 VPC 端点域名。其他两个选项实例(目标是 EC2 实例)和 lambda(目标是 AWS Lambda 函数)不能用过。
ec2.InterfaceVpcEndpoint
构造没有直接给出 IP 地址的输出。底层 CloudFormation 资源也不支持它。相反,您将不得不使用 ec2.InterfaceVpcEndpoint
的 vpcEndpointDnsEntries
属性 并将域名解析为代码中的 IP 地址(控制台配置也需要相同的域名解析)。您可以使用 IpTarget object in your ApplicationTargetGroup.
此时,您将 运行 由于 CDK 在幕后的工作方式而遇到最后一个障碍。
{'Fn::GetAtt': ['EndpointResourceLogicalName', 'DnsEntries']
等值。但是,由于我们需要 DNS 条目的实际值才能解析它,因此令牌值将无用。
解决此问题的一种方法是让两个完全独立的 CDK 应用程序以这种方式构建:
- 具有 VPC 和接口端点的应用程序 A。使用 CfnOutput. 将
- 具有其余资源的应用程序 B。您将必须编写代码来读取应用程序 A 创建的 CloudFormation 堆栈的输出。您可以将 Fn.importValue 用于 VPC ID,但不能将其用于 DnsEntries 输出,因为它会再次解析为 Fn::ImportValue 基于令牌。您需要使用 AWS 开发工具包或其他一些选项来读取堆栈输出的实际值。一旦你有了域名,你就可以在你的 typescript 代码中解析它(我对 typescript 不是很熟悉,这可能需要第三方库)。
vpcEndpointDnsEntries
和 VPC-ID 定义为输出
图片来源: