This message was deleted.
# automation-api
s
This message was deleted.
b
Have you tried making your lambda invocation from within an output apply delegate?
l
yes (I think). This is how I am attempting to pass in the name servers from my records.
invoke_stack_function(body=route_53_resources['hosted_zone'].name_servers.apply(lambda name_servers: name_servers), function="addnameservers", message="Name servers were added successfully!")
l
Do you need to use the lambda? Can you instead allow your Pulumi program to access the HZ in the other account, and add the necessary records there in the normal way?
To answer the question, can you use Output's
get()
method? https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/pulumi/#OutputInstance-get
b
That usage of apply doesn't really do anything. The apply delegate is used to do something with an output once it is known, so if you are acting with the result of the apply rather than within the delegate itself you are still just handing an output. What you want is: var delayedNamedServers = name_servers.apply(lambda name_servers: return invocation(name_servers)); Now you have an output that will do your invocation once the value is known, and if the invocation function also returns an Output<T> that doesn't resolve until your invocation finishes than any downstream consumers of that new output will wait until the invocation completes before deploying.
🤦‍♀️ 1
Or what @little-cartoon-10569 is suggesting would work too. But I think you should checkout the inputs/outputs documentation
l
THank you both! @bored-oyster-3147 - I tried the below, and am getting an error saying that list object has no attribute apply... I also tried with just apply (and not Output.all) and it didn't work either. I haven't tried the .get() yet. I'll do that next.
Copy code
add_name_servers = Output.all(route_53_resources['hosted_zone'].name_servers).apply(lambda name_servers: invoke_stack_function(body={"org_id": org_id, "hosted_zone_name_servers": name_servers}, function="addnameservers", message="Name servers were added successfully!", aws_access_key_id=os.environ['BUILDBOT_ACCESS_KEY'], aws_secret_access_key=os.environ['BUILDBOT_SECRET_KEY']))
b
Hard to say what the issue is, idk what type the “route_53_resources” variable is or what the key “hosted_zone” in that dictionary returns or what type the “name_servers” property is.
l
that's fair. I'll keep digging on my end 🙂 Thanks!
It's been a while! I'm back to solving this issue, but it's a little different and more straightforward. Basically, I have a function that accepts a hosted_zone_id for a hosted zone that already exists, and then attempts to create and validate a certificate. I copy and pasted the example directly from the docs and all I did was remove the "example_zone" resource and pass in my own id. It doesn't work. I get the error
AttributeError: 'Certificate' object has no attribute 'domainValidationOptions
. ANy ideas? Happy to share my code also 🙂 \
Copy code
def create_and_validate_certificate(org_id, hosted_zone_id):
    example_certificate = aws.acm.Certificate(f'shared-certificate-{org_id}',
                                              domain_name=f'{org_id}.<http://getbuildbot.com|getbuildbot.com>',
                                              subject_alternative_names=[f'*.{org_id}.<http://getbuildbot.com|getbuildbot.com>'],
                                              validation_method="DNS")
    example_record = []
    for range in [{"key": k, "value": v} for [k, v] in enumerate({dvo.domainName: {
        name: dvo.resourceRecordName,
        record: dvo.resourceRecordValue,
        type: dvo.resourceRecordType,
    } for dvo in example_certificate.domainValidationOptions})]:
        example_record.append(aws.route53.Record(f"exampleRecord-{range['key']}",
                                                 allow_overwrite=True,
                                                 name=range["value"]["name"],
                                                 records=[range["value"]["record"]],
                                                 ttl=60,
                                                 type=range["value"]["type"],
                                                 zone_id=hosted_zone_id))
    example_certificate_validation = aws.acm.CertificateValidation("exampleCertificateValidation",
                                                                   certificate_arn=example_certificate.arn,
                                                                   validation_record_fqdns=example_record.apply(
                                                                       lambda example_record: [record.fqdn for record in
                                                                                        example_record]))
    return example_certificate_validation.certificate_arn
Just sending this so my thread pops back up in the channel also. In regards to certificate validation with aws acm 🙂
l
Check that you're definitely using the correct class / type for Certificate. aws.acm.Certificate does have a domainValidationOptions property, so if your code is saying that it doesn't, then the problem must be that your object isn't an aws.acm.Certificate.
Ah, no wait, it's domainValidationOptions in typescript. In Python, it's domain_validation_options.
Looks like a copypasta in the docs.
l
@little-cartoon-10569 do you think that is true for
resourceRecordName
also? and the others?
Now I am getting
error: python inline source runtime error: 'Output' object is not iterable, consider iterating the underlying value inside an 'apply'
. I don't understand exactly how apply works, and was hoping the example provided in the docs would just work. Any idea how I would modify the for loop with an apply?
l
Yes, the python convention is to separate words with underscores.
You need to move the for loop inside he apply.