The gcp:secretmanager/regionalSecretVersion:RegionalSecretVersion resource, part of the Pulumi GCP provider, stores a specific version of secret data within a regional Secret Manager secret. This guide focuses on three capabilities: plaintext and base64-encoded data storage, version state control, and deletion policy configuration.
Secret versions belong to RegionalSecret resources that define the container, location, and access controls. The examples are intentionally small. Combine them with your own secret definitions and IAM policies.
Store plaintext secret data in a version
Most workflows begin by storing sensitive data as a new version of a regional secret.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const secret_basic = new gcp.secretmanager.RegionalSecret("secret-basic", {
secretId: "secret-version",
location: "us-central1",
});
const regionalSecretVersionBasic = new gcp.secretmanager.RegionalSecretVersion("regional_secret_version_basic", {
secret: secret_basic.id,
secretData: "secret-data",
});
import pulumi
import pulumi_gcp as gcp
secret_basic = gcp.secretmanager.RegionalSecret("secret-basic",
secret_id="secret-version",
location="us-central1")
regional_secret_version_basic = gcp.secretmanager.RegionalSecretVersion("regional_secret_version_basic",
secret=secret_basic.id,
secret_data="secret-data")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
secret_basic, err := secretmanager.NewRegionalSecret(ctx, "secret-basic", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("secret-version"),
Location: pulumi.String("us-central1"),
})
if err != nil {
return err
}
_, err = secretmanager.NewRegionalSecretVersion(ctx, "regional_secret_version_basic", &secretmanager.RegionalSecretVersionArgs{
Secret: secret_basic.ID(),
SecretData: pulumi.String("secret-data"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var secret_basic = new Gcp.SecretManager.RegionalSecret("secret-basic", new()
{
SecretId = "secret-version",
Location = "us-central1",
});
var regionalSecretVersionBasic = new Gcp.SecretManager.RegionalSecretVersion("regional_secret_version_basic", new()
{
Secret = secret_basic.Id,
SecretData = "secret-data",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.secretmanager.RegionalSecret;
import com.pulumi.gcp.secretmanager.RegionalSecretArgs;
import com.pulumi.gcp.secretmanager.RegionalSecretVersion;
import com.pulumi.gcp.secretmanager.RegionalSecretVersionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var secret_basic = new RegionalSecret("secret-basic", RegionalSecretArgs.builder()
.secretId("secret-version")
.location("us-central1")
.build());
var regionalSecretVersionBasic = new RegionalSecretVersion("regionalSecretVersionBasic", RegionalSecretVersionArgs.builder()
.secret(secret_basic.id())
.secretData("secret-data")
.build());
}
}
resources:
secret-basic:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: secret-version
location: us-central1
regionalSecretVersionBasic:
type: gcp:secretmanager:RegionalSecretVersion
name: regional_secret_version_basic
properties:
secret: ${["secret-basic"].id}
secretData: secret-data
The secret property references the parent RegionalSecret by ID. The secretData property contains the actual payload, limited to 64KiB. Each time you update secretData, Pulumi creates a new version; the Warning in the documentation notes this force-new behavior.
Store base64-encoded binary data
Binary files like certificates need base64 encoding before storage.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as std from "@pulumi/std";
const secret_basic = new gcp.secretmanager.RegionalSecret("secret-basic", {
secretId: "secret-version",
location: "us-central1",
});
const regionalSecretVersionBase64 = new gcp.secretmanager.RegionalSecretVersion("regional_secret_version_base64", {
secret: secret_basic.id,
secretData: std.filebase64({
input: "secret-data.pfx",
}).then(invoke => invoke.result),
isSecretDataBase64: true,
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std
secret_basic = gcp.secretmanager.RegionalSecret("secret-basic",
secret_id="secret-version",
location="us-central1")
regional_secret_version_base64 = gcp.secretmanager.RegionalSecretVersion("regional_secret_version_base64",
secret=secret_basic.id,
secret_data=std.filebase64(input="secret-data.pfx").result,
is_secret_data_base64=True)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
secret_basic, err := secretmanager.NewRegionalSecret(ctx, "secret-basic", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("secret-version"),
Location: pulumi.String("us-central1"),
})
if err != nil {
return err
}
invokeFilebase64, err := std.Filebase64(ctx, &std.Filebase64Args{
Input: "secret-data.pfx",
}, nil)
if err != nil {
return err
}
_, err = secretmanager.NewRegionalSecretVersion(ctx, "regional_secret_version_base64", &secretmanager.RegionalSecretVersionArgs{
Secret: secret_basic.ID(),
SecretData: pulumi.String(invokeFilebase64.Result),
IsSecretDataBase64: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var secret_basic = new Gcp.SecretManager.RegionalSecret("secret-basic", new()
{
SecretId = "secret-version",
Location = "us-central1",
});
var regionalSecretVersionBase64 = new Gcp.SecretManager.RegionalSecretVersion("regional_secret_version_base64", new()
{
Secret = secret_basic.Id,
SecretData = Std.Filebase64.Invoke(new()
{
Input = "secret-data.pfx",
}).Apply(invoke => invoke.Result),
IsSecretDataBase64 = true,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.secretmanager.RegionalSecret;
import com.pulumi.gcp.secretmanager.RegionalSecretArgs;
import com.pulumi.gcp.secretmanager.RegionalSecretVersion;
import com.pulumi.gcp.secretmanager.RegionalSecretVersionArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.Filebase64Args;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var secret_basic = new RegionalSecret("secret-basic", RegionalSecretArgs.builder()
.secretId("secret-version")
.location("us-central1")
.build());
var regionalSecretVersionBase64 = new RegionalSecretVersion("regionalSecretVersionBase64", RegionalSecretVersionArgs.builder()
.secret(secret_basic.id())
.secretData(StdFunctions.filebase64(Filebase64Args.builder()
.input("secret-data.pfx")
.build()).result())
.isSecretDataBase64(true)
.build());
}
}
resources:
secret-basic:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: secret-version
location: us-central1
regionalSecretVersionBase64:
type: gcp:secretmanager:RegionalSecretVersion
name: regional_secret_version_base64
properties:
secret: ${["secret-basic"].id}
secretData:
fn::invoke:
function: std:filebase64
arguments:
input: secret-data.pfx
return: result
isSecretDataBase64: true
The isSecretDataBase64 property tells Secret Manager the data is already encoded, preventing double-encoding. The filebase64 function reads and encodes the file in one step. This is useful for PFX certificates, private keys, or other binary formats.
Create a disabled version for staged rollout
Teams preparing new credentials often create versions in a disabled state, then enable them during maintenance windows.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const secret_basic = new gcp.secretmanager.RegionalSecret("secret-basic", {
secretId: "secret-version",
location: "us-central1",
});
const regionalSecretVersionDisabled = new gcp.secretmanager.RegionalSecretVersion("regional_secret_version_disabled", {
secret: secret_basic.id,
secretData: "secret-data",
enabled: false,
});
import pulumi
import pulumi_gcp as gcp
secret_basic = gcp.secretmanager.RegionalSecret("secret-basic",
secret_id="secret-version",
location="us-central1")
regional_secret_version_disabled = gcp.secretmanager.RegionalSecretVersion("regional_secret_version_disabled",
secret=secret_basic.id,
secret_data="secret-data",
enabled=False)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
secret_basic, err := secretmanager.NewRegionalSecret(ctx, "secret-basic", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("secret-version"),
Location: pulumi.String("us-central1"),
})
if err != nil {
return err
}
_, err = secretmanager.NewRegionalSecretVersion(ctx, "regional_secret_version_disabled", &secretmanager.RegionalSecretVersionArgs{
Secret: secret_basic.ID(),
SecretData: pulumi.String("secret-data"),
Enabled: pulumi.Bool(false),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var secret_basic = new Gcp.SecretManager.RegionalSecret("secret-basic", new()
{
SecretId = "secret-version",
Location = "us-central1",
});
var regionalSecretVersionDisabled = new Gcp.SecretManager.RegionalSecretVersion("regional_secret_version_disabled", new()
{
Secret = secret_basic.Id,
SecretData = "secret-data",
Enabled = false,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.secretmanager.RegionalSecret;
import com.pulumi.gcp.secretmanager.RegionalSecretArgs;
import com.pulumi.gcp.secretmanager.RegionalSecretVersion;
import com.pulumi.gcp.secretmanager.RegionalSecretVersionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var secret_basic = new RegionalSecret("secret-basic", RegionalSecretArgs.builder()
.secretId("secret-version")
.location("us-central1")
.build());
var regionalSecretVersionDisabled = new RegionalSecretVersion("regionalSecretVersionDisabled", RegionalSecretVersionArgs.builder()
.secret(secret_basic.id())
.secretData("secret-data")
.enabled(false)
.build());
}
}
resources:
secret-basic:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: secret-version
location: us-central1
regionalSecretVersionDisabled:
type: gcp:secretmanager:RegionalSecretVersion
name: regional_secret_version_disabled
properties:
secret: ${["secret-basic"].id}
secretData: secret-data
enabled: false
The enabled property controls whether applications can access this version. Setting it to false creates the version but prevents retrieval until you flip it to true. This supports blue-green credential rotation.
Preserve versions when removing from Pulumi state
When migrating infrastructure or reorganizing stacks, you may need to remove a version from state without destroying the secret data.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const secret_basic = new gcp.secretmanager.RegionalSecret("secret-basic", {
secretId: "secret-version",
location: "us-central1",
});
const regionalSecretVersionDeletionPolicy = new gcp.secretmanager.RegionalSecretVersion("regional_secret_version_deletion_policy", {
secret: secret_basic.id,
secretData: "secret-data",
deletionPolicy: "ABANDON",
});
import pulumi
import pulumi_gcp as gcp
secret_basic = gcp.secretmanager.RegionalSecret("secret-basic",
secret_id="secret-version",
location="us-central1")
regional_secret_version_deletion_policy = gcp.secretmanager.RegionalSecretVersion("regional_secret_version_deletion_policy",
secret=secret_basic.id,
secret_data="secret-data",
deletion_policy="ABANDON")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
secret_basic, err := secretmanager.NewRegionalSecret(ctx, "secret-basic", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("secret-version"),
Location: pulumi.String("us-central1"),
})
if err != nil {
return err
}
_, err = secretmanager.NewRegionalSecretVersion(ctx, "regional_secret_version_deletion_policy", &secretmanager.RegionalSecretVersionArgs{
Secret: secret_basic.ID(),
SecretData: pulumi.String("secret-data"),
DeletionPolicy: pulumi.String("ABANDON"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var secret_basic = new Gcp.SecretManager.RegionalSecret("secret-basic", new()
{
SecretId = "secret-version",
Location = "us-central1",
});
var regionalSecretVersionDeletionPolicy = new Gcp.SecretManager.RegionalSecretVersion("regional_secret_version_deletion_policy", new()
{
Secret = secret_basic.Id,
SecretData = "secret-data",
DeletionPolicy = "ABANDON",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.secretmanager.RegionalSecret;
import com.pulumi.gcp.secretmanager.RegionalSecretArgs;
import com.pulumi.gcp.secretmanager.RegionalSecretVersion;
import com.pulumi.gcp.secretmanager.RegionalSecretVersionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var secret_basic = new RegionalSecret("secret-basic", RegionalSecretArgs.builder()
.secretId("secret-version")
.location("us-central1")
.build());
var regionalSecretVersionDeletionPolicy = new RegionalSecretVersion("regionalSecretVersionDeletionPolicy", RegionalSecretVersionArgs.builder()
.secret(secret_basic.id())
.secretData("secret-data")
.deletionPolicy("ABANDON")
.build());
}
}
resources:
secret-basic:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: secret-version
location: us-central1
regionalSecretVersionDeletionPolicy:
type: gcp:secretmanager:RegionalSecretVersion
name: regional_secret_version_deletion_policy
properties:
secret: ${["secret-basic"].id}
secretData: secret-data
deletionPolicy: ABANDON
The deletionPolicy property set to ABANDON removes the version from Pulumi’s state but leaves it intact in Secret Manager. This is an alternative to the default DELETE behavior, useful during stack migrations.
Disable versions instead of deleting them
Compliance requirements may require keeping version history even when credentials are rotated.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const secret_basic = new gcp.secretmanager.RegionalSecret("secret-basic", {
secretId: "secret-version",
location: "us-central1",
});
const regionalSecretVersionDeletionPolicy = new gcp.secretmanager.RegionalSecretVersion("regional_secret_version_deletion_policy", {
secret: secret_basic.id,
secretData: "secret-data",
deletionPolicy: "DISABLE",
});
import pulumi
import pulumi_gcp as gcp
secret_basic = gcp.secretmanager.RegionalSecret("secret-basic",
secret_id="secret-version",
location="us-central1")
regional_secret_version_deletion_policy = gcp.secretmanager.RegionalSecretVersion("regional_secret_version_deletion_policy",
secret=secret_basic.id,
secret_data="secret-data",
deletion_policy="DISABLE")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
secret_basic, err := secretmanager.NewRegionalSecret(ctx, "secret-basic", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("secret-version"),
Location: pulumi.String("us-central1"),
})
if err != nil {
return err
}
_, err = secretmanager.NewRegionalSecretVersion(ctx, "regional_secret_version_deletion_policy", &secretmanager.RegionalSecretVersionArgs{
Secret: secret_basic.ID(),
SecretData: pulumi.String("secret-data"),
DeletionPolicy: pulumi.String("DISABLE"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var secret_basic = new Gcp.SecretManager.RegionalSecret("secret-basic", new()
{
SecretId = "secret-version",
Location = "us-central1",
});
var regionalSecretVersionDeletionPolicy = new Gcp.SecretManager.RegionalSecretVersion("regional_secret_version_deletion_policy", new()
{
Secret = secret_basic.Id,
SecretData = "secret-data",
DeletionPolicy = "DISABLE",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.secretmanager.RegionalSecret;
import com.pulumi.gcp.secretmanager.RegionalSecretArgs;
import com.pulumi.gcp.secretmanager.RegionalSecretVersion;
import com.pulumi.gcp.secretmanager.RegionalSecretVersionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var secret_basic = new RegionalSecret("secret-basic", RegionalSecretArgs.builder()
.secretId("secret-version")
.location("us-central1")
.build());
var regionalSecretVersionDeletionPolicy = new RegionalSecretVersion("regionalSecretVersionDeletionPolicy", RegionalSecretVersionArgs.builder()
.secret(secret_basic.id())
.secretData("secret-data")
.deletionPolicy("DISABLE")
.build());
}
}
resources:
secret-basic:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: secret-version
location: us-central1
regionalSecretVersionDeletionPolicy:
type: gcp:secretmanager:RegionalSecretVersion
name: regional_secret_version_deletion_policy
properties:
secret: ${["secret-basic"].id}
secretData: secret-data
deletionPolicy: DISABLE
Setting deletionPolicy to DISABLE marks the version as inactive without removing it from Secret Manager. This maintains audit trails while preventing access. It’s another alternative to DELETE, focused on compliance rather than migration.
Beyond these examples
These snippets focus on specific version-level features: plaintext and base64-encoded data storage, version state management, and deletion policies. They’re intentionally minimal rather than full secret management solutions.
The examples reference pre-existing infrastructure such as RegionalSecret resources (parent secrets) and local files for base64 encoding. They focus on configuring the version rather than provisioning the secret container or access controls.
To keep things focused, common version patterns are omitted, including:
- Customer-managed encryption keys (customerManagedEncryptions)
- Version lifecycle management and rotation
- Access control and IAM bindings
- Cross-region replication
These omissions are intentional: the goal is to illustrate how each version feature is wired, not provide drop-in secrets management modules. See the RegionalSecretVersion resource reference for all available configuration options.
Let's create GCP Regional Secret Versions
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Updates & Lifecycle
secretData field is immutable. Updating it forces resource replacement: the existing version is deleted before the new one is created, potentially causing outages.createBeforeDestroy lifecycle block to create the new secret version before destroying the old one.secretData is immutable. Any change forces replacement of the entire resource.Secret Data & Encoding
isSecretDataBase64 to true and provide base64-encoded data. You can use functions like filebase64() to encode files.Deletion & State Management
You have three options via deletionPolicy:
- DELETE (default) - Permanently deletes the version
- DISABLE - Disables the version without deleting it
- ABANDON - Leaves the version in place when removing from Pulumi
enabled to false, or use deletionPolicy set to DISABLE when removing the resource.