This message was deleted.
# general
s
This message was deleted.
b
Copy code
passwordConfig = pulumi.Config("passwords")

passwordConfig.require_secret("pw1")
I think is what you need (untested)
g
thanks I will try that
Copy code
no it id not work I got an error please set a value using the command `pulumi config set passwords:pw1 <value>`
b
okay give me a few minutes
g
I wish Config could just deserialize into an Object it I'm trying to workout how can I use this with Pydantinc object or at least a data class as my config object
b
@great-sunset-355 it can be grabbed as an object:
Copy code
config = pulumi.Config()
passwords = config.require_object("passwords")
pw = passwords.get("pw1")

<http://pulumi.log.info|pulumi.log.info>(pw)
there's also
require_secret_object
g
yeah that's what I'm working with
b
the snippet above works for me
g
yeah I'm trying to deserialize it into an object (dataclass or pydantic settings) so I do not have to refer to the sections as strings
Also if a
secret object
contains mix of secret and not secret values, all of them are treated as secrets
b
yes that's expected behaviour
g
I think that the problem is that in python Output looks like a dictionary so I'd naturally expect to behave that way This snippet works
Copy code
from dataclasses import dataclass
import pulumi 

@dataclass
class MyConfig:
    pw1: Any 

    config = pulumi.Config()
    passwords = config.require_secret_object("passwords")
    mycfg = MyConfig(passwords['pw1'])
    print(mycfg)
However this does not:
Copy code
from dataclasses import dataclass
import pulumi 

@dataclass
class MyConfig:
    pw1: Any 

    config = pulumi.Config()
    passwords = config.require_secret_object("passwords")
    mycfg = MyConfig(**passwords)
    print(mycfg)
with error
Copy code
TypeError: attribute of type 'Output' is not callable
    error: an unhandled error occurred: Program exited with non-zero exit code: 1
I wonder if there is a way to get the
keys
from the Output without knowing them
b
No, that’s not possible because output is asynchronous. Have a read of this: https://www.leebriggs.co.uk/blog/2021/05/09/pulumi-apply.html Essentially you’ll have to use an apply
g
I see then using apply will expose the secrets in the sate anyway
btw I read that article yesterday it was super helpful
@billowy-army-68599 it looks to me that I am never able to get a list from the secret object
b
you need to do it inside an
apply
because it's an output
g
Copy code
config:
  NS:obj:
    ALLOWED_HOSTS:
    - <http://URL1.com|URL1.com>
    - <http://URL2.com|URL2.com>
I'm trying to construct call
','.join(ALLOWED_HOSTS)
as an string input for another resource And since my ALLOWED_HOSTS is part of a secret object it is not possible even with apply I keep getting `Output`s never the value
b
any secret is an output, that's how secrets work because it needs to decrypt the value, so it's async. if you're working with outputs it MUST be inside an apply if you want to use it with another string
g
how can I get a list back not string?
b
from config?
g
yeah
b
this returns the correct types:
Copy code
config = pulumi.Config()
foo = config.require_object("foo")

allowed_hosts = foo.get("allowed_hosts")

print(type(allowed_hosts))
<http://pulumi.log.info|pulumi.log.info>(allowed_hosts[0])
<http://pulumi.log.info|pulumi.log.info>(allowed_hosts[1])
If you want it as a secret object:
Copy code
config = pulumi.Config()
foo = config.require_object("foo")
secret_foo = config.require_secret_object("foo")

allowed_hosts = foo.get("allowed_hosts")
secret_allowed_hosts = foo.get("allowed_hosts")

print(type(allowed_hosts))
<http://pulumi.log.info|pulumi.log.info>(allowed_hosts[0])
<http://pulumi.log.info|pulumi.log.info>(allowed_hosts[1])

<http://pulumi.log.info|pulumi.log.info>(secret_allowed_hosts[2])

secret_foo.apply(lambda host: print(host))
Copy code
Type                 Name                      Plan       Info
 +   pulumi:pulumi:Stack  py-structured-config-dev  create     5 messages

Diagnostics:
  pulumi:pulumi:Stack (py-structured-config-dev):
    <class 'list'>
    {'allowed_hosts': ['<http://example.com|example.com>', '<http://example.net|example.net>', '[secret]']}

    <http://example.com|example.com>
    <http://example.net|example.net>
    [secret]


Do you want to perform this update?  [Use arrows to move, enter to select, type to filter]
  yes
> no
  details
g
this line is wrong I believe
Copy code
secret_allowed_hosts = foo.get("allowed_hosts")
b
ah yes, fixing
here we go:
Copy code
import pulumi

config = pulumi.Config()
foo = config.require_object("foo")
secret_foo = config.require_secret_object("foo")

allowed_hosts = foo.get("allowed_hosts")
secret_allowed_hosts = secret_foo.apply(lambda h: print(h.get("allowed_hosts")))

print(type(allowed_hosts))
<http://pulumi.log.info|pulumi.log.info>(allowed_hosts[0])
<http://pulumi.log.info|pulumi.log.info>(allowed_hosts[1])

<http://pulumi.log.info|pulumi.log.info>(secret_allowed_hosts[2])

secret_foo.apply(lambda host: print(host))
g
I wonder if using async and await would fix it
b
why use async/await when you can use apply? it does the same thing
g
I find apply way too complicated
lemme try to replicate your example in my environment
b
i'm sorry to hear you're finding it too complicated, unfortunately you're going to come across it quite a lot 🙂
g
am I expected to get an error when running your code?
I just created fresh project
b
You’ll need to populate the config the same as I did obviously
g
I did this:
Copy code
pulumi config set-all --path \
    --plaintext foo.allowed_hosts[0]=host1 \
    --plaintext foo.allowed_hosts[1]=host2
I really appreciate we spend the on this, if I am to use pulumi I have to understand this problem.
b
Away from keyboard at the moment be back soon
@great-sunset-355 looking at your comment, you cannot log an output that way, you have to do it inside an apply
your
need_list
method won't work either, because you're trying to do a join on an async value
g
can I make something wait for output though?
b
yes, using
apply
g
If I need to wait for a Cloudformation stack to finish do I just write a function that waits until it's done and then unblocks the rest of the code?
b
g
I tried that and still got an exception + the example did not use the function
wait_for_loadbalancer
it does not wait for the function
@billowy-army-68599 I believe I hit this problem https://github.com/pulumi/pulumi/issues/2484
162 Views