Introducing envVarMappings for Provider Credentials
Source: Pulumi Blog
Running multiple providers with different credentials
Providers traditionally rely on fixed environment variable names (e.g., AWS_ACCESS_KEY_ID, ARM_CLIENT_SECRET). This made it difficult to configure two providers of the same type—such as two AWS providers targeting different accounts—in a single Pulumi program using environment variables.
Pulumi v3.220.0 introduces envVarMappings, a new resource option that lets you remap provider environment variables to custom keys, solving this limitation.
Authentication options
When configuring a Pulumi provider, you have two primary ways to supply credentials:
1. Pulumi configuration (stored in Pulumi.yaml)
pulumi config set azure-native:clientSecret --secret
2. Environment variables
export ARM_CLIENT_SECRET=1234567
Environment variables are especially handy in CI pipelines or when you prefer not to write secrets to the state file (even when encrypted). However, the hard‑coded variable names required by providers can cause problems in several scenarios.
When the built‑in variables fall short
- Multiple provider instances needing different credentials but sharing the same variable name.
For example, using two explicit Azure providers for different subscriptions could not be configured via separate environment variables. The only alternative was to set the credentials in the provider configuration, which writes secrets to state and can generate noisy diffs during token rotation.
Remapping environment variables with envVarMappings
envVarMappings allows you to tell a provider to read its expected variable from a custom‑defined environment variable.
Concept:
“For any environment variable that my Pulumi provider expects, I want to be able to tell the provider to use the value of a custom‑defined environment variable instead.”
Example
Suppose a provider expects ARM_CLIENT_SECRET, but you want it to use a different value defined in CUSTOM_ARM_CLIENT_SECRET.
export CUSTOM_ARM_CLIENT_SECRET=7654321
Then configure the provider with a mapping:
TypeScript
import * as pulumi from "@pulumi/pulumi";
import * as command from "@pulumi/command";
const provider = new command.Provider("command-provider", {}, {
envVarMappings: {
// If CUSTOM_ARM_CLIENT_SECRET exists, provider sees the value as ARM_CLIENT_SECRET
"CUSTOM_ARM_CLIENT_SECRET": "ARM_CLIENT_SECRET",
},
});
Python
import pulumi
import pulumi_command as command
provider = command.Provider("command-provider",
opts=pulumi.ResourceOptions(
env_var_mappings={
# If CUSTOM_ARM_CLIENT_SECRET exists, provider sees the value as ARM_CLIENT_SECRET
"CUSTOM_ARM_CLIENT_SECRET": "ARM_CLIENT_SECRET",
}
)
)
Go
provider, err := command.NewProvider(ctx,
"command-provider",
&command.ProviderArgs{},
pulumi.EnvVarMappings(map[string]string{
// If CUSTOM_ARM_CLIENT_SECRET exists, provider sees the value as ARM_CLIENT_SECRET
"CUSTOM_ARM_CLIENT_SECRET": "ARM_CLIENT_SECRET",
}),
)
if err != nil {
return err
}
C#
var provider = new Command.Provider("command-provider",
new Command.ProviderArgs(),
new CustomResourceOptions
{
EnvVarMappings = new Dictionary
{
// If CUSTOM_ARM_CLIENT_SECRET exists, provider sees the value as ARM_CLIENT_SECRET
{ "CUSTOM_ARM_CLIENT_SECRET", "ARM_CLIENT_SECRET" }
}
});
Java
var provider = new Provider("command-provider",
ProviderArgs.Empty,
CustomResourceOptions.builder()
.envVarMappings(Map.of(
// If CUSTOM_ARM_CLIENT_SECRET exists, provider sees the value as ARM_CLIENT_SECRET
"CUSTOM_ARM_CLIENT_SECRET", "ARM_CLIENT_SECRET"))
.build());
YAML (Pulumi YAML)
resources:
command-provider:
type: pulumi:providers:command
options:
envVarMappings:
# If CUSTOM_ARM_CLIENT_SECRET exists, provider sees the value as ARM_CLIENT_SECRET
CUSTOM_ARM_CLIENT_SECRET: ARM_CLIENT_SECRET
With envVarMappings, each provider can read its required variables from uniquely named environment variables, enabling multiple credential sets within the same program.
Try it today
Use Pulumi v3.220.0 or later and add envVarMappings to any provider that supports it. For complete reference, see the official envVarMappings documentation.
Happy coding!