Search code examples
amazon-web-servicesaws-cdk

AWS CDK CfnMapping value as list type in aws_cdk.aws_apigatewayv2_authorizers.HttpJwtAuthorizer's jwt_audience field


The documentation for the underlying Cloudformation Mapping says,

The values can be String or List types.

If you use a list value mapping in a CfnOutput, you'll get an error.

# fails to deploy:
#  "Template format error: The Value field of every Outputs member must
#   evaluate to a String and not a List."

CfnOutput(
    self,
    "values",
    value=mapping.find_in_map(Fn.ref("AWS::Region"), "values")
)

Clearly the Mapping value is indeed a list.

However, if I try to use it as a list in aws_cdk.aws_apigatewayv2_authorizers.HttpJwtAuthorizer , the stack can't even synth.

        mapping = CfnMapping(self, "Mapping",
            mapping={
                "us-east-2": { "values": [ "value1", "value2" ] }
            },
        )
        authorizer = aws_apigatewayv2_authorizers.HttpJwtAuthorizer(
            "HttpJWTAuthorizer",
            "auther",
            authorizer_name="JWT-Authorizer",
            identity_source=["$request.header.Authorization"],
            #jwt_audience=["value1", "value2"], # synth works
            jwt_audience=mapping.find_in_map(Fn.ref("AWS::Region"), "values"), # synth does not work
        )

Failure message is:

RuntimeError: Passed to parameter props of new aws-cdk-lib.aws_apigatewayv2_authorizers.HttpJwtAuthorizer: Unable to deserialize value as aws-cdk-lib.aws_apigatewayv2_authorizers.HttpJwtAuthorizerProps
ā”œā”€ā”€ šŸ›‘ Failing value is an object
ā”‚      { '$jsii.struct': [Object] }
ā•°ā”€ā”€ šŸ” Failure reason(s):
    ā•°ā”€ Key 'jwtAudience': Unable to deserialize value as array<string>
        ā”œā”€ā”€ šŸ›‘ Failing value is a string
        ā”‚      '${Token[TOKEN.15]}'
        ā•°ā”€ā”€ šŸ” Failure reason(s):
            ā•°ā”€ Value is not an array

Am I wrong in expecting this to work? Since this issue happens at synth, this seems like a CDK issue. I haven't tested it yet in pure cloudformation, but pretty confident it would work.

Reproduction: https://github.com/farrellit/cfn-mapping-test/blob/e7815503ceb7487ad722f7ea0a3afe5ed7b03b14/cdk_mapping_test/cdk_mapping_test_stack.py


Solution

  • Assuming the token actually does resolve to a list, you can make CDK represent it as such using the asList helper function:

    // specifying the variable type explicitly here for illustrative purposes
    const myValues: string[] = Token.asList(mapping.find_in_map(Fn.ref("AWS::Region"), "values"));