ProjectSink class
Manages a project-level logging sink. For more information see:
- API documentation
- How-to Guides
- Exporting Logs
> You can specify exclusions for log sinks created by terraform by using the exclusions field of gcp.logging.FolderSink
> Note: You must have granted the "Logs Configuration Writer" IAM role (roles/logging.configWriter) to the credentials used with this provider.
> Note You must enable the Cloud Resource Manager API
> Note: The _Default and _Required logging sinks are automatically created for a given project and cannot be deleted. Creating a resource of this type will acquire and update the resource that already exists at the desired location. These sinks cannot be removed so deleting this resource will remove the sink config from your terraform state but will leave the logging sink unchanged. The sinks that are currently automatically created are "_Default" and "_Required".
Example Usage
Basic Sink
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const my_sink = new gcp.logging.ProjectSink("my-sink", {
name: "my-pubsub-instance-sink",
destination: "pubsub.googleapis.com/projects/my-project/topics/instance-activity",
filter: "resource.type = gce_instance AND severity >= WARNING",
uniqueWriterIdentity: true,
});
import pulumi
import pulumi_gcp as gcp
my_sink = gcp.logging.ProjectSink("my-sink",
name="my-pubsub-instance-sink",
destination="pubsub.googleapis.com/projects/my-project/topics/instance-activity",
filter="resource.type = gce_instance AND severity >= WARNING",
unique_writer_identity=True)
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var my_sink = new Gcp.Logging.ProjectSink("my-sink", new()
{
Name = "my-pubsub-instance-sink",
Destination = "pubsub.googleapis.com/projects/my-project/topics/instance-activity",
Filter = "resource.type = gce_instance AND severity >= WARNING",
UniqueWriterIdentity = true,
});
});
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.NewProjectSink(ctx, "my-sink", &logging.ProjectSinkArgs{
Name: pulumi.String("my-pubsub-instance-sink"),
Destination: pulumi.String("pubsub.googleapis.com/projects/my-project/topics/instance-activity"),
Filter: pulumi.String("resource.type = gce_instance AND severity >= WARNING"),
UniqueWriterIdentity: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
pulumi {
required_providers {
gcp = {
source = "pulumi/gcp"
}
}
}
resource "gcp_logging_projectsink" "my-sink" {
name = "my-pubsub-instance-sink"
destination = "pubsub.googleapis.com/projects/my-project/topics/instance-activity"
filter = "resource.type = gce_instance AND severity >= WARNING"
unique_writer_identity = true
}
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.logging.ProjectSink;
import com.pulumi.gcp.logging.ProjectSinkArgs;
import java.util.ArrayList;
import java.util.Arrays;
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 my_sink = new ProjectSink("my-sink", ProjectSinkArgs.builder()
.name("my-pubsub-instance-sink")
.destination("pubsub.googleapis.com/projects/my-project/topics/instance-activity")
.filter("resource.type = gce_instance AND severity >= WARNING")
.uniqueWriterIdentity(true)
.build());
}
}
resources:
my-sink:
type: gcp:logging:ProjectSink
properties:
name: my-pubsub-instance-sink
destination: pubsub.googleapis.com/projects/my-project/topics/instance-activity
filter: resource.type = gce_instance AND severity >= WARNING
uniqueWriterIdentity: true
Cloud Storage Bucket Destination
A more complete example follows: this creates a compute instance, as well as a log sink that logs all activity to a
cloud storage bucket. Because we are using uniqueWriterIdentity, we must grant it access to the bucket.
Note that this grant requires the "Project IAM Admin" IAM role (roles/resourcemanager.projectIamAdmin) granted to the
credentials used with Terraform.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
// Our logged compute instance
const my_logged_instance = new gcp.compute.Instance("my-logged-instance", {
networkInterfaces: [{
accessConfigs: [{}],
network: "default",
}],
name: "my-instance",
machineType: "e2-medium",
zone: "us-central1-a",
bootDisk: {
initializeParams: {
image: "debian-cloud/debian-11",
},
},
});
// A gcs bucket to store logs in
const gcs_bucket = new gcp.storage.Bucket("gcs-bucket", {
name: "my-unique-logging-bucket",
location: "US",
});
// Our sink; this logs all activity related to our "my-logged-instance" instance
const instance_sink = new gcp.logging.ProjectSink("instance-sink", {
name: "my-instance-sink",
description: "some explanation on what this is",
destination: pulumi.interpolate`storage.googleapis.com/${gcs_bucket.name}`,
filter: pulumi.interpolate`resource.type = gce_instance AND resource.labels.instance_id = "${my_logged_instance.instanceId}"`,
uniqueWriterIdentity: true,
});
// Because our sink uses a unique_writer, we must grant that writer access to the bucket.
const gcs_bucket_writer = new gcp.projects.IAMBinding("gcs-bucket-writer", {
project: "your-project-id",
role: "roles/storage.objectCreator",
members: [instance_sink.writerIdentity],
});
import pulumi
import pulumi_gcp as gcp
# Our logged compute instance
my_logged_instance = gcp.compute.Instance("my-logged-instance",
network_interfaces=[{
"access_configs": [{}],
"network": "default",
}],
name="my-instance",
machine_type="e2-medium",
zone="us-central1-a",
boot_disk={
"initialize_params": {
"image": "debian-cloud/debian-11",
},
})
# A gcs bucket to store logs in
gcs_bucket = gcp.storage.Bucket("gcs-bucket",
name="my-unique-logging-bucket",
location="US")
# Our sink; this logs all activity related to our "my-logged-instance" instance
instance_sink = gcp.logging.ProjectSink("instance-sink",
name="my-instance-sink",
description="some explanation on what this is",
destination=gcs_bucket.name.apply(lambda name: f"storage.googleapis.com/{name}"),
filter=my_logged_instance.instance_id.apply(lambda instance_id: f"resource.type = gce_instance AND resource.labels.instance_id = \"{instance_id}\""),
unique_writer_identity=True)
# Because our sink uses a unique_writer, we must grant that writer access to the bucket.
gcs_bucket_writer = gcp.projects.IAMBinding("gcs-bucket-writer",
project="your-project-id",
role="roles/storage.objectCreator",
members=[instance_sink.writer_identity])
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
// Our logged compute instance
var my_logged_instance = new Gcp.Compute.Instance("my-logged-instance", new()
{
NetworkInterfaces = new[]
{
new Gcp.Compute.Inputs.InstanceNetworkInterfaceArgs
{
AccessConfigs = new[]
{
null,
},
Network = "default",
},
},
Name = "my-instance",
MachineType = "e2-medium",
Zone = "us-central1-a",
BootDisk = new Gcp.Compute.Inputs.InstanceBootDiskArgs
{
InitializeParams = new Gcp.Compute.Inputs.InstanceBootDiskInitializeParamsArgs
{
Image = "debian-cloud/debian-11",
},
},
});
// A gcs bucket to store logs in
var gcs_bucket = new Gcp.Storage.Bucket("gcs-bucket", new()
{
Name = "my-unique-logging-bucket",
Location = "US",
});
// Our sink; this logs all activity related to our "my-logged-instance" instance
var instance_sink = new Gcp.Logging.ProjectSink("instance-sink", new()
{
Name = "my-instance-sink",
Description = "some explanation on what this is",
Destination = gcs_bucket.Name.Apply(name => $"storage.googleapis.com/{name}"),
Filter = my_logged_instance.InstanceId.Apply(instanceId => $"resource.type = gce_instance AND resource.labels.instance_id = \"{instanceId}\""),
UniqueWriterIdentity = true,
});
// Because our sink uses a unique_writer, we must grant that writer access to the bucket.
var gcs_bucket_writer = new Gcp.Projects.IAMBinding("gcs-bucket-writer", new()
{
Project = "your-project-id",
Role = "roles/storage.objectCreator",
Members = new[]
{
instance_sink.WriterIdentity,
},
});
});
package main
import (
"fmt"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/logging"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/projects"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/storage"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// Our logged compute instance
my_logged_instance, err := compute.NewInstance(ctx, "my-logged-instance", &compute.InstanceArgs{
NetworkInterfaces: compute.InstanceNetworkInterfaceArray{
&compute.InstanceNetworkInterfaceArgs{
AccessConfigs: compute.InstanceNetworkInterfaceAccessConfigArray{
&compute.InstanceNetworkInterfaceAccessConfigArgs{},
},
Network: pulumi.String("default"),
},
},
Name: pulumi.String("my-instance"),
MachineType: pulumi.String("e2-medium"),
Zone: pulumi.String("us-central1-a"),
BootDisk: &compute.InstanceBootDiskArgs{
InitializeParams: &compute.InstanceBootDiskInitializeParamsArgs{
Image: pulumi.String("debian-cloud/debian-11"),
},
},
})
if err != nil {
return err
}
// A gcs bucket to store logs in
gcs_bucket, err := storage.NewBucket(ctx, "gcs-bucket", &storage.BucketArgs{
Name: pulumi.String("my-unique-logging-bucket"),
Location: pulumi.String("US"),
})
if err != nil {
return err
}
// Our sink; this logs all activity related to our "my-logged-instance" instance
instance_sink, err := logging.NewProjectSink(ctx, "instance-sink", &logging.ProjectSinkArgs{
Name: pulumi.String("my-instance-sink"),
Description: pulumi.String("some explanation on what this is"),
Destination: gcs_bucket.Name.ApplyT(func(name string) (string, error) {
return fmt.Sprintf("storage.googleapis.com/%v", name), nil
}).(pulumi.StringOutput),
Filter: my_logged_instance.InstanceId.ApplyT(func(instanceId string) (string, error) {
return fmt.Sprintf("resource.type = gce_instance AND resource.labels.instance_id = \"%v\"", instanceId), nil
}).(pulumi.StringOutput),
UniqueWriterIdentity: pulumi.Bool(true),
})
if err != nil {
return err
}
// Because our sink uses a unique_writer, we must grant that writer access to the bucket.
_, err = projects.NewIAMBinding(ctx, "gcs-bucket-writer", &projects.IAMBindingArgs{
Project: pulumi.String("your-project-id"),
Role: pulumi.String("roles/storage.objectCreator"),
Members: pulumi.StringArray{
instance_sink.WriterIdentity,
},
})
if err != nil {
return err
}
return nil
})
}
pulumi {
required_providers {
gcp = {
source = "pulumi/gcp"
}
}
}
# Our logged compute instance
resource "gcp_compute_instance" "my-logged-instance" {
network_interfaces {
access_configs {
}
network = "default"
}
name = "my-instance"
machine_type = "e2-medium"
zone = "us-central1-a"
boot_disk = {
initialize_params = {
image = "debian-cloud/debian-11"
}
}
}
# A gcs bucket to store logs in
resource "gcp_storage_bucket" "gcs-bucket" {
name = "my-unique-logging-bucket"
location = "US"
}
# Our sink; this logs all activity related to our "my-logged-instance" instance
resource "gcp_logging_projectsink" "instance-sink" {
name = "my-instance-sink"
description = "some explanation on what this is"
destination ="storage.googleapis.com/${gcp_storage_bucket.gcs-bucket.name}"
filter ="resource.type = gce_instance AND resource.labels.instance_id = "${gcp_compute_instance.my-logged-instance.instance_id}""
unique_writer_identity = true
}
# Because our sink uses a unique_writer, we must grant that writer access to the bucket.
resource "gcp_projects_iambinding" "gcs-bucket-writer" {
project = "your-project-id"
role = "roles/storage.objectCreator"
members = [gcp_logging_projectsink.instance-sink.writer_identity]
}
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Instance;
import com.pulumi.gcp.compute.InstanceArgs;
import com.pulumi.gcp.compute.inputs.InstanceNetworkInterfaceArgs;
import com.pulumi.gcp.compute.inputs.InstanceNetworkInterfaceAccessConfigArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceBootDiskInitializeParamsArgs;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.logging.ProjectSink;
import com.pulumi.gcp.logging.ProjectSinkArgs;
import com.pulumi.gcp.projects.IAMBinding;
import com.pulumi.gcp.projects.IAMBindingArgs;
import java.util.ArrayList;
import java.util.Arrays;
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) {
// Our logged compute instance
var my_logged_instance = new Instance("my-logged-instance", InstanceArgs.builder()
.networkInterfaces(InstanceNetworkInterfaceArgs.builder()
.accessConfigs(InstanceNetworkInterfaceAccessConfigArgs.builder()
.build())
.network("default")
.build())
.name("my-instance")
.machineType("e2-medium")
.zone("us-central1-a")
.bootDisk(InstanceBootDiskArgs.builder()
.initializeParams(InstanceBootDiskInitializeParamsArgs.builder()
.image("debian-cloud/debian-11")
.build())
.build())
.build());
// A gcs bucket to store logs in
var gcs_bucket = new Bucket("gcs-bucket", BucketArgs.builder()
.name("my-unique-logging-bucket")
.location("US")
.build());
// Our sink; this logs all activity related to our "my-logged-instance" instance
var instance_sink = new ProjectSink("instance-sink", ProjectSinkArgs.builder()
.name("my-instance-sink")
.description("some explanation on what this is")
.destination(gcs_bucket.name().applyValue(_name -> String.format("storage.googleapis.com/%s", _name)))
.filter(my_logged_instance.instanceId().applyValue(_instanceId -> String.format("resource.type = gce_instance AND resource.labels.instance_id = \"%s\"", _instanceId)))
.uniqueWriterIdentity(true)
.build());
// Because our sink uses a unique_writer, we must grant that writer access to the bucket.
var gcs_bucket_writer = new IAMBinding("gcs-bucket-writer", IAMBindingArgs.builder()
.project("your-project-id")
.role("roles/storage.objectCreator")
.members(instance_sink.writerIdentity())
.build());
}
}
resources:
# Our logged compute instance
my-logged-instance:
type: gcp:compute:Instance
properties:
networkInterfaces:
- accessConfigs:
- {}
network: default
name: my-instance
machineType: e2-medium
zone: us-central1-a
bootDisk:
initializeParams:
image: debian-cloud/debian-11
# A gcs bucket to store logs in
gcs-bucket:
type: gcp:storage:Bucket
properties:
name: my-unique-logging-bucket
location: US
# Our sink; this logs all activity related to our "my-logged-instance" instance
instance-sink:
type: gcp:logging:ProjectSink
properties:
name: my-instance-sink
description: some explanation on what this is
destination: storage.googleapis.com/${["gcs-bucket"].name}
filter: resource.type = gce_instance AND resource.labels.instance_id = "${["my-logged-instance"].instanceId}"
uniqueWriterIdentity: true
# Because our sink uses a unique_writer, we must grant that writer access to the bucket.
gcs-bucket-writer:
type: gcp:projects:IAMBinding
properties:
project: your-project-id
role: roles/storage.objectCreator
members:
- ${["instance-sink"].writerIdentity}
User-Managed Service Account
The following example creates a sink that are configured with user-managed service accounts, by specifying
the customWriterIdentity field.
Note that you can only create a sink that uses a user-managed service account when the sink destination is a log bucket.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const custom_sa = new gcp.serviceaccount.Account("custom-sa", {
project: "other-project-id",
accountId: "gce-log-bucket-sink",
displayName: "gce-log-bucket-sink",
});
// Create a sink that uses user-managed service account
const my_sink = new gcp.logging.ProjectSink("my-sink", {
name: "other-project-log-bucket-sink",
destination: "logging.googleapis.com/projects/other-project-id/locations/global/buckets/gce-logs",
filter: "resource.type = gce_instance AND severity >= WARNING",
uniqueWriterIdentity: true,
customWriterIdentity: custom_sa.email,
});
// grant writer access to the user-managed service account
const custom_sa_logbucket_binding = new gcp.projects.IAMMember("custom-sa-logbucket-binding", {
project: "destination-project-id",
role: "roles/logging.bucketWriter",
member: pulumi.interpolate`serviceAccount:${custom_sa.email}`,
});
import pulumi
import pulumi_gcp as gcp
custom_sa = gcp.serviceaccount.Account("custom-sa",
project="other-project-id",
account_id="gce-log-bucket-sink",
display_name="gce-log-bucket-sink")
# Create a sink that uses user-managed service account
my_sink = gcp.logging.ProjectSink("my-sink",
name="other-project-log-bucket-sink",
destination="logging.googleapis.com/projects/other-project-id/locations/global/buckets/gce-logs",
filter="resource.type = gce_instance AND severity >= WARNING",
unique_writer_identity=True,
custom_writer_identity=custom_sa.email)
# grant writer access to the user-managed service account
custom_sa_logbucket_binding = gcp.projects.IAMMember("custom-sa-logbucket-binding",
project="destination-project-id",
role="roles/logging.bucketWriter",
member=custom_sa.email.apply(lambda email: f"serviceAccount:{email}"))
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var custom_sa = new Gcp.ServiceAccount.Account("custom-sa", new()
{
Project = "other-project-id",
AccountId = "gce-log-bucket-sink",
DisplayName = "gce-log-bucket-sink",
});
// Create a sink that uses user-managed service account
var my_sink = new Gcp.Logging.ProjectSink("my-sink", new()
{
Name = "other-project-log-bucket-sink",
Destination = "logging.googleapis.com/projects/other-project-id/locations/global/buckets/gce-logs",
Filter = "resource.type = gce_instance AND severity >= WARNING",
UniqueWriterIdentity = true,
CustomWriterIdentity = custom_sa.Email,
});
// grant writer access to the user-managed service account
var custom_sa_logbucket_binding = new Gcp.Projects.IAMMember("custom-sa-logbucket-binding", new()
{
Project = "destination-project-id",
Role = "roles/logging.bucketWriter",
Member = custom_sa.Email.Apply(email => $"serviceAccount:{email}"),
});
});
package main
import (
"fmt"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/logging"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/projects"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/serviceaccount"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
custom_sa, err := serviceaccount.NewAccount(ctx, "custom-sa", &serviceaccount.AccountArgs{
Project: pulumi.String("other-project-id"),
AccountId: pulumi.String("gce-log-bucket-sink"),
DisplayName: pulumi.String("gce-log-bucket-sink"),
})
if err != nil {
return err
}
// Create a sink that uses user-managed service account
_, err = logging.NewProjectSink(ctx, "my-sink", &logging.ProjectSinkArgs{
Name: pulumi.String("other-project-log-bucket-sink"),
Destination: pulumi.String("logging.googleapis.com/projects/other-project-id/locations/global/buckets/gce-logs"),
Filter: pulumi.String("resource.type = gce_instance AND severity >= WARNING"),
UniqueWriterIdentity: pulumi.Bool(true),
CustomWriterIdentity: custom_sa.Email,
})
if err != nil {
return err
}
// grant writer access to the user-managed service account
_, err = projects.NewIAMMember(ctx, "custom-sa-logbucket-binding", &projects.IAMMemberArgs{
Project: pulumi.String("destination-project-id"),
Role: pulumi.String("roles/logging.bucketWriter"),
Member: custom_sa.Email.ApplyT(func(email string) (string, error) {
return fmt.Sprintf("serviceAccount:%v", email), nil
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
return nil
})
}
pulumi {
required_providers {
gcp = {
source = "pulumi/gcp"
}
}
}
resource "gcp_serviceaccount_account" "custom-sa" {
project = "other-project-id"
account_id = "gce-log-bucket-sink"
display_name = "gce-log-bucket-sink"
}
# Create a sink that uses user-managed service account
resource "gcp_logging_projectsink" "my-sink" {
name = "other-project-log-bucket-sink"
destination = "logging.googleapis.com/projects/other-project-id/locations/global/buckets/gce-logs"
filter = "resource.type = gce_instance AND severity >= WARNING"
unique_writer_identity = true
# Use a user-managed service account
custom_writer_identity = gcp_serviceaccount_account.custom-sa.email
}
# grant writer access to the user-managed service account
resource "gcp_projects_iammember" "custom-sa-logbucket-binding" {
project = "destination-project-id"
role = "roles/logging.bucketWriter"
member ="serviceAccount:${gcp_serviceaccount_account.custom-sa.email}"
}
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.serviceaccount.Account;
import com.pulumi.gcp.serviceaccount.AccountArgs;
import com.pulumi.gcp.logging.ProjectSink;
import com.pulumi.gcp.logging.ProjectSinkArgs;
import com.pulumi.gcp.projects.IAMMember;
import com.pulumi.gcp.projects.IAMMemberArgs;
import java.util.ArrayList;
import java.util.Arrays;
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 custom_sa = new Account("custom-sa", AccountArgs.builder()
.project("other-project-id")
.accountId("gce-log-bucket-sink")
.displayName("gce-log-bucket-sink")
.build());
// Create a sink that uses user-managed service account
var my_sink = new ProjectSink("my-sink", ProjectSinkArgs.builder()
.name("other-project-log-bucket-sink")
.destination("logging.googleapis.com/projects/other-project-id/locations/global/buckets/gce-logs")
.filter("resource.type = gce_instance AND severity >= WARNING")
.uniqueWriterIdentity(true)
.customWriterIdentity(custom_sa.email())
.build());
// grant writer access to the user-managed service account
var custom_sa_logbucket_binding = new IAMMember("custom-sa-logbucket-binding", IAMMemberArgs.builder()
.project("destination-project-id")
.role("roles/logging.bucketWriter")
.member(custom_sa.email().applyValue(_email -> String.format("serviceAccount:%s", _email)))
.build());
}
}
resources:
custom-sa:
type: gcp:serviceaccount:Account
properties:
project: other-project-id
accountId: gce-log-bucket-sink
displayName: gce-log-bucket-sink
# Create a sink that uses user-managed service account
my-sink:
type: gcp:logging:ProjectSink
properties:
name: other-project-log-bucket-sink
destination: logging.googleapis.com/projects/other-project-id/locations/global/buckets/gce-logs
filter: resource.type = gce_instance AND severity >= WARNING
uniqueWriterIdentity: true # Use a user-managed service account
customWriterIdentity: ${["custom-sa"].email}
# grant writer access to the user-managed service account
custom-sa-logbucket-binding:
type: gcp:projects:IAMMember
properties:
project: destination-project-id
role: roles/logging.bucketWriter
member: serviceAccount:${["custom-sa"].email}
The above example will create a log sink that route logs to destination GCP project using an user-managed service account.
Sink Exclusions
The following example uses exclusions to filter logs that will not be exported. In this example logs are exported to a log bucket and there are 2 exclusions configured
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const log_bucket = new gcp.logging.ProjectSink("log-bucket", {
name: "my-logging-sink",
destination: "logging.googleapis.com/projects/my-project/locations/global/buckets/_Default",
exclusions: [
{
name: "nsexcllusion1",
description: "Exclude logs from namespace-1 in k8s",
filter: "resource.type = k8s_container resource.labels.namespace_name=\"namespace-1\" ",
},
{
name: "nsexcllusion2",
description: "Exclude logs from namespace-2 in k8s",
filter: "resource.type = k8s_container resource.labels.namespace_name=\"namespace-2\" ",
},
],
uniqueWriterIdentity: true,
});
import pulumi
import pulumi_gcp as gcp
log_bucket = gcp.logging.ProjectSink("log-bucket",
name="my-logging-sink",
destination="logging.googleapis.com/projects/my-project/locations/global/buckets/_Default",
exclusions=[
{
"name": "nsexcllusion1",
"description": "Exclude logs from namespace-1 in k8s",
"filter": "resource.type = k8s_container resource.labels.namespace_name=\"namespace-1\" ",
},
{
"name": "nsexcllusion2",
"description": "Exclude logs from namespace-2 in k8s",
"filter": "resource.type = k8s_container resource.labels.namespace_name=\"namespace-2\" ",
},
],
unique_writer_identity=True)
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var log_bucket = new Gcp.Logging.ProjectSink("log-bucket", new()
{
Name = "my-logging-sink",
Destination = "logging.googleapis.com/projects/my-project/locations/global/buckets/_Default",
Exclusions = new[]
{
new Gcp.Logging.Inputs.ProjectSinkExclusionArgs
{
Name = "nsexcllusion1",
Description = "Exclude logs from namespace-1 in k8s",
Filter = "resource.type = k8s_container resource.labels.namespace_name=\"namespace-1\" ",
},
new Gcp.Logging.Inputs.ProjectSinkExclusionArgs
{
Name = "nsexcllusion2",
Description = "Exclude logs from namespace-2 in k8s",
Filter = "resource.type = k8s_container resource.labels.namespace_name=\"namespace-2\" ",
},
},
UniqueWriterIdentity = true,
});
});
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.NewProjectSink(ctx, "log-bucket", &logging.ProjectSinkArgs{
Name: pulumi.String("my-logging-sink"),
Destination: pulumi.String("logging.googleapis.com/projects/my-project/locations/global/buckets/_Default"),
Exclusions: logging.ProjectSinkExclusionArray{
&logging.ProjectSinkExclusionArgs{
Name: pulumi.String("nsexcllusion1"),
Description: pulumi.String("Exclude logs from namespace-1 in k8s"),
Filter: pulumi.String("resource.type = k8s_container resource.labels.namespace_name=\"namespace-1\" "),
},
&logging.ProjectSinkExclusionArgs{
Name: pulumi.String("nsexcllusion2"),
Description: pulumi.String("Exclude logs from namespace-2 in k8s"),
Filter: pulumi.String("resource.type = k8s_container resource.labels.namespace_name=\"namespace-2\" "),
},
},
UniqueWriterIdentity: pulumi.Bool(true),
})
if err != nil {
return err
}
return nil
})
}
pulumi {
required_providers {
gcp = {
source = "pulumi/gcp"
}
}
}
resource "gcp_logging_projectsink" "log-bucket" {
name = "my-logging-sink"
destination = "logging.googleapis.com/projects/my-project/locations/global/buckets/_Default"
exclusions {
name = "nsexcllusion1"
description = "Exclude logs from namespace-1 in k8s"
filter = "resource.type = k8s_container resource.labels.namespace_name=\"namespace-1\" "
}
exclusions {
name = "nsexcllusion2"
description = "Exclude logs from namespace-2 in k8s"
filter = "resource.type = k8s_container resource.labels.namespace_name=\"namespace-2\" "
}
unique_writer_identity = true
}
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.logging.ProjectSink;
import com.pulumi.gcp.logging.ProjectSinkArgs;
import com.pulumi.gcp.logging.inputs.ProjectSinkExclusionArgs;
import java.util.ArrayList;
import java.util.Arrays;
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 log_bucket = new ProjectSink("log-bucket", ProjectSinkArgs.builder()
.name("my-logging-sink")
.destination("logging.googleapis.com/projects/my-project/locations/global/buckets/_Default")
.exclusions(
ProjectSinkExclusionArgs.builder()
.name("nsexcllusion1")
.description("Exclude logs from namespace-1 in k8s")
.filter("resource.type = k8s_container resource.labels.namespace_name=\"namespace-1\" ")
.build(),
ProjectSinkExclusionArgs.builder()
.name("nsexcllusion2")
.description("Exclude logs from namespace-2 in k8s")
.filter("resource.type = k8s_container resource.labels.namespace_name=\"namespace-2\" ")
.build())
.uniqueWriterIdentity(true)
.build());
}
}
resources:
log-bucket:
type: gcp:logging:ProjectSink
properties:
name: my-logging-sink
destination: logging.googleapis.com/projects/my-project/locations/global/buckets/_Default
exclusions:
- name: nsexcllusion1
description: Exclude logs from namespace-1 in k8s
filter: 'resource.type = k8s_container resource.labels.namespace_name="namespace-1" '
- name: nsexcllusion2
description: Exclude logs from namespace-2 in k8s
filter: 'resource.type = k8s_container resource.labels.namespace_name="namespace-2" '
uniqueWriterIdentity: true
Import
Project-level logging sinks can be imported using their URI, e.g.
projects/{{project_id}}/sinks/{{name}}
When using the pulumi import command, project-level logging sinks can be imported using one of the formats above. For example:
$ pulumi import gcp:logging/projectSink:ProjectSink default projects/{{project_id}}/sinks/{{name}}
Constructors
- ProjectSink(String name, {ProjectSinkArgs? args, CustomResourceOptions? options})
-
Creates a new ProjectSink.
nameThe Pulumi resource name.argsArguments used to configure this ProjectSink. The set of arguments for ProjectSink.optionsResource options controlling this resource's behavior. - ProjectSink.reference(String urn)
- Creates a typed reference to an existing ProjectSink resource.
Properties
-
bigqueryOptions
↔ Output<
ProjectSinkBigqueryOptions> -
Options that affect sinks exporting data to BigQuery. Structure documented below.
latefinal
-
childResources
→ Set<
Resource> -
finalinherited
-
completionSources
↔ Map<
String, IOutputCompletionSource> -
latefinalinherited
-
customWriterIdentity
↔ Output<
String?> -
A user managed service account that will be used to write
the log entries. The format must be
serviceAccount:some@email. This field can only be specified if you are routing logs to a destination outside this sink's project. If not specified, a Logging service account will automatically be generated.latefinal -
deletionPolicy
↔ Output<
String> -
Whether Terraform will be prevented from destroying the resource. Defaults to "DELETE".
When a 'terraform destroy' or 'pulumi up' would delete the resource,
the command will fail if this field is set to "PREVENT" in Terraform state.
When set to "ABANDON", the command will remove the resource from Terraform
management without updating or deleting the resource in the API.
When set to "DELETE", deleting the resource is allowed.
latefinal
-
description
↔ Output<
String?> -
A description of this sink. The maximum length of the description is 8000 characters.
latefinal
-
destination
↔ Output<
String> -
The destination of the sink (or, in other words, where logs are written to). Can be a Cloud Storage bucket, a PubSub topic, a BigQuery dataset, a Cloud Logging bucket, or a Google Cloud project. Examples:
latefinal
-
disabled
↔ Output<
bool?> -
If set to True, then this sink is disabled and it does not export any log entries.
latefinal
-
exclusions
↔ Output<
List< ProjectSinkExclusion> ?> -
Log entries that match any of the exclusion filters will not be exported. If a log entry is matched by both
filterand one ofexclusions.filter, it will not be exported. Can be repeated multiple times for multiple exclusions. Structure is documented below.latefinal -
filter
↔ Output<
String?> -
The filter to apply when exporting logs. Only log entries that match the filter are exported.
See Advanced Log Filters for information on how to
write a filter.
latefinal
- hashCode → int
-
The hash code for this object.
no setterinherited
-
id
↔ Output<
String> -
getter/setter pairinherited
- isCustom → bool
-
Returns whether this resource is provider-managed.
no setterinherited
- isProtected → bool
-
Returns whether this resource is protected from deletion.
no setterinherited
- isRemote → bool
-
Whether this resource is registered as remote.
no setterinherited
- isResourceReference → bool
-
Whether this instance represents a resource value returned over RPC.
finalinherited
-
name
↔ Output<
String> -
The name of the logging sink. Logging automatically creates two sinks:
_Requiredand_Default.latefinal -
project
↔ Output<
String> -
The ID of the project to create the sink in. If omitted, the project associated with the provider is
used.
latefinal
-
resourceTransforms
→ List<
ResourceTransform> -
Inherited/explicit async transforms.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
transformations
→ List<
ResourceTransformation> -
Inherited/explicit legacy transformations.
no setterinherited
-
uniqueWriterIdentity
↔ Output<
bool?> -
Whether to use a service agent as the
writerIdentityfor this sink. Iffalse,writerIdentityisserviceAccount:cloud-logs@system.gserviceaccount.comand the sink's destination must be in the same project as the sink. Iftrue(the default),writerIdentityis a service agent shared by sinks with the same parent. You must setuniqueWriterIdentitytotrueto publish logs across projects or usebigqueryOptions. See theprojects.sinks.createAPI documentation for more information.latefinal -
urn
↔ Output<
String> -
latefinalinherited
-
writerIdentity
↔ Output<
String> -
The identity associated with this sink. This identity must be granted write access to the
configured
destination.latefinal
Methods
-
failId(
Object error) → void -
Completes this resource ID with an error when registration fails.
inherited
-
failOutputs(
Object error) → void -
Completes all output properties with
error.inherited -
failUrn(
Object error) → void -
Completes this resource URN with an error when registration fails.
inherited
-
getProvider(
String moduleMember) → ProviderResource? -
Returns provider for
moduleMember's package, if configured.inherited -
getResourceName(
) → String -
Returns this resource's logical name.
inherited
-
getResourceType(
) → String -
Returns this resource's Pulumi type token.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
registerOutput<
T> (String propertyName, {Object? decoder(Object?)?, bool isSecret = false}) → Output< T> -
Registers a dynamic output property for this resource.
inherited
-
resolveId(
String? value, {required bool isKnown}) → void -
Resolves the provider-assigned ID for this resource.
inherited
-
resolveOutputs(
Struct outputs) → void -
Resolves all output properties from a monitor response payload.
inherited
-
resolveUrn(
String value) → void -
Resolves this resource's URN once assigned by the engine.
inherited
-
serializeProperties(
Map< String, dynamic> properties) → Future<Struct> -
Serializes resource properties for RPC transmission.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Methods
-
get(
String name, Input< String> id, {ProjectSinkState? state, CustomResourceOptions? options}) → ProjectSink -
Gets an existing ProjectSink resource's state with the given
nameandid.