Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Python dynamic providers to capture secrets #15864

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

justinvp
Copy link
Member

@justinvp justinvp commented Apr 4, 2024

As of #13315 (which shipped in v3.75.0), __provider (the serialized provider string) is always set to a secret in the state. This can lead to poor performance when there are a lot of dynamic resources and the serialized provider does not actually have any secrets.

This change allows Outputs to be captured during serialization of the provider, which wasn't previously possible.

Additionally, a new attribute, auto_secret, can be set on the ResourceProvider subclass to opt-in to automatically determining the secretness based on whether any secret Outputs were captured during serialization of the provider. auto_secret is False by default, which makes __provider always a secret (current behavior). If set to True, __provider will only be a secret if secret Outputs were captured during serialization of the provider.

Setting auto_secret to True aligns Python dynamic providers with Node.js.

import pulumi
from pulumi.dynamic import CreateResult, Resource, ResourceProvider

config = pulumi.Config()
password = config.require_secret("password")

class SimpleProvider(ResourceProvider):
    auto_secret = True

    def create(self, props):
        # Need to use `password.get()` to get the underlying value of the secret from within the serialized code.
        # This simulates using this as a credential to talk to an external system.
        return CreateResult("0", { "authenticated": "200" if password.get() == "s3cret" else "401" })

class SimpleResource(Resource):
    authenticated: pulumi.Output[str]

    def __init__(self, name):
        super().__init__(SimpleProvider(), name, { "authenticated": None })


r = SimpleResource("foo")
pulumi.export("out", r.authenticated)

Fixes #15539

This allows the serialization used by dynamic providers to capture secrets, and if so, marks the resulting input value as a secret so that the `__provider` property will be a secret in the state.

The `__provider` property will no longer always be a secret. It will only be marked as a secret if a secret was captured during serialization of the provider.

Note: Previously, it wasn't possible to capture Outputs when serializing the resource provider. This change makes it possible and allows secrets to be captured.
@pulumi-bot
Copy link
Contributor

Changelog

[uncommitted] (2024-04-04)

Features

  • [sdk/python] Allow Python dynamic providers to capture secrets
    #15864

By default, we continue to always make `__provider` a secret, unless `auto_secret` is set to `True`, in which case we only make `__provider` a secret if any secret Outputs were captured.
@justinvp justinvp marked this pull request as ready for review April 4, 2024 22:27
@justinvp justinvp requested a review from a team as a code owner April 4, 2024 22:27
@justinvp
Copy link
Member Author

justinvp commented Apr 8, 2024

One thing I still want to check is the behavior when there are unknowns, i.e. check the Node.js behavior and match that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide a way to opt-out of secretness for Python dynamic providers
2 participants