mirror of https://github.com/pulumi/pulumi.git
472e6bdd50
As of https://github.com/pulumi/pulumi/pull/13315 (which shipped in [v3.75.0](https://github.com/pulumi/pulumi/releases/tag/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 does two things: 1. Provides a way to opt-out of always serializing the provider as a secret. 2. Allows Outputs to be captured during serialization of the provider, which wasn't previously possible. ## 1. Opt-out of always serializing as secret A new attribute, `serialize_as_secret_always`, can be set on a subclass of `ResourceProvider` to opt-out of always serializing the provider as a secret. If you know you don't have any secrets being serialized into the provider and want to avoid the encryption overhead, you can set this attribute to `False`. ```python class MyProvider(ResourceProvider): serialize_as_secret_always = False def create(self, props): # Doesn't have any secrets that need encrypting ... ``` ## 2. Allow Outputs to be captured If you currently try to capture an `Output`, it fails when serializing the provider with: ``` TypeError: cannot pickle '_asyncio.Future' object ``` This change allows Outputs to be captured/serialized for dynamic providers, including secret Outputs. This aligns Python dynamic providers with [Node.js](https://github.com/pulumi/pulumi/pull/13329). ```python import pulumi from pulumi.dynamic import CreateResult, Resource, ResourceProvider config = pulumi.Config() password = config.require_secret("password") class SimpleProvider(ResourceProvider): 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) ``` Note: In the above example, we didn't have to specify `serialize_as_secret_always` since the default behavior is to always serialize the provider as a secret. If we wanted to, we could have specified `serialize_as_secret_always = False` and it still would have serialized the provider as a secret, since it captured `password` which is a secret Output. If `serialize_as_secret_always = False` was specified and no secrets were captured, then the provider would not be serialized as a secret. We plan to recommend this approach to capturing secrets for both Node.js and Python dynamic providers after this change. Fixes #15539 |
||
---|---|---|
.. | ||
about | ||
aliases | ||
backend/diy | ||
cloud_secrets_provider | ||
component_provider_schema | ||
config_basic | ||
config_capture_e2e/nodejs | ||
config_missing | ||
config_secrets_warn | ||
construct_component | ||
construct_component_configure_provider | ||
construct_component_error_apply | ||
construct_component_id_output | ||
construct_component_methods | ||
construct_component_methods_errors | ||
construct_component_methods_provider | ||
construct_component_methods_resources | ||
construct_component_methods_unknown | ||
construct_component_output_values | ||
construct_component_plain | ||
construct_component_provider | ||
construct_component_provider_explicit | ||
construct_component_provider_propagation | ||
construct_component_resource_options | ||
construct_component_slow | ||
construct_component_unknown | ||
construct_nested_component/go | ||
custom_timeouts | ||
delete_before_create | ||
deleted_with | ||
dependency_steps | ||
double_pending_delete | ||
duplicate_urns | ||
dynamic | ||
ee_perf | ||
empty | ||
enums | ||
environments_basic | ||
environments_merge | ||
exclude_protected | ||
explicit_provider | ||
gather_plugin | ||
get_created | ||
get_resource | ||
go | ||
invalid_package_json | ||
large_resource | ||
nodejs | ||
partial_state | ||
partial_values | ||
policy | ||
printf | ||
project_main | ||
project_main_abs | ||
project_main_parent/foo | ||
protect_resources | ||
provider_secret_config | ||
python | ||
python_await | ||
query | ||
read | ||
recreate_resource_check | ||
refresh/go | ||
resource_refs_get_resource | ||
rotate_passphrase | ||
secret_outputs | ||
single_resource | ||
stack_bad_parenting | ||
stack_dependencies | ||
stack_outputs | ||
stack_outputs_program_error | ||
stack_outputs_resource_error | ||
stack_parenting | ||
stack_project_name | ||
state_rename_parent | ||
steps | ||
targets | ||
transformations | ||
transforms | ||
tsconfig | ||
types | ||
unsafe_snapshot_tests/bad_resource | ||
valid-property-names | ||
.gitignore | ||
appdash_test.go | ||
component_setup.sh | ||
integration_acceptance_test.go | ||
integration_go_acceptance_test.go | ||
integration_go_test.go | ||
integration_nodejs_acceptance_test.go | ||
integration_nodejs_test.go | ||
integration_python_acceptance_test.go | ||
integration_python_test.go | ||
integration_test.go | ||
integration_util_test.go |