<@UB9RYG30V> If you can post a bit of your code su...
# general
s
@bright-motherboard-93404 If you can post a bit of your code surrounding it I’ll give you a nicer example
b
This is what I'm working on atm:
Copy code
function dashboard(name, instances) {
  reutrn pulumi.all(instances).apply(
    (is) =>
      new aws.cloudwatch.Dashboard(name, {
	dashboardName: name,
	dashboardBody: JSON.stringify({
          widgets: [
            {type: "metric",
             properties: {
	       metrics: defineMetrics(is),
               period: 300,
               stat: "Average",
               region: "us-west-2",
               title: "EC2 Instance CPU"
             }
            }
          ]
	})
      }))
  };

function defineMetrics(instances) {
  return instances.map(function(i) {
    return ["AWS/EC2", "CPUUtilization", "InstanceId", i.id]
  })
}
s
OK, so what you want is…
b
and this is driven by the top-level statement: ```
let dashboard = cw.dashboard("classifier-dashboard", [metrics_host, initializer].concat(workers)) ```
s
Actually you are on the right track there
The JSON.stringify needs to be inside the apply body
Such that the return value of the
apply
is an
Output<string>
That is then assignable to the
dashboardBody
property which is an
Input<string>
- broadly speaking
Input<T> = T | Output<T> | Promise<T>
b
ah, okay
give me a sec
Copy code
function mkDash(name, instances) {
  let dashBody = pulumi.all(instances).apply(
    (is) => JSON.stringify({
      widgets: [
        {type: "metric",
         properties: {
	   metrics: defineMetrics(is),
           period: 300,
           stat: "Average",
           region: "us-west-2",
           title: "EC2 Instance CPU"
         }
        }
      ]
    }));
  return new aws.cloudwatch.Dashboard(name, {
	dashboardName: name,
	dashboardBody: dashBody
  })
};
still complaining : + awscloudwatchDashboard classifier-dashboard creating failed error: Plan apply failed: Putting dashboard failed: InvalidParameterInput: The dashboard body is invalid, there are 2 validation errors:
Copy code
{
        "message": "Should NOT have more than 3 items",
        "dataPath": "/widgets/0/properties/metrics/0"
      },
s
That looks like a legitimate issue - is what you want an object per instance?
(It looks to me like the serialization isn’t the issue there, at least)
b
The shape of the data is legit: when I redefine defineMetrics to be:
Copy code
function defineMetrics(instances) {
  return instances.map(function(i) {
    return ["AWS/EC2", "CPUUtilization", "InstanceId", i.toString()]
  })
}
then the dashboard gets created properly, and the dashboard contains as many entries as there are instances in the stack.
(Of course they're not populated, because '[object object]' is not a real instance id )
s
Is
instances
here
aws.ec2.Instance[]
?
b
yes
Okay, I sovled it! Here's the crucial bit:
Copy code
function mkDash(name, instances) {
  let dashBody = pulumi.all(instances.map(i => i.id)).apply(
    (iids) => {
      x = defineMetrics(iids);
      return JSON.stringify({
pulumi.all needs to get the list of instance *id*s, not the instances themselves
s
Ah - sorry I didn’t see the “yes” 30 mins ago
b
no worries, that was investigative work that I needed to do anyway 😉
I ended up debugging using the
with
construct... shiver
s
I think there is another way to do that without using
pulumi.all
as well, I’ll have a play around in a minute
b
In any case, thanks so much for your help
s
No worries! Feel free to post any more things you run into
b
My feeling is that the api that depends on a string is breaking the lazy evaluation model of Pulumi
s
If you want to subscribe to pulumi-aws#353, that will hopefully become easier
b
👍
s
Anything where an unknown value has to modify control flow is more cumbersome than would be ideal, but we need to make it easier where possible for specific circumstances.