aws-cdk: Automatic token exports can not be arrays

Reproduction Steps

Add the following to your stack:

Fn.select(0, vpcEndpoint.vpcEndpointDnsEntries)

It generates the following which is incorrect since DnsEntries are a string

"ExportsOutputFnGetAttVPCVpcCloudAuthVpcEndpointA6A0016BDnsEntries65E2739D": {
  "Value": {
    "Fn::GetAtt": [
      "VPCVpcCloudAuthVpcEndpointA6A0016B",
      "DnsEntries"
    ]
  },
  "Export": {
    "Name": "Vpc:ExportsOutputFnGetAttVPCVpcCloudAuthVpcEndpointA6A0016BDnsEntries65E2739D"
  }
}

Error Log

Vpc: creating CloudFormation changeset...

 ❌  Vpc failed: Error [ValidationError]: Template format error: The Value field of every Outputs member must evaluate to a String.
    at Request.extractError (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/protocol/query.js:50:29)
    at Request.callListeners (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/home/linuxbrew/.linuxbrew/Cellar/aws-cdk/1.20.0/libexec/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
  message: 'Template format error: The Value field of every Outputs member must evaluate to a String.',
  code: 'ValidationError',
  time: 2020-01-19T23:30:22.007Z,
  requestId: '43c10843-42a8-4439-a770-a77ec7859f46',
  statusCode: 400,
  retryable: false,
  retryDelay: 109.59137506513541
}
Template format error: The Value field of every Outputs member must evaluate to a String.

Environment

  • CLI Version :
  • Framework Version:
  • OS :
  • Language :

Other


This is 🐛 Bug Report

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 17 (5 by maintainers)

Most upvoted comments

Would be ideal if the manual workaround wasn’t needed.

I have experience the same issue had had to create my own way around it (not ideal 😛)

@SomayaB and @rix0rrr you asked about example code, here it is (https://github.com/timpur/aws-cdk-issue-5897/blob/master/cdk.out/Stack1.template.json#L18).

Very basic stack but produces the issue. Seems the select happens in the consumer which is fine bout the generated output doesnt account for refs that are arrays of strings …

I imagine is something to do with this line (https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/core/lib/private/refs.ts#L183)

Thanks. Hopes this helps

I can report the same issue with InterfaceVpcEndpoint

in one stack I have:

this.endpointDNS = Fn.select(0, this.endpointService.vpcEndpointDnsEntries);

Then the output of that stack is:

"Outputs": {
    "ExportsOutputFnGetAttsapgatewayvpcendpoint99C0B197DnsEntriesC7F2A387": {
      "Value": {
        "Fn::GetAtt": [
          "sapgatewayvpcendpoint99C0B197",
          "DnsEntries"
        ]
      },
      "Export": {
        "Name": "SAPGatewayProxyEndpointClient:ExportsOutputFnGetAttsapgatewayvpcendpoint99C0B197DnsEntriesC7F2A387"
      }
    }
  }

And then Fn::Split happens at the “consumption” stack

{
   "Name":"HOST",
   "Value":{
      "Fn::Join":[
         "",
         [
            {
               "Fn::Select":[
                  0,
                  {
                     "Fn::ImportValue":"SAPGatewayProxyEndpointClient:ExportsOutputFnGetAttsapgatewayvpcendpoint99C0B197DnsEntriesC7F2A387"
                  }
               ]
            },
            "}:443"
         ]
      ]
   }
},`