The gcp:logging/projectBucketConfig:ProjectBucketConfig resource, part of the Pulumi GCP provider, configures project-level logging buckets: their retention policies, encryption settings, analytics capabilities, and field indexing. This guide focuses on four capabilities: retention policy configuration, Log Analytics enablement, customer-managed encryption, and field indexing.
GCP automatically creates _Default and _Required buckets for each project; these cannot be deleted. This resource acquires and configures existing buckets or creates custom ones. CMEK configurations require KMS keys and IAM bindings. The examples are intentionally small. Combine them with your own log sinks, monitoring, and compliance policies.
Configure retention for the default bucket
GCP automatically creates _Default and _Required buckets for each project. Teams adjust retention periods on these buckets to meet compliance requirements or control storage costs.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.organizations.Project("default", {
projectId: "your-project-id",
name: "your-project-id",
orgId: "123456789",
});
const basic = new gcp.logging.ProjectBucketConfig("basic", {
project: _default.projectId,
location: "global",
retentionDays: 30,
bucketId: "_Default",
});
import pulumi
import pulumi_gcp as gcp
default = gcp.organizations.Project("default",
project_id="your-project-id",
name="your-project-id",
org_id="123456789")
basic = gcp.logging.ProjectBucketConfig("basic",
project=default.project_id,
location="global",
retention_days=30,
bucket_id="_Default")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/logging"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_default, err := organizations.NewProject(ctx, "default", &organizations.ProjectArgs{
ProjectId: pulumi.String("your-project-id"),
Name: pulumi.String("your-project-id"),
OrgId: pulumi.String("123456789"),
})
if err != nil {
return err
}
_, err = logging.NewProjectBucketConfig(ctx, "basic", &logging.ProjectBucketConfigArgs{
Project: _default.ProjectId,
Location: pulumi.String("global"),
RetentionDays: pulumi.Int(30),
BucketId: pulumi.String("_Default"),
})
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 @default = new Gcp.Organizations.Project("default", new()
{
ProjectId = "your-project-id",
Name = "your-project-id",
OrgId = "123456789",
});
var basic = new Gcp.Logging.ProjectBucketConfig("basic", new()
{
Project = @default.ProjectId,
Location = "global",
RetentionDays = 30,
BucketId = "_Default",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.organizations.Project;
import com.pulumi.gcp.organizations.ProjectArgs;
import com.pulumi.gcp.logging.ProjectBucketConfig;
import com.pulumi.gcp.logging.ProjectBucketConfigArgs;
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 default_ = new Project("default", ProjectArgs.builder()
.projectId("your-project-id")
.name("your-project-id")
.orgId("123456789")
.build());
var basic = new ProjectBucketConfig("basic", ProjectBucketConfigArgs.builder()
.project(default_.projectId())
.location("global")
.retentionDays(30)
.bucketId("_Default")
.build());
}
}
resources:
default:
type: gcp:organizations:Project
properties:
projectId: your-project-id
name: your-project-id
orgId: '123456789'
basic:
type: gcp:logging:ProjectBucketConfig
properties:
project: ${default.projectId}
location: global
retentionDays: 30
bucketId: _Default
The bucketId “_Default” references the automatically-created bucket. The retentionDays property sets how long logs persist before automatic deletion; the minimum is 1 day. Setting location to “global” stores logs across regions.
Create a custom bucket with retention policy
Beyond automatic buckets, teams create custom buckets to organize logs by application, environment, or compliance tier.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const basic = new gcp.logging.ProjectBucketConfig("basic", {
project: "project_id",
location: "global",
retentionDays: 30,
bucketId: "custom-bucket",
});
import pulumi
import pulumi_gcp as gcp
basic = gcp.logging.ProjectBucketConfig("basic",
project="project_id",
location="global",
retention_days=30,
bucket_id="custom-bucket")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/logging"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := logging.NewProjectBucketConfig(ctx, "basic", &logging.ProjectBucketConfigArgs{
Project: pulumi.String("project_id"),
Location: pulumi.String("global"),
RetentionDays: pulumi.Int(30),
BucketId: pulumi.String("custom-bucket"),
})
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 basic = new Gcp.Logging.ProjectBucketConfig("basic", new()
{
Project = "project_id",
Location = "global",
RetentionDays = 30,
BucketId = "custom-bucket",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.logging.ProjectBucketConfig;
import com.pulumi.gcp.logging.ProjectBucketConfigArgs;
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 basic = new ProjectBucketConfig("basic", ProjectBucketConfigArgs.builder()
.project("project_id")
.location("global")
.retentionDays(30)
.bucketId("custom-bucket")
.build());
}
}
resources:
basic:
type: gcp:logging:ProjectBucketConfig
properties:
project: project_id
location: global
retentionDays: 30
bucketId: custom-bucket
Custom buckets use any bucketId except “_Default” or “_Required”. Each bucket can have its own retention policy, allowing you to keep audit logs longer than application logs.
Enable Log Analytics for SQL queries
Log Analytics allows teams to query logs using SQL in the GCP console, enabling complex analysis without exporting to BigQuery.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const analytics_enabled_bucket = new gcp.logging.ProjectBucketConfig("analytics-enabled-bucket", {
project: "project_id",
location: "global",
retentionDays: 30,
enableAnalytics: true,
bucketId: "custom-bucket",
});
import pulumi
import pulumi_gcp as gcp
analytics_enabled_bucket = gcp.logging.ProjectBucketConfig("analytics-enabled-bucket",
project="project_id",
location="global",
retention_days=30,
enable_analytics=True,
bucket_id="custom-bucket")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/logging"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := logging.NewProjectBucketConfig(ctx, "analytics-enabled-bucket", &logging.ProjectBucketConfigArgs{
Project: pulumi.String("project_id"),
Location: pulumi.String("global"),
RetentionDays: pulumi.Int(30),
EnableAnalytics: pulumi.Bool(true),
BucketId: pulumi.String("custom-bucket"),
})
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 analytics_enabled_bucket = new Gcp.Logging.ProjectBucketConfig("analytics-enabled-bucket", new()
{
Project = "project_id",
Location = "global",
RetentionDays = 30,
EnableAnalytics = true,
BucketId = "custom-bucket",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.logging.ProjectBucketConfig;
import com.pulumi.gcp.logging.ProjectBucketConfigArgs;
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 analytics_enabled_bucket = new ProjectBucketConfig("analytics-enabled-bucket", ProjectBucketConfigArgs.builder()
.project("project_id")
.location("global")
.retentionDays(30)
.enableAnalytics(true)
.bucketId("custom-bucket")
.build());
}
}
resources:
analytics-enabled-bucket:
type: gcp:logging:ProjectBucketConfig
properties:
project: project_id
location: global
retentionDays: 30
enableAnalytics: true
bucketId: custom-bucket
Setting enableAnalytics to true activates SQL-based querying in the Log Analytics page. This cannot be disabled once enabled. Logs in analytics-enabled buckets support filtering, aggregation, and joins using standard SQL syntax.
Encrypt logs with customer-managed keys
Organizations with strict data sovereignty requirements encrypt logs using their own KMS keys rather than Google-managed encryption.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const cmekSettings = gcp.logging.getProjectCmekSettings({
project: "project_id",
});
const keyring = new gcp.kms.KeyRing("keyring", {
name: "keyring-example",
location: "us-central1",
});
const key = new gcp.kms.CryptoKey("key", {
name: "crypto-key-example",
keyRing: keyring.id,
rotationPeriod: "7776000s",
});
const cryptoKeyBinding = new gcp.kms.CryptoKeyIAMBinding("crypto_key_binding", {
cryptoKeyId: key.id,
role: "roles/cloudkms.cryptoKeyEncrypterDecrypter",
members: [cmekSettings.then(cmekSettings => `serviceAccount:${cmekSettings.serviceAccountId}`)],
});
const example_project_bucket_cmek_settings = new gcp.logging.ProjectBucketConfig("example-project-bucket-cmek-settings", {
project: "project_id",
location: "us-central1",
retentionDays: 30,
bucketId: "custom-bucket",
cmekSettings: {
kmsKeyName: key.id,
},
}, {
dependsOn: [cryptoKeyBinding],
});
import pulumi
import pulumi_gcp as gcp
cmek_settings = gcp.logging.get_project_cmek_settings(project="project_id")
keyring = gcp.kms.KeyRing("keyring",
name="keyring-example",
location="us-central1")
key = gcp.kms.CryptoKey("key",
name="crypto-key-example",
key_ring=keyring.id,
rotation_period="7776000s")
crypto_key_binding = gcp.kms.CryptoKeyIAMBinding("crypto_key_binding",
crypto_key_id=key.id,
role="roles/cloudkms.cryptoKeyEncrypterDecrypter",
members=[f"serviceAccount:{cmek_settings.service_account_id}"])
example_project_bucket_cmek_settings = gcp.logging.ProjectBucketConfig("example-project-bucket-cmek-settings",
project="project_id",
location="us-central1",
retention_days=30,
bucket_id="custom-bucket",
cmek_settings={
"kms_key_name": key.id,
},
opts = pulumi.ResourceOptions(depends_on=[crypto_key_binding]))
package main
import (
"fmt"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/kms"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/logging"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
cmekSettings, err := logging.GetProjectCmekSettings(ctx, &logging.GetProjectCmekSettingsArgs{
Project: "project_id",
}, nil)
if err != nil {
return err
}
keyring, err := kms.NewKeyRing(ctx, "keyring", &kms.KeyRingArgs{
Name: pulumi.String("keyring-example"),
Location: pulumi.String("us-central1"),
})
if err != nil {
return err
}
key, err := kms.NewCryptoKey(ctx, "key", &kms.CryptoKeyArgs{
Name: pulumi.String("crypto-key-example"),
KeyRing: keyring.ID(),
RotationPeriod: pulumi.String("7776000s"),
})
if err != nil {
return err
}
cryptoKeyBinding, err := kms.NewCryptoKeyIAMBinding(ctx, "crypto_key_binding", &kms.CryptoKeyIAMBindingArgs{
CryptoKeyId: key.ID(),
Role: pulumi.String("roles/cloudkms.cryptoKeyEncrypterDecrypter"),
Members: pulumi.StringArray{
pulumi.Sprintf("serviceAccount:%v", cmekSettings.ServiceAccountId),
},
})
if err != nil {
return err
}
_, err = logging.NewProjectBucketConfig(ctx, "example-project-bucket-cmek-settings", &logging.ProjectBucketConfigArgs{
Project: pulumi.String("project_id"),
Location: pulumi.String("us-central1"),
RetentionDays: pulumi.Int(30),
BucketId: pulumi.String("custom-bucket"),
CmekSettings: &logging.ProjectBucketConfigCmekSettingsArgs{
KmsKeyName: key.ID(),
},
}, pulumi.DependsOn([]pulumi.Resource{
cryptoKeyBinding,
}))
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 cmekSettings = Gcp.Logging.GetProjectCmekSettings.Invoke(new()
{
Project = "project_id",
});
var keyring = new Gcp.Kms.KeyRing("keyring", new()
{
Name = "keyring-example",
Location = "us-central1",
});
var key = new Gcp.Kms.CryptoKey("key", new()
{
Name = "crypto-key-example",
KeyRing = keyring.Id,
RotationPeriod = "7776000s",
});
var cryptoKeyBinding = new Gcp.Kms.CryptoKeyIAMBinding("crypto_key_binding", new()
{
CryptoKeyId = key.Id,
Role = "roles/cloudkms.cryptoKeyEncrypterDecrypter",
Members = new[]
{
$"serviceAccount:{cmekSettings.Apply(getProjectCmekSettingsResult => getProjectCmekSettingsResult.ServiceAccountId)}",
},
});
var example_project_bucket_cmek_settings = new Gcp.Logging.ProjectBucketConfig("example-project-bucket-cmek-settings", new()
{
Project = "project_id",
Location = "us-central1",
RetentionDays = 30,
BucketId = "custom-bucket",
CmekSettings = new Gcp.Logging.Inputs.ProjectBucketConfigCmekSettingsArgs
{
KmsKeyName = key.Id,
},
}, new CustomResourceOptions
{
DependsOn =
{
cryptoKeyBinding,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.logging.LoggingFunctions;
import com.pulumi.gcp.logging.inputs.GetProjectCmekSettingsArgs;
import com.pulumi.gcp.kms.KeyRing;
import com.pulumi.gcp.kms.KeyRingArgs;
import com.pulumi.gcp.kms.CryptoKey;
import com.pulumi.gcp.kms.CryptoKeyArgs;
import com.pulumi.gcp.kms.CryptoKeyIAMBinding;
import com.pulumi.gcp.kms.CryptoKeyIAMBindingArgs;
import com.pulumi.gcp.logging.ProjectBucketConfig;
import com.pulumi.gcp.logging.ProjectBucketConfigArgs;
import com.pulumi.gcp.logging.inputs.ProjectBucketConfigCmekSettingsArgs;
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 cmekSettings = LoggingFunctions.getProjectCmekSettings(GetProjectCmekSettingsArgs.builder()
.project("project_id")
.build());
var keyring = new KeyRing("keyring", KeyRingArgs.builder()
.name("keyring-example")
.location("us-central1")
.build());
var key = new CryptoKey("key", CryptoKeyArgs.builder()
.name("crypto-key-example")
.keyRing(keyring.id())
.rotationPeriod("7776000s")
.build());
var cryptoKeyBinding = new CryptoKeyIAMBinding("cryptoKeyBinding", CryptoKeyIAMBindingArgs.builder()
.cryptoKeyId(key.id())
.role("roles/cloudkms.cryptoKeyEncrypterDecrypter")
.members(String.format("serviceAccount:%s", cmekSettings.serviceAccountId()))
.build());
var example_project_bucket_cmek_settings = new ProjectBucketConfig("example-project-bucket-cmek-settings", ProjectBucketConfigArgs.builder()
.project("project_id")
.location("us-central1")
.retentionDays(30)
.bucketId("custom-bucket")
.cmekSettings(ProjectBucketConfigCmekSettingsArgs.builder()
.kmsKeyName(key.id())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(cryptoKeyBinding)
.build());
}
}
resources:
keyring:
type: gcp:kms:KeyRing
properties:
name: keyring-example
location: us-central1
key:
type: gcp:kms:CryptoKey
properties:
name: crypto-key-example
keyRing: ${keyring.id}
rotationPeriod: 7776000s
cryptoKeyBinding:
type: gcp:kms:CryptoKeyIAMBinding
name: crypto_key_binding
properties:
cryptoKeyId: ${key.id}
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
members:
- serviceAccount:${cmekSettings.serviceAccountId}
example-project-bucket-cmek-settings:
type: gcp:logging:ProjectBucketConfig
properties:
project: project_id
location: us-central1
retentionDays: 30
bucketId: custom-bucket
cmekSettings:
kmsKeyName: ${key.id}
options:
dependsOn:
- ${cryptoKeyBinding}
variables:
cmekSettings:
fn::invoke:
function: gcp:logging:getProjectCmekSettings
arguments:
project: project_id
The cmekSettings block specifies a KMS key for encrypting new log entries. The logging service account needs the cryptoKeyEncrypterDecrypter role on the key, granted via CryptoKeyIAMBinding. The dependsOn ensures IAM bindings exist before bucket creation. Once CMEK is enabled, it cannot be disabled, though you can change the key.
Index fields for faster query performance
When Log Analytics is enabled, indexing specific JSON fields accelerates queries that filter on those fields.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const example_project_bucket_index_configs = new gcp.logging.ProjectBucketConfig("example-project-bucket-index-configs", {
project: "project_id",
location: "global",
retentionDays: 30,
bucketId: "custom-bucket",
indexConfigs: [{
fieldPath: "jsonPayload.request.status",
type: "INDEX_TYPE_STRING",
}],
});
import pulumi
import pulumi_gcp as gcp
example_project_bucket_index_configs = gcp.logging.ProjectBucketConfig("example-project-bucket-index-configs",
project="project_id",
location="global",
retention_days=30,
bucket_id="custom-bucket",
index_configs=[{
"field_path": "jsonPayload.request.status",
"type": "INDEX_TYPE_STRING",
}])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/logging"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := logging.NewProjectBucketConfig(ctx, "example-project-bucket-index-configs", &logging.ProjectBucketConfigArgs{
Project: pulumi.String("project_id"),
Location: pulumi.String("global"),
RetentionDays: pulumi.Int(30),
BucketId: pulumi.String("custom-bucket"),
IndexConfigs: logging.ProjectBucketConfigIndexConfigArray{
&logging.ProjectBucketConfigIndexConfigArgs{
FieldPath: pulumi.String("jsonPayload.request.status"),
Type: pulumi.String("INDEX_TYPE_STRING"),
},
},
})
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 example_project_bucket_index_configs = new Gcp.Logging.ProjectBucketConfig("example-project-bucket-index-configs", new()
{
Project = "project_id",
Location = "global",
RetentionDays = 30,
BucketId = "custom-bucket",
IndexConfigs = new[]
{
new Gcp.Logging.Inputs.ProjectBucketConfigIndexConfigArgs
{
FieldPath = "jsonPayload.request.status",
Type = "INDEX_TYPE_STRING",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.logging.ProjectBucketConfig;
import com.pulumi.gcp.logging.ProjectBucketConfigArgs;
import com.pulumi.gcp.logging.inputs.ProjectBucketConfigIndexConfigArgs;
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 example_project_bucket_index_configs = new ProjectBucketConfig("example-project-bucket-index-configs", ProjectBucketConfigArgs.builder()
.project("project_id")
.location("global")
.retentionDays(30)
.bucketId("custom-bucket")
.indexConfigs(ProjectBucketConfigIndexConfigArgs.builder()
.fieldPath("jsonPayload.request.status")
.type("INDEX_TYPE_STRING")
.build())
.build());
}
}
resources:
example-project-bucket-index-configs:
type: gcp:logging:ProjectBucketConfig
properties:
project: project_id
location: global
retentionDays: 30
bucketId: custom-bucket
indexConfigs:
- fieldPath: jsonPayload.request.status
type: INDEX_TYPE_STRING
The indexConfigs array defines fields to index. Each entry specifies a fieldPath (dot-notation for nested JSON) and a type (INDEX_TYPE_STRING, INDEX_TYPE_INTEGER). Indexing speeds up WHERE clauses on high-cardinality fields like request status codes or user IDs.
Beyond these examples
These snippets focus on specific bucket-level features: retention policies and custom bucket creation, Log Analytics and SQL querying, and customer-managed encryption and field indexing. They’re intentionally minimal rather than full logging solutions.
The examples may reference pre-existing infrastructure such as GCP projects with logging enabled, and KMS keyrings and crypto keys for CMEK configurations. They focus on configuring the bucket rather than provisioning log sinks or monitoring.
To keep things focused, common bucket patterns are omitted, including:
- Bucket locking (locked property)
- Bucket descriptions (description property)
- Log sink routing to buckets
- Lifecycle state monitoring
These omissions are intentional: the goal is to illustrate how each bucket feature is wired, not provide drop-in logging modules. See the ProjectBucketConfig resource reference for all available configuration options.
Let's configure GCP Cloud Logging Buckets
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Lifecycle & Deletion
_Default and _Required buckets for each project. You can either configure these existing buckets by using their names as bucketId, or create new custom buckets with your own bucketId.Immutability & Configuration Limits
bucketId, location, and project properties are immutable after creation. You’ll need to create a new bucket if you need to change any of these values.enableAnalytics and cmekSettings are one-way configurations that cannot be disabled once enabled. However, you can change the KMS key used for CMEK encryption.Encryption & Security
cmekSettings with your KMS key ID. You must also grant the logging service account the roles/cloudkms.cryptoKeyEncrypterDecrypter role on your key. Use dependsOn to ensure the IAM binding is created before the bucket.Retention & Locking
retentionDays to zero at bucket creation, it defaults to 30 days. The minimum retention period is 1 day.locked to true makes the retention period immutable—it can’t be changed afterward. Locked buckets can only be deleted if they’re empty.Analytics & Performance
enableAnalytics to true. This allows you to query logs in the Log Analytics page using SQL. Note that this cannot be disabled once enabled.indexConfigs to specify field paths and index types. For example, you can index jsonPayload.request.status with type INDEX_TYPE_STRING to speed up queries on that field.Using a different cloud?
Explore monitoring guides for other cloud providers: