I have one weird type conversion when using Pulumi...
# general
q
I have one weird type conversion when using Pulumi stack references. An example with some anonymization of the code: In stack A I have:
Copy code
const a_secrets: pulumi.Output<pulumi.Output<string>[]>
...and:
Copy code
pulumi stack output --stack A/infra/kari --show-secrets --json | jq '.a_secrets'
[
  "this-is-secret-from-a-8929c229"
]
So,
a_secrets
is of type (I'm using Typescript):
const a_secrets: *pulumi*.*Output*<*pulumi*.*Output*<string>[]>
Then I use stack A in stack B:
Copy code
const a_secrets = stackA.requireOutput("a_secrets") as pulumi.Output<pulumi.Output<string>[]>;

a_secrets.apply(a => {
  console.log(`****************************`);
  console.log(`typeof: ${typeof(a)}`);
  console.log(`json: ${JSON.stringify(a)}`);
})
=> output:
Copy code
****************************
typeof: object
json: {"XXXXXXXX93072939515e22adb298388d":"XXXXXXXX64138c4ac30d75fd1eb44270","value":["this-is-secret-from-a-8929c229"]}
So, what I would expect in the stack B side for the type of
a_secrets
to be is the same
pulumi.Output<pulumi.Output<string>[]>
, but the type is
{string: string, "value": [string]}
and therefore I need to do this clumsy type conversion later on when I want to use that array:
Copy code
type a_type = {string: string, "value": [string]};
...
  secrets: a_secrets.apply(a => {
    // NOTE: Ugly! Why cannot we use the type that the stack A is supposed to return?
    const secrets_array = a as unknown as pulumi.Output<a_type>;
    return secrets_array["value"];
  }),
When running
pulumi up
I see in the output:
a_secrets: [secret]
. Perhaps this has something to do with this weird type conversion? I have dependency
"@pulumi/pulumi": "^3.42.0"
in my Pulumi / Typescript and I'm using
Pulumi cli v3.42.0
on Ubuntu 2022, and the infrastructure gets created in GCP and we are using Pulumi Service to store the stacks. Any idea if I'm missing something here? Any help would be appreciated (🧵).
e
So internally stack outputs are all basically just JSON blobs (the "4dabf18193072939515e22adb298388d" is pulumi encoding that it's a special JSON blob) so we lose all the typing information between stacks, which is why
requireOutput
just returns an
Output<any>
. But I think you should be able to type this as an
Output<string[]>
a
The issue here isn’t that the type information is lost - it’s that an output exported as
Copy code
export data = ["some-string"]
Is being imported as
Copy code
const data = stack.requireOutput("data");

console.log(data) // {string: "...", value: ["some-string"]}
Whereas the expected value of data should be
["some-string"]
e
That's because it's secret
q
So. Does that mean that for secrets we cannot convey the type information from stack A to stack B when using stack references?
What would be the right way to pass this kind of secret from one stack to another to avoid this:
Copy code
type a_type = {string: string, "value": [string]};
a as unknown as pulumi.Output<a_type>;
e
Does that mean that for secrets we cannot convey the type information from stack A to stack B when using stack references?
As above we never get type information across stacks, its all just untyped JSON.
What would be the right way to pass this kind of secret from one stack to another to avoid this:
Output<string[]> should work here, if it's not that's a n SDK bug that we should go and look into.
a
That’s because it’s secret
I don’t understand why this makes any difference. I have never seen this behaviour when exporting any other kind of secret data, even other datatypes that are
string[]
- this is as if the JSON representation is getting transformed. Seems like a bug to me..
And the data itself being exported is correct as when we run
pulumi stack output
then it’s correct. Why would pulumi modify this on the consuming stack?
As above we never get type information across stacks, its all just untyped JSON.
I don’t think Kari is referring to the TypeScript type here - but rather the underlying structure of the data. I.e we don’t care that the output is Typed (in TS) as
Output<any>
but that the data itself is being mutated when compared to how it is exported from the source stack
q
Yep. That's what I meant - sorry, English is not my native language.
e
but that the data itself is being mutated when compared to how it is exported from the source stack
That is by design when the value is secret. As I said under the hood this just a JSON blob so there needs to be some way to indicate what bits are secret, that's done by wrapping the value in an object with the special key "4dabf18193072939515e22adb298388d" and value "1b47061264138c4ac30d75fd1eb44270". What's not by design is that your seeing that mutation, the SDK layer should have picked that up and translated it into a Output<string[]>.
I'm gonna check we've got tests for this and see if I can repro
a
Thanks 🙏 Let us know if you need anything to help reproduce
e
hmm yeh I'm not having any luck reproducing this, if you can throw something minimal in a gist or something and send us an issue (github.com/pulumi/pulumi/issues) I'll have another look
123 Views