amazon-web-services - 无法在 CDK 中使用来自 AWS CustomResource 的响应(通过 AwsSdkCall)

标签 amazon-web-services aws-cloudformation aws-cdk aws-cloudformation-custom-resource aws-cdk-custom-resource

我有一个 VPC 终端节点,我想检索其私有(private) IP 地址(以通过目标组映射到 Application Load Balancer)。

我分两步完成:

  1. 首先,我使用 EC2::describeVpcEndpoints 创建一个 AwsCustomResource 来检索其网络接口(interface) ID
  2. 然后,我使用 EC2::describeNetworkInterfaces 创建第二个 CustomResource 来检索私有(private) IP 地址(在参数中传递先前的网络接口(interface) ID)

这是我的 CDK 代码:

// 1st get the VPC endpoint network interface IDs
const vpcEndpointsCall: AwsSdkCall = {
    service: "EC2",
    action: "describeVpcEndpoints",
    outputPaths: [`VpcEndpoints.0.NetworkInterfaceIds`],
    parameters: {
        VpcEndpointIds: [myVpcEndpointId],
    },
    physicalResourceId: PhysicalResourceId.of('describeVpcEndpoints'),
}

const vpces = new AwsCustomResource(
    this.stack,
    `DescribeVpcEndpoints-${this.stackProps.deploy.environmentName}`,
    {
        onCreate: vpcEndpointsCall,
        onUpdate: vpcEndpointsCall,
        policy: {
            statements: [
                new PolicyStatement({
                    actions: ["ec2:DescribeVpcEndpoints"],
                    resources: ["*"],
                }),
            ],
        },
    }
);
        
const networkInterfaceIds = vpces.getResponseField(`VpcEndpoints.0.NetworkInterfaceIds`)

for (let index = 0; index < this.stackProps.core!.vpc.availabilityZones.length; index++) {
    
    // 2nd get the private IP addresses of the VPC endpoint network interface IDs
    const sdkCall: AwsSdkCall = {
        service: "EC2",
        action: "describeNetworkInterfaces",
        outputPaths: [`NetworkInterfaces.${index}.PrivateIpAddress`],
        parameters: {
            NetworkInterfaceIds: Token.asString(networkInterfaceIds),
            Filters: [
                { Name: "interface-type", Values: ["vpc_endpoint"] }
            ],
        },
        physicalResourceId: PhysicalResourceId.of('describeNetworkInterfaces'),
    }

    const eni = new AwsCustomResource(
        this.stack,
        `DescribeNetworkInterfaces-${this.stackProps.deploy.environmentName}${index}`,
        {
            onCreate: sdkCall,
            onUpdate: sdkCall,
            policy: {
                statements: [
                    new PolicyStatement({
                        actions: ["ec2:DescribeNetworkInterfaces"],
                        resources: ["*"],
                    }),
                ],
            },
        }
    );

    targetGroup.addTarget(new IpTarget(Token.asString(eni.getResponseField(`NetworkInterfaces.${index}.PrivateIpAddress`)), targetPort))
}

但是在cdk部署期间,出现以下错误:

CustomResource 属性错误:供应商响应在对象 arn:aws:cloudformation:eu-west-3:XXXXXXXXXX:stack/CDK-Core-EC2-XXXXXXXXXX/XXXXXXXXXX| 中不包含 VpcEndpoints.0.NetworkInterfaceIds 键描述VpcEndpointsXXXXXXXXXX|S3存储桶中的XXXXXXXXXX cloudformation-custom-resource-storage-euwest3

以下是 DescribeVpcEndpoints 调用的结果:

{
    "VpcEndpoints": [
        {
            "VpcEndpointId": "XXX",
            "VpcEndpointType": "Interface",
            "VpcId": "XXX",
            "ServiceName": "com.amazonaws.eu-west-3.execute-api",
            "State": "available",
            "PolicyDocument": "{\n  \"Statement\": [\n    {\n      \"Action\": \"*\", \n      \"Effect\": \"Allow\", \n      \"Principal\": \"*\", \n      \"Resource\": \"*\"\n    }\n  ]\n}",       
            "RouteTableIds": [],
            "SubnetIds": [
                "subnet-XXX",
                "subnet-XXX",
                "subnet-XXX"
            ],
            "Groups": [
                {
                    "GroupId": "XXX",
                    "GroupName": "XXX"
                },
                {
                    "GroupId": "XXX",
                    "GroupName": "XXX"
                }
            ],
            "IpAddressType": "ipv4",
            "DnsOptions": {
                "DnsRecordIpType": "ipv4"
            },
            "PrivateDnsEnabled": true,
            "RequesterManaged": false,
            "NetworkInterfaceIds": [
                "eni-XXX",
                "eni-XXX",
                "eni-XXX"
            ],
            "DnsEntries": [
                {
                    "DnsName": "vpce-XXX.execute-api.eu-west-3.vpce.amazonaws.com",
                    "HostedZoneId": "XXX"
                },
                {
                    "DnsName": "vpce-XXX-eu-west-3c.execute-api.eu-west-3.vpce.amazonaws.com",
                    "HostedZoneId": "XXX"
                },
                {
                    "DnsName": "vpce-XXX-eu-west-3b.execute-api.eu-west-3.vpce.amazonaws.com",
                    "HostedZoneId": "XXX"
                },
                {
                    "DnsName": "vpce-XXX-eu-west-3a.execute-api.eu-west-3.vpce.amazonaws.com",
                    "HostedZoneId": "XXX"
                },
                {
                    "DnsName": "execute-api.eu-west-3.amazonaws.com",
                    "HostedZoneId": "XXX"
                },
                {
                    "DnsName": "*.execute-api.eu-west-3.amazonaws.com",
                    "HostedZoneId": "XXX"
                }
            ],
            "CreationTimestamp": "XXX",
            "Tags": [],
            "OwnerId": "XXX"
        }
}

所以我不明白为什么 getResponseField('VpcEndpoints.0.NetworkInterfaceIds') 不起作用。

我希望在字段 VpcEndpoints.0.NetworkInterfaceIds 中获得网络接口(interface) ID 列表。

有什么想法吗?

最佳答案

刚刚修复了同样的问题:您的问题是 Token.asString(networkInterfaceIds)Token.asString 无法处理数组。

您必须通过索引访问每个数组条目本身:

Token.asString(networkInterfaceIds)[0]

Token.asString(networkInterfaceIds)[1]

...

此外,您应该在任何地方都使用 Token.asString,因此您必须稍微重构您的代码。

关于amazon-web-services - 无法在 CDK 中使用来自 AWS CustomResource 的响应(通过 AwsSdkCall),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76962122/

相关文章:

amazon-web-services - 将现有应用程序 AWS 堆栈转换为 CloudFormation

amazon-web-services - 如何在cloudformation策略文档中引用资源ARN? (yaml)

amazon-s3 - CloudFormation 中如何派生 S3 存储桶名称?

typescript - 如何在 aws cdk 2.61.1 中将架构迁移到 ISchema

amazon-web-services - Lambda 上的 AWS SES - 无法(静默地)发送电子邮件

ios - S3 上传程序在尝试上传大文件时抛出异常

javascript - @aws-cdk/pipelines 和 @aws-cdk/aws-codepipeline 有什么区别?

amazon-web-services - 在 aws-cdk 上的 aws-rds 上,使数据库可公开访问的设置在哪里?

android - 如何将 Amazon Cognito 与适用于 Android 的 Google Plus 集成?

amazon-web-services - AWS S3 桶和谷歌云存储桶之间的实时同步