pulumi / pulumi-dotnet

.NET support for Pulumi
Apache License 2.0
28 stars 25 forks source link

Static `StackReference` not working with Inline program #190

Closed PhilBroderickCrezco closed 1 year ago

PhilBroderickCrezco commented 1 year ago

What happened?

I'm trying to set up some automation with the Automation API + inline programs, and use stack references in the program (with StackReference class in C#) to retrieve outputs from another stack. As these outputs need to be accessed from various classes, we opt to create a static class that holds all the stack outputs, and reference that where we need.

This works create in a classic Pulumi CLI driven app, but the stack reference resource doesn't get created in the inline program version + Automation API. The Pulumi previews correctly show the output values when they are referenced in other resources, but when running pulumi up (via Automation API), the stack reference resource never gets created, throwing an error similar to:

image (1)

Example

Static class with StackReference resource:

public static class StackReferenceConfig
{
    private static readonly StackReference StackRef = new(<STACK_REF>);

    public static object StackOutput = StackRef.RequireOutput(<OUTPUT_NAME>);
}

Inline program that uses the static class:

public class InlineStack : Stack
{
    public InlineStack()
    {
        var stackOutput = StackReferenceConfig.StackOutput;
    }
}

Program.cs that uses Automation API to create + deploy stack:

var stack = await LocalWorkspace.CreateOrSelectStackAsync(new InlineProgramArgs(<PROJECT>, <STACK>, PulumiFn.Create<InlineStack>()));

var preview = await stack.PreviewAsync(new PreviewOptions
{
    OnStandardOutput = Console.WriteLine
});

var update = await stack.UpAsync(new UpOptions
{
    OnStandardOutput = Console.WriteLine
});

Output of pulumi about

CLI
Version      3.78.0
Go Version   go1.20.7
Go Compiler  gc

Host
OS       Microsoft Windows 11 Pro
Version  10.0.22621 Build 22621
Arch     x86_64

Dependencies:
NAME                VERSION
Pulumi              3.57.0
Pulumi.Automation   3.57.0

Additional context

Simply changing Program.cs to:

return await Deployment.RunAsync<InlineStack>();

with appropriate Pulumi.yaml config file, the stack reference resource will be created as expected.

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

Frassle commented 1 year ago

I would not expect this to work, and I don't think there's anything we can do to make it work. Pulumi objects are sensitive to the async context they are created in, you can't reuse an object across multiple deployment runs.

If you want this to work you need to ensure the StackRef is new'd up for each deployment run, the easiest way of which is to just not make this object static.

There probably are ways to make this still look "static" like with AsyncLocal but I'd consider that a very advanced use case and would only recommend it if you really well understand how dotnet execution contexts and async locals work.