The gcp:secretmanager/regionalSecret:RegionalSecret resource, part of the Pulumi GCP provider, defines a regional secret container whose versions are created and accessed within a single GCP region. This guide focuses on three capabilities: creating secrets with metadata, customer-managed encryption, and rotation scheduling.
Regional secrets are containers for sensitive data; the actual secret values live in separate RegionalSecretVersion resources. The examples are intentionally small. Combine them with your own KMS keys, Pub/Sub topics, and IAM policies.
Create a regional secret with labels and annotations
Most deployments start by creating a secret container in a specific region with metadata for tracking and discovery.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const regional_secret_basic = new gcp.secretmanager.RegionalSecret("regional-secret-basic", {
secretId: "tf-reg-secret",
location: "us-central1",
labels: {
label: "my-label",
},
annotations: {
key1: "value1",
key2: "value2",
key3: "value3",
},
deletionProtection: false,
});
import pulumi
import pulumi_gcp as gcp
regional_secret_basic = gcp.secretmanager.RegionalSecret("regional-secret-basic",
secret_id="tf-reg-secret",
location="us-central1",
labels={
"label": "my-label",
},
annotations={
"key1": "value1",
"key2": "value2",
"key3": "value3",
},
deletion_protection=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 {
_, err := secretmanager.NewRegionalSecret(ctx, "regional-secret-basic", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("tf-reg-secret"),
Location: pulumi.String("us-central1"),
Labels: pulumi.StringMap{
"label": pulumi.String("my-label"),
},
Annotations: pulumi.StringMap{
"key1": pulumi.String("value1"),
"key2": pulumi.String("value2"),
"key3": pulumi.String("value3"),
},
DeletionProtection: 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 regional_secret_basic = new Gcp.SecretManager.RegionalSecret("regional-secret-basic", new()
{
SecretId = "tf-reg-secret",
Location = "us-central1",
Labels =
{
{ "label", "my-label" },
},
Annotations =
{
{ "key1", "value1" },
{ "key2", "value2" },
{ "key3", "value3" },
},
DeletionProtection = 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 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 regional_secret_basic = new RegionalSecret("regional-secret-basic", RegionalSecretArgs.builder()
.secretId("tf-reg-secret")
.location("us-central1")
.labels(Map.of("label", "my-label"))
.annotations(Map.ofEntries(
Map.entry("key1", "value1"),
Map.entry("key2", "value2"),
Map.entry("key3", "value3")
))
.deletionProtection(false)
.build());
}
}
resources:
regional-secret-basic:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: tf-reg-secret
location: us-central1
labels:
label: my-label
annotations:
key1: value1
key2: value2
key3: value3
deletionProtection: false
The secretId provides a unique identifier within the project, while location pins the secret to a specific region (e.g., us-central1). Labels and annotations add organizational metadata: labels for filtering and cost tracking, annotations for tool-specific state. The deletionProtection flag prevents accidental deletion during Pulumi operations.
Encrypt secrets with customer-managed KMS keys
Organizations with compliance requirements often control their own encryption keys rather than using Google-managed encryption.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const project = gcp.organizations.getProject({});
const kms_secret_binding = new gcp.kms.CryptoKeyIAMMember("kms-secret-binding", {
cryptoKeyId: "kms-key",
role: "roles/cloudkms.cryptoKeyEncrypterDecrypter",
member: project.then(project => `serviceAccount:service-${project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com`),
});
const regional_secret_with_cmek = new gcp.secretmanager.RegionalSecret("regional-secret-with-cmek", {
secretId: "tf-reg-secret",
location: "us-central1",
customerManagedEncryption: {
kmsKeyName: "kms-key",
},
}, {
dependsOn: [kms_secret_binding],
});
import pulumi
import pulumi_gcp as gcp
project = gcp.organizations.get_project()
kms_secret_binding = gcp.kms.CryptoKeyIAMMember("kms-secret-binding",
crypto_key_id="kms-key",
role="roles/cloudkms.cryptoKeyEncrypterDecrypter",
member=f"serviceAccount:service-{project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com")
regional_secret_with_cmek = gcp.secretmanager.RegionalSecret("regional-secret-with-cmek",
secret_id="tf-reg-secret",
location="us-central1",
customer_managed_encryption={
"kms_key_name": "kms-key",
},
opts = pulumi.ResourceOptions(depends_on=[kms_secret_binding]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/kms"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
"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 {
project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{}, nil)
if err != nil {
return err
}
kms_secret_binding, err := kms.NewCryptoKeyIAMMember(ctx, "kms-secret-binding", &kms.CryptoKeyIAMMemberArgs{
CryptoKeyId: pulumi.String("kms-key"),
Role: pulumi.String("roles/cloudkms.cryptoKeyEncrypterDecrypter"),
Member: pulumi.Sprintf("serviceAccount:service-%v@gcp-sa-secretmanager.iam.gserviceaccount.com", project.Number),
})
if err != nil {
return err
}
_, err = secretmanager.NewRegionalSecret(ctx, "regional-secret-with-cmek", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("tf-reg-secret"),
Location: pulumi.String("us-central1"),
CustomerManagedEncryption: &secretmanager.RegionalSecretCustomerManagedEncryptionArgs{
KmsKeyName: pulumi.String("kms-key"),
},
}, pulumi.DependsOn([]pulumi.Resource{
kms_secret_binding,
}))
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 project = Gcp.Organizations.GetProject.Invoke();
var kms_secret_binding = new Gcp.Kms.CryptoKeyIAMMember("kms-secret-binding", new()
{
CryptoKeyId = "kms-key",
Role = "roles/cloudkms.cryptoKeyEncrypterDecrypter",
Member = $"serviceAccount:service-{project.Apply(getProjectResult => getProjectResult.Number)}@gcp-sa-secretmanager.iam.gserviceaccount.com",
});
var regional_secret_with_cmek = new Gcp.SecretManager.RegionalSecret("regional-secret-with-cmek", new()
{
SecretId = "tf-reg-secret",
Location = "us-central1",
CustomerManagedEncryption = new Gcp.SecretManager.Inputs.RegionalSecretCustomerManagedEncryptionArgs
{
KmsKeyName = "kms-key",
},
}, new CustomResourceOptions
{
DependsOn =
{
kms_secret_binding,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetProjectArgs;
import com.pulumi.gcp.kms.CryptoKeyIAMMember;
import com.pulumi.gcp.kms.CryptoKeyIAMMemberArgs;
import com.pulumi.gcp.secretmanager.RegionalSecret;
import com.pulumi.gcp.secretmanager.RegionalSecretArgs;
import com.pulumi.gcp.secretmanager.inputs.RegionalSecretCustomerManagedEncryptionArgs;
import com.pulumi.resources.CustomResourceOptions;
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) {
final var project = OrganizationsFunctions.getProject(GetProjectArgs.builder()
.build());
var kms_secret_binding = new CryptoKeyIAMMember("kms-secret-binding", CryptoKeyIAMMemberArgs.builder()
.cryptoKeyId("kms-key")
.role("roles/cloudkms.cryptoKeyEncrypterDecrypter")
.member(String.format("serviceAccount:service-%s@gcp-sa-secretmanager.iam.gserviceaccount.com", project.number()))
.build());
var regional_secret_with_cmek = new RegionalSecret("regional-secret-with-cmek", RegionalSecretArgs.builder()
.secretId("tf-reg-secret")
.location("us-central1")
.customerManagedEncryption(RegionalSecretCustomerManagedEncryptionArgs.builder()
.kmsKeyName("kms-key")
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(kms_secret_binding)
.build());
}
}
resources:
kms-secret-binding:
type: gcp:kms:CryptoKeyIAMMember
properties:
cryptoKeyId: kms-key
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
member: serviceAccount:service-${project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com
regional-secret-with-cmek:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: tf-reg-secret
location: us-central1
customerManagedEncryption:
kmsKeyName: kms-key
options:
dependsOn:
- ${["kms-secret-binding"]}
variables:
project:
fn::invoke:
function: gcp:organizations:getProject
arguments: {}
The customerManagedEncryption block references a KMS key by name. Before creating the secret, you must grant the Secret Manager service account the cryptoKeyEncrypterDecrypter role on your KMS key. The dependsOn ensures the IAM binding exists before Secret Manager attempts encryption.
Schedule automatic rotation notifications
Applications that rotate credentials need notifications when it’s time to generate new versions.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const project = gcp.organizations.getProject({});
const topic = new gcp.pubsub.Topic("topic", {name: "tf-topic"});
const secretsManagerAccess = new gcp.pubsub.TopicIAMMember("secrets_manager_access", {
topic: topic.name,
role: "roles/pubsub.publisher",
member: project.then(project => `serviceAccount:service-${project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com`),
});
const regional_secret_with_rotation = new gcp.secretmanager.RegionalSecret("regional-secret-with-rotation", {
secretId: "tf-reg-secret",
location: "us-central1",
topics: [{
name: topic.id,
}],
rotation: {
rotationPeriod: "3600s",
nextRotationTime: "2045-11-30T00:00:00Z",
},
}, {
dependsOn: [secretsManagerAccess],
});
import pulumi
import pulumi_gcp as gcp
project = gcp.organizations.get_project()
topic = gcp.pubsub.Topic("topic", name="tf-topic")
secrets_manager_access = gcp.pubsub.TopicIAMMember("secrets_manager_access",
topic=topic.name,
role="roles/pubsub.publisher",
member=f"serviceAccount:service-{project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com")
regional_secret_with_rotation = gcp.secretmanager.RegionalSecret("regional-secret-with-rotation",
secret_id="tf-reg-secret",
location="us-central1",
topics=[{
"name": topic.id,
}],
rotation={
"rotation_period": "3600s",
"next_rotation_time": "2045-11-30T00:00:00Z",
},
opts = pulumi.ResourceOptions(depends_on=[secrets_manager_access]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/pubsub"
"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 {
project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{}, nil)
if err != nil {
return err
}
topic, err := pubsub.NewTopic(ctx, "topic", &pubsub.TopicArgs{
Name: pulumi.String("tf-topic"),
})
if err != nil {
return err
}
secretsManagerAccess, err := pubsub.NewTopicIAMMember(ctx, "secrets_manager_access", &pubsub.TopicIAMMemberArgs{
Topic: topic.Name,
Role: pulumi.String("roles/pubsub.publisher"),
Member: pulumi.Sprintf("serviceAccount:service-%v@gcp-sa-secretmanager.iam.gserviceaccount.com", project.Number),
})
if err != nil {
return err
}
_, err = secretmanager.NewRegionalSecret(ctx, "regional-secret-with-rotation", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("tf-reg-secret"),
Location: pulumi.String("us-central1"),
Topics: secretmanager.RegionalSecretTopicArray{
&secretmanager.RegionalSecretTopicArgs{
Name: topic.ID(),
},
},
Rotation: &secretmanager.RegionalSecretRotationArgs{
RotationPeriod: pulumi.String("3600s"),
NextRotationTime: pulumi.String("2045-11-30T00:00:00Z"),
},
}, pulumi.DependsOn([]pulumi.Resource{
secretsManagerAccess,
}))
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 project = Gcp.Organizations.GetProject.Invoke();
var topic = new Gcp.PubSub.Topic("topic", new()
{
Name = "tf-topic",
});
var secretsManagerAccess = new Gcp.PubSub.TopicIAMMember("secrets_manager_access", new()
{
Topic = topic.Name,
Role = "roles/pubsub.publisher",
Member = $"serviceAccount:service-{project.Apply(getProjectResult => getProjectResult.Number)}@gcp-sa-secretmanager.iam.gserviceaccount.com",
});
var regional_secret_with_rotation = new Gcp.SecretManager.RegionalSecret("regional-secret-with-rotation", new()
{
SecretId = "tf-reg-secret",
Location = "us-central1",
Topics = new[]
{
new Gcp.SecretManager.Inputs.RegionalSecretTopicArgs
{
Name = topic.Id,
},
},
Rotation = new Gcp.SecretManager.Inputs.RegionalSecretRotationArgs
{
RotationPeriod = "3600s",
NextRotationTime = "2045-11-30T00:00:00Z",
},
}, new CustomResourceOptions
{
DependsOn =
{
secretsManagerAccess,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetProjectArgs;
import com.pulumi.gcp.pubsub.Topic;
import com.pulumi.gcp.pubsub.TopicArgs;
import com.pulumi.gcp.pubsub.TopicIAMMember;
import com.pulumi.gcp.pubsub.TopicIAMMemberArgs;
import com.pulumi.gcp.secretmanager.RegionalSecret;
import com.pulumi.gcp.secretmanager.RegionalSecretArgs;
import com.pulumi.gcp.secretmanager.inputs.RegionalSecretTopicArgs;
import com.pulumi.gcp.secretmanager.inputs.RegionalSecretRotationArgs;
import com.pulumi.resources.CustomResourceOptions;
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) {
final var project = OrganizationsFunctions.getProject(GetProjectArgs.builder()
.build());
var topic = new Topic("topic", TopicArgs.builder()
.name("tf-topic")
.build());
var secretsManagerAccess = new TopicIAMMember("secretsManagerAccess", TopicIAMMemberArgs.builder()
.topic(topic.name())
.role("roles/pubsub.publisher")
.member(String.format("serviceAccount:service-%s@gcp-sa-secretmanager.iam.gserviceaccount.com", project.number()))
.build());
var regional_secret_with_rotation = new RegionalSecret("regional-secret-with-rotation", RegionalSecretArgs.builder()
.secretId("tf-reg-secret")
.location("us-central1")
.topics(RegionalSecretTopicArgs.builder()
.name(topic.id())
.build())
.rotation(RegionalSecretRotationArgs.builder()
.rotationPeriod("3600s")
.nextRotationTime("2045-11-30T00:00:00Z")
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(secretsManagerAccess)
.build());
}
}
resources:
topic:
type: gcp:pubsub:Topic
properties:
name: tf-topic
secretsManagerAccess:
type: gcp:pubsub:TopicIAMMember
name: secrets_manager_access
properties:
topic: ${topic.name}
role: roles/pubsub.publisher
member: serviceAccount:service-${project.number}@gcp-sa-secretmanager.iam.gserviceaccount.com
regional-secret-with-rotation:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: tf-reg-secret
location: us-central1
topics:
- name: ${topic.id}
rotation:
rotationPeriod: 3600s
nextRotationTime: 2045-11-30T00:00:00Z
options:
dependsOn:
- ${secretsManagerAccess}
variables:
project:
fn::invoke:
function: gcp:organizations:getProject
arguments: {}
The rotation block defines when Secret Manager sends Pub/Sub notifications: rotationPeriod sets the interval (e.g., every hour), nextRotationTime sets the first notification. The topics array lists Pub/Sub topics that receive these notifications. Your application subscribes to these topics and generates new secret versions in response.
Set automatic expiration with TTL
Temporary credentials benefit from automatic cleanup after a fixed duration.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const regional_secret_with_ttl = new gcp.secretmanager.RegionalSecret("regional-secret-with-ttl", {
secretId: "tf-reg-secret",
location: "us-central1",
labels: {
label: "my-label",
},
annotations: {
key1: "value1",
key2: "value2",
key3: "value3",
},
ttl: "36000s",
});
import pulumi
import pulumi_gcp as gcp
regional_secret_with_ttl = gcp.secretmanager.RegionalSecret("regional-secret-with-ttl",
secret_id="tf-reg-secret",
location="us-central1",
labels={
"label": "my-label",
},
annotations={
"key1": "value1",
"key2": "value2",
"key3": "value3",
},
ttl="36000s")
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 {
_, err := secretmanager.NewRegionalSecret(ctx, "regional-secret-with-ttl", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("tf-reg-secret"),
Location: pulumi.String("us-central1"),
Labels: pulumi.StringMap{
"label": pulumi.String("my-label"),
},
Annotations: pulumi.StringMap{
"key1": pulumi.String("value1"),
"key2": pulumi.String("value2"),
"key3": pulumi.String("value3"),
},
Ttl: pulumi.String("36000s"),
})
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 regional_secret_with_ttl = new Gcp.SecretManager.RegionalSecret("regional-secret-with-ttl", new()
{
SecretId = "tf-reg-secret",
Location = "us-central1",
Labels =
{
{ "label", "my-label" },
},
Annotations =
{
{ "key1", "value1" },
{ "key2", "value2" },
{ "key3", "value3" },
},
Ttl = "36000s",
});
});
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 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 regional_secret_with_ttl = new RegionalSecret("regional-secret-with-ttl", RegionalSecretArgs.builder()
.secretId("tf-reg-secret")
.location("us-central1")
.labels(Map.of("label", "my-label"))
.annotations(Map.ofEntries(
Map.entry("key1", "value1"),
Map.entry("key2", "value2"),
Map.entry("key3", "value3")
))
.ttl("36000s")
.build());
}
}
resources:
regional-secret-with-ttl:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: tf-reg-secret
location: us-central1
labels:
label: my-label
annotations:
key1: value1
key2: value2
key3: value3
ttl: 36000s
The ttl property sets a duration after which the secret expires and becomes inaccessible. Use this for short-lived credentials where you know the lifetime but not the exact end date. Only one of ttl or expireTime can be set.
Schedule expiration at a specific timestamp
Some secrets need to expire at a known future date.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const regional_secret_with_expire_time = new gcp.secretmanager.RegionalSecret("regional-secret-with-expire-time", {
secretId: "tf-reg-secret",
location: "us-central1",
labels: {
label: "my-label",
},
annotations: {
key1: "value1",
key2: "value2",
key3: "value3",
},
expireTime: "2055-11-30T00:00:00Z",
});
import pulumi
import pulumi_gcp as gcp
regional_secret_with_expire_time = gcp.secretmanager.RegionalSecret("regional-secret-with-expire-time",
secret_id="tf-reg-secret",
location="us-central1",
labels={
"label": "my-label",
},
annotations={
"key1": "value1",
"key2": "value2",
"key3": "value3",
},
expire_time="2055-11-30T00:00:00Z")
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 {
_, err := secretmanager.NewRegionalSecret(ctx, "regional-secret-with-expire-time", &secretmanager.RegionalSecretArgs{
SecretId: pulumi.String("tf-reg-secret"),
Location: pulumi.String("us-central1"),
Labels: pulumi.StringMap{
"label": pulumi.String("my-label"),
},
Annotations: pulumi.StringMap{
"key1": pulumi.String("value1"),
"key2": pulumi.String("value2"),
"key3": pulumi.String("value3"),
},
ExpireTime: pulumi.String("2055-11-30T00:00:00Z"),
})
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 regional_secret_with_expire_time = new Gcp.SecretManager.RegionalSecret("regional-secret-with-expire-time", new()
{
SecretId = "tf-reg-secret",
Location = "us-central1",
Labels =
{
{ "label", "my-label" },
},
Annotations =
{
{ "key1", "value1" },
{ "key2", "value2" },
{ "key3", "value3" },
},
ExpireTime = "2055-11-30T00:00:00Z",
});
});
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 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 regional_secret_with_expire_time = new RegionalSecret("regional-secret-with-expire-time", RegionalSecretArgs.builder()
.secretId("tf-reg-secret")
.location("us-central1")
.labels(Map.of("label", "my-label"))
.annotations(Map.ofEntries(
Map.entry("key1", "value1"),
Map.entry("key2", "value2"),
Map.entry("key3", "value3")
))
.expireTime("2055-11-30T00:00:00Z")
.build());
}
}
resources:
regional-secret-with-expire-time:
type: gcp:secretmanager:RegionalSecret
properties:
secretId: tf-reg-secret
location: us-central1
labels:
label: my-label
annotations:
key1: value1
key2: value2
key3: value3
expireTime: 2055-11-30T00:00:00Z
The expireTime property sets an absolute timestamp in RFC3339 format. Use this when you know the exact expiration date, such as for certificates or time-bound access tokens. Only one of expireTime or ttl can be set.
Beyond these examples
These snippets focus on specific regional secret features: regional secret creation with metadata, customer-managed encryption, and rotation scheduling and lifecycle management. They’re intentionally minimal rather than full secrets management solutions.
The examples may reference pre-existing infrastructure such as KMS keys for customer-managed encryption, Pub/Sub topics for rotation notifications, and IAM bindings for the Secret Manager service account. They focus on configuring the secret container rather than provisioning the surrounding infrastructure.
To keep things focused, common secret patterns are omitted, including:
- Secret version creation and data storage (requires RegionalSecretVersion resource)
- Version aliases for stable references (versionAliases)
- Version destruction delays (versionDestroyTtl)
- IAM policies for secret access control
These omissions are intentional: the goal is to illustrate how each regional secret feature is wired, not provide drop-in secrets management modules. See the Regional Secret resource reference for all available configuration options.
Let's create GCP Regional Secrets
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Lifecycle
ttl sets a duration from creation (e.g., “3600s”), while expireTime sets a specific timestamp (e.g., “2055-11-30T00:00:00Z”). You can only use one, not both.location, secretId, project, and tags properties are immutable. Changing them requires replacing the resource.deletionProtection to true. This prevents Pulumi from destroying the secret during updates or destroy operations.Encryption & Security
customerManagedEncryption.kmsKeyName with your KMS key. First, create a gcp.kms.CryptoKeyIAMMember granting roles/cloudkms.cryptoKeyEncrypterDecrypter to the Secret Manager service account (service-PROJECT_NUMBER@gcp-sa-secretmanager.iam.gserviceaccount.com), then use dependsOn to ensure the IAM binding is created before the secret.Rotation & Notifications
rotation with rotationPeriod and nextRotationTime, and add at least one Pub/Sub topic to topics. The Secret Manager service account needs roles/pubsub.publisher on the topic. Use dependsOn to ensure IAM permissions are set before creating the secret.topics array.Labels & Metadata
annotations and labels fields are non-authoritative, meaning they only manage values you explicitly set in your configuration. To see all annotations and labels (including those set by other clients or services), use effectiveAnnotations and effectiveLabels.[\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62} (1-63 chars, start with lowercase letter). Label values must match [\p{Ll}\p{Lo}\p{N}_-]{0,63} (0-63 chars). Maximum 64 labels per secret.Version Management
pulumi import with one of these formats: projects/PROJECT/locations/LOCATION/secrets/SECRET_ID, PROJECT/LOCATION/SECRET_ID, or LOCATION/SECRET_ID.