I am writing an aws.lambda.CallbackFunction that m...
# general
f
I am writing an aws.lambda.CallbackFunction that must be passed some output values from resources created in order to make calls to the aws api. These parameters are passed in as `pulumi.Input`s. What is the canonical way to unwrap these values from their Input implementation?
pulumi.output(queueUrl).get()
? More context in thread.
Copy code
export async function getApproximateNumberOfMessages(queueUrl: pulumi.Input<string>): Promise<number> {
    const queueUrlStr = pulumi.output(queueUrl).get()
}
Example aws api function call.
This getApproximateNumberOfMessages function would get called in the callback function passed to the aws.lambda.CallbackFunction resource.
For example,
Copy code
const cbFn = new aws.lambda.CallbackFunction(`${name}-callback-fn`, {
    name: `${name}-handler`,
    role: args.role,
    callback: async function (event: aws.cloudwatch.EventRuleEvent) {
        await getApproximateNumberOfMessages(queueUrl)
    }
});
b
providing a callback in the languages that support it for the lambda relies on function serialziation. So if your function cannot work after being deserialized (because it calls out to an external function) than it will not work. I personally would instead pass my lambda function as a string and I would use
Output.apply(..)
to interpolate the values into the function that you need to, or you could set the values that the function needs as environment variables on the lambda and have the lambda access them
f
I have been warned to not create resources in apply before.
b
I am not saying that you should create resources in apply.
f
Oh. What did you mean? I interpreted that as:
Copy code
queueUrl.apply(url => {
    const cbFn = new aws.lambda.CallbackFunction(`${name}-callback-fn`, {
        name: `${name}-handler`,
        role: args.role,
        callback: async function (event: aws.cloudwatch.EventRuleEvent) {
            await getApproximateNumberOfMessages(url)
        }
    });
})
b
Can you link me the reference for
CallbackFunction
? Because all I see here is `Function`: https://www.pulumi.com/docs/reference/pkg/aws/lambda/?iaid=no-experiment Then I could explain better
b
I'm saying to pass the function as a string and interpolate your value in. Here you can see that
FunctionArgs
takes in an
Archive
in the
code
input. So you could make your archive with a
StringAsset
after interpolating your queue URL. So your code could be:
Copy code
var code = queueUrl.apply(url => {
    return @"async function (event: aws.cloudwatch.EventRuleEvent) {
        var url = ${url};
        // do work
    }";
});
Using whatever string interpolation looks like. And now your function is an
Output<string>
which can be passed
f
Oh, I'm using Pulumi's function serialization.
Don't think I want to convert to strings.
b
yes I was saying I don't think it will work with function serialization unless you use environment variables.
you can't serialize a result that is acquired asynchonously without also making the serialziation result async
f
Makes sense. So then the question is why isn't function serialization async?
I think the environment var idea will work.
Woot! Thank you @bored-oyster-3147
b
think about how function serialization must work - you provide a function to the
callback
parameter. Pulumi is not examining the inside of your function, it can't really do that. All it can do is serialize the function not knowing it's contents. It has no awareness of the fact that your function is calling out to some
Input<T>
or
Output<T>
The function serialization exists purely as a QOL thing in the languages that support it so that you can write your lambda in the same file/language that you are writing your pulumi code
✔️ 1
no problem hope that works