Hi everyone, I've been pulling my hair out trying...
# typescript
r
Hi everyone, I've been pulling my hair out trying to make the outputs of my stack work. I want to get each network security rule by name, and then output it. Here is what I have right now : https://gist.github.com/MathieuBuisson/0aeb53488077beb4da484cc79caad079#file-stack-ts This deploys resources perfectly, however the outputs
consulRule
and
sshRule
are incorrect. All the rule outputs have the same property values : https://gist.github.com/MathieuBuisson/0aeb53488077beb4da484cc79caad079#file-outputs-txt As you can see in the Gist, all rules outputs are identical. It looks like these 3 rules outputs are all referencing the same object : the first rule. Could anyone give me any pointers on what I'm doing wrong here ? Thank you.
w
What is the type of
nsg.rules
here?
Does this work?
Copy code
function getRuleByName(name: string)     {
    return pulumi.all(nsg.rules.map(r => r.rule.name)).apply(ruleNames => {
        return ruleNames.find(ruleName => name === ruleName);
    });
}
r
nsg.rules
is of type
NetworkSecurityRule[]
,
NetworkSecurityRule
being a custom ComponentResource and has a
rule
property of type
azure.network.NetworkSecurityRule
.
Thank you for your help @white-balloon-205. This only outputs the name of the rules, instead of the rules object.
I'm still stuck on this : https://pulumi-community.slack.com/archives/CJ909TL6P/p1572375960100600 Anybody has any suggestion, please ?
t
Why do you try to convert to promise?
You should export Outputs directly, potentially changed with
apply
and
all
So something like Luke suggested but without mapping to name first
r
Thanks for your help @tall-librarian-49374 The
Promise()
is just to unwrap the underlying object from the output, as explained in this article : https://www.pulumi.com/blog/unit-testing-infrastructure-in-nodejs-and-mocha/ As per your suggestion, i modified
getRuleByName
like so :
Copy code
function getRuleByName(name: string) {
    return pulumi.all(nsg.rules.apply(r => {
        return r.find(r => r.rule.name === name)
    })
}
But then I get the error :
Property 'apply' does not exist on type 'NetworkSecurityRule[]'.
NetworkSecurityRule
is a custom ComponentResource which contains an
azure.network.NetworkSecurityRule.
t
Should be
return pulumi.all(nsg.rules).apply(r  => ...
r
Thanks @tall-librarian-49374 So this :
Copy code
function getRuleByName(name: string) {
    return pulumi.all(nsg.rules).apply(r => {
        return r.find(r => r.rule.name === name)
    })
}
Results in the following error for the test in the find method:
This condition will always return 'false' since the types 'Output<string>' and 'string' have no overlap
And this might work :
Copy code
function getRuleByName(name: string) {
    return pulumi.all(nsg.rules).apply(r => {
        return r.find(r => r.rule.name.get() === name)
    })
}
But it result in the following error :
Copy code
Error: Cannot call '.get' during update or preview.
    To manipulate the value of this Output, use '.apply' instead.
t
Sorry for many false hints. Now I finally opened an editor and this seems to fit your use case:
Copy code
function getRuleByName(name: string) {
  return pulumi.all(nsg.rules.map(r => r.name)).apply(names => {
      const index = names.indexOf(name);
      return index >= 0 ? nsg.rules[index] : undefined;
  });
}
r
@tall-librarian-49374 Wow, that is some ugly and convoluted code, but it works ! I remember seeing a Github issue related to making outputs easier to deal with, but I cannot find it. I think that outputs should be simpler to use. A common use case is testing : importing the outputs into the tests suite and running assertions against them should be much simpler than it is now. Anyway, thanks a lot for your help.
t
That's a valid but a challenging goal. I'm glad you are unblocked for now.