AWS CDK创建ClientVpnEndpoint后如何正确获取其DnsName属性
问题原因
AWS CloudFormation 原生的 AWS::EC2::ClientVpnEndpoint 资源类型目前仅支持通过 GetAtt 获取 EndpointId 属性,未暴露 DnsName 等其他返回字段,因此直接调用 getAtt("DnsName") 会触发不支持属性的报错。
解决方案
通过 CDK 内置的 AwsCustomResource 调用 AWS EC2 的 OpenAPI 接口主动拉取 Client VPN 端点的全量属性,即可拿到 DnsName 字段,操作代码如下:
- 首先导入依赖包:
import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from 'aws-cdk-lib/custom-resources'; import { CfnOutput, Fn } from 'aws-cdk-lib';
- 在创建好
ClientVpnEndpoint实例后,添加自定义资源拉取DnsName:
const clientVpnEndpoint = new ClientVpnEndpoint(stack, "vpn-enpoint", { vpc: vpc, cidr: "10.16.0.0/22", clientCertificateArn: config.clientCertificateArn, serverCertificateArn: config.serverCertificateArn, dnsServers: ["8.8.8.8", "4.4.4.4"], logging: false, }); // 自定义资源调用EC2接口拉取属性 const getVpnDnsResource = new AwsCustomResource(stack, "GetClientVpnDns", { onUpdate: { service: "EC2", action: "describeClientVpnEndpoints", parameters: { ClientVpnEndpointIds: [clientVpnEndpoint.endpointId], }, physicalResourceId: PhysicalResourceId.of(clientVpnEndpoint.endpointId), }, // 自动配置调用接口所需的IAM权限 policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: AwsCustomResourcePolicy.ANY_RESOURCE, }), }); // 提取DnsName字段输出 const vpnDnsName = getVpnDnsResource.getResponseField("ClientVpnEndpoints.0.DnsName"); // 可选:去除DnsName前缀的*.(控制台展示的可用地址一般不需要星号) // const cleanedVpnDnsName = Fn.replace(vpnDnsName, "*.", ""); new CfnOutput(stack, "vpn-enpoint-output", { value: vpnDnsName, // 用下面的行输出去除星号的地址 // value: cleanedVpnDnsName, });
注意事项
该自定义资源会在每次栈更新时自动调用接口拉取最新的DnsName,无需额外手动操作,权限也会由CDK自动配置,不需要手动新增IAM角色。
内容的提问来源于stack exchange,提问作者Maksim Romanenko
相关产品推荐
相关产品推荐

