简体   繁体   中英

Step Functions parameter (array or not to array)

I have a couple of state machines that use respectively DescribeNetworkInterfaces (and EC2 API) and ListResourceRecordSets (a Route53 API).

I compose both Parameters using the Input as follows:

For EC2:

      "Parameters": {
        "NetworkInterfaceIds.$": "$.detail.attachments[0].details[?(@.name==networkInterfaceId)].value"
      "Resource": "arn:aws:states:::aws-sdk:ec2:describeNetworkInterfaces",

For Route 53:

      "Parameters": {
        "HostedZoneId.$": "$.NetworkInterfaces[0].TagSet[?(@.Key==HOSTZONEID)].Value"
      },
      "Resource": "arn:aws:states:::aws-sdk:route53:listResourceRecordSets"

They resolve fine but the problem is that, for some reasons, the [?(@.name=.networkInterfaceId)] and the [?(@.Key==HOSTZONEID)] turn the Parmeters values into array. Respectively:

{
  "NetworkInterfaceIds": [
    "eni-00f25c294401006b2"
  ]
}

And:

{
  "HostedZoneId": [
    "Z0555263BOXV8ELWLRS5"
  ]
}

In my case, the EC2 call succeeds because the Network API does expect an array of ENIs. However the Route53 call fails because the Records API does expect just one hosted zone id. This is the error message I get from SF:

No hosted zone found with ID: ["Z0555263BOXV8ELWLRS5"] (Service: Route53, Status Code: 404, Request ID: fa5bc89b-ca3d-4fe9-b2f3-baf01d509d76)

Based on my tests, it seems that it's the select that is causing the Parameter to be turned into an array because if I point directly to a field (which I cannot do) such as this:

      "Parameters": {
        "NetworkInterfaceIds.$": "States.Array($.detail.attachments[0].details[1].value)"
      },

The input parameter is no longer constructed as an array and the Network API fails with:

An error occurred while executing the state 'DescribeNetworkInterfaces (1)' (entered at the event id #2). The Parameters '{"NetworkInterfaceIds":"eni-00f25c294401006b2"}' could not be used to start the Task: [Cannot construct instance of An error occurred while executing the state 'DescribeNetworkInterfaces (1)' (entered at the event id #2). The Parameters '{"NetworkInterfaceIds":"eni-00f25c294401006b2"}' could not be used to start the Task: [Cannot construct instance of java.util.ArrayList (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('eni-00f25c294401006b2')]

I can fix the above problem using the States.Array intrinsic but it's a moot point because I need to dynamically select the the values in the inputs.

So I am at the point where the EC2 call works because, by chance, I need an array... but I can't figure out how to turn the Route53 parameter (hosted zone id) into a non array.

It was easier than I thought. I figure there was an intrinsic that would allow me to extract a value from an array: States.ArrayGetItem .

The following did the trick:

      "Parameters": {
        "HostedZoneId.$": "States.ArrayGetItem($.NetworkInterfaces[0].TagSet[?(@.Key==HOSTZONEID)].Value, 0)"
      },

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM