Create GCP Regional Secret Versions

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 FREE

Frequently Asked Questions

Updates & Lifecycle
Why does updating my secret data cause downtime?
The secretData field is immutable. Updating it forces resource replacement: the existing version is deleted before the new one is created, potentially causing outages.
How can I update secret data without downtime?
Use the createBeforeDestroy lifecycle block to create the new secret version before destroying the old one.
Can I update the secret data after creation?
No, secretData is immutable. Any change forces replacement of the entire resource.
Secret Data & Encoding
How do I store binary data or certificates in a secret version?
Set isSecretDataBase64 to true and provide base64-encoded data. You can use functions like filebase64() to encode files.
What's the maximum size for secret data?
Secret data must be no larger than 64KiB.
Deletion & State Management
What are my options for removing or disabling a secret version?

You have three options via deletionPolicy:

  1. DELETE (default) - Permanently deletes the version
  2. DISABLE - Disables the version without deleting it
  3. ABANDON - Leaves the version in place when removing from Pulumi
How do I disable a secret version without deleting it?
Set enabled to false, or use deletionPolicy set to DISABLE when removing the resource.

Using a different cloud?

Explore security guides for other cloud providers: