The aws:s3/bucketMetric:BucketMetric resource, part of the Pulumi AWS provider, configures CloudWatch metrics collection for S3 buckets, enabling monitoring of request rates, data transfer, and errors. This guide focuses on three capabilities: bucket-wide metrics collection, prefix and tag-based filtering, and Access Point integration.
Metric configurations reference existing S3 buckets and optionally filter by Access Points or object tags. The examples are intentionally small. Combine them with your own CloudWatch dashboards and alarms.
Track metrics for an entire bucket
CloudWatch metrics help teams monitor request rates, data transfer, and error counts. The simplest configuration tracks all objects without filtering.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {bucket: "example"});
const example_entire_bucket = new aws.s3.BucketMetric("example-entire-bucket", {
bucket: example.id,
name: "EntireBucket",
});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example", bucket="example")
example_entire_bucket = aws.s3.BucketMetric("example-entire-bucket",
bucket=example.id,
name="EntireBucket")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := s3.NewBucket(ctx, "example", &s3.BucketArgs{
Bucket: pulumi.String("example"),
})
if err != nil {
return err
}
_, err = s3.NewBucketMetric(ctx, "example-entire-bucket", &s3.BucketMetricArgs{
Bucket: example.ID(),
Name: pulumi.String("EntireBucket"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.S3.Bucket("example", new()
{
BucketName = "example",
});
var example_entire_bucket = new Aws.S3.BucketMetric("example-entire-bucket", new()
{
Bucket = example.Id,
Name = "EntireBucket",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
import com.pulumi.aws.s3.BucketMetric;
import com.pulumi.aws.s3.BucketMetricArgs;
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 = new Bucket("example", BucketArgs.builder()
.bucket("example")
.build());
var example_entire_bucket = new BucketMetric("example-entire-bucket", BucketMetricArgs.builder()
.bucket(example.id())
.name("EntireBucket")
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucket: example
example-entire-bucket:
type: aws:s3:BucketMetric
properties:
bucket: ${example.id}
name: EntireBucket
The bucket property references the bucket to monitor. The name property provides a unique identifier for this metrics configuration (up to 64 characters). Without a filter, CloudWatch collects metrics for all objects in the bucket.
Filter metrics by prefix and tags
Large buckets often contain multiple workloads. Filtering by prefix and tags lets you track specific subsets independently.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {bucket: "example"});
const example_filtered = new aws.s3.BucketMetric("example-filtered", {
bucket: example.id,
name: "ImportantBlueDocuments",
filter: {
prefix: "documents/",
tags: {
priority: "high",
"class": "blue",
},
},
});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example", bucket="example")
example_filtered = aws.s3.BucketMetric("example-filtered",
bucket=example.id,
name="ImportantBlueDocuments",
filter={
"prefix": "documents/",
"tags": {
"priority": "high",
"class": "blue",
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := s3.NewBucket(ctx, "example", &s3.BucketArgs{
Bucket: pulumi.String("example"),
})
if err != nil {
return err
}
_, err = s3.NewBucketMetric(ctx, "example-filtered", &s3.BucketMetricArgs{
Bucket: example.ID(),
Name: pulumi.String("ImportantBlueDocuments"),
Filter: &s3.BucketMetricFilterArgs{
Prefix: pulumi.String("documents/"),
Tags: pulumi.StringMap{
"priority": pulumi.String("high"),
"class": pulumi.String("blue"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.S3.Bucket("example", new()
{
BucketName = "example",
});
var example_filtered = new Aws.S3.BucketMetric("example-filtered", new()
{
Bucket = example.Id,
Name = "ImportantBlueDocuments",
Filter = new Aws.S3.Inputs.BucketMetricFilterArgs
{
Prefix = "documents/",
Tags =
{
{ "priority", "high" },
{ "class", "blue" },
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
import com.pulumi.aws.s3.BucketMetric;
import com.pulumi.aws.s3.BucketMetricArgs;
import com.pulumi.aws.s3.inputs.BucketMetricFilterArgs;
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 = new Bucket("example", BucketArgs.builder()
.bucket("example")
.build());
var example_filtered = new BucketMetric("example-filtered", BucketMetricArgs.builder()
.bucket(example.id())
.name("ImportantBlueDocuments")
.filter(BucketMetricFilterArgs.builder()
.prefix("documents/")
.tags(Map.ofEntries(
Map.entry("priority", "high"),
Map.entry("class", "blue")
))
.build())
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucket: example
example-filtered:
type: aws:s3:BucketMetric
properties:
bucket: ${example.id}
name: ImportantBlueDocuments
filter:
prefix: documents/
tags:
priority: high
class: blue
The filter property narrows metrics collection to objects matching criteria. The prefix limits collection to objects under a specific path. The tags property requires objects to have matching key-value pairs. CloudWatch only tracks objects that satisfy both conditions.
Track metrics through an S3 Access Point
S3 Access Points provide named network endpoints with their own permissions and network controls. Filtering by Access Point isolates traffic through specific endpoints.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {bucket: "example"});
const example_access_point = new aws.s3.AccessPoint("example-access-point", {
bucket: example.id,
name: "example-access-point",
});
const example_filtered = new aws.s3.BucketMetric("example-filtered", {
bucket: example.id,
name: "ImportantBlueDocuments",
filter: {
accessPoint: example_access_point.arn,
tags: {
priority: "high",
"class": "blue",
},
},
});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example", bucket="example")
example_access_point = aws.s3.AccessPoint("example-access-point",
bucket=example.id,
name="example-access-point")
example_filtered = aws.s3.BucketMetric("example-filtered",
bucket=example.id,
name="ImportantBlueDocuments",
filter={
"access_point": example_access_point.arn,
"tags": {
"priority": "high",
"class": "blue",
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := s3.NewBucket(ctx, "example", &s3.BucketArgs{
Bucket: pulumi.String("example"),
})
if err != nil {
return err
}
example_access_point, err := s3.NewAccessPoint(ctx, "example-access-point", &s3.AccessPointArgs{
Bucket: example.ID(),
Name: pulumi.String("example-access-point"),
})
if err != nil {
return err
}
_, err = s3.NewBucketMetric(ctx, "example-filtered", &s3.BucketMetricArgs{
Bucket: example.ID(),
Name: pulumi.String("ImportantBlueDocuments"),
Filter: &s3.BucketMetricFilterArgs{
AccessPoint: example_access_point.Arn,
Tags: pulumi.StringMap{
"priority": pulumi.String("high"),
"class": pulumi.String("blue"),
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.S3.Bucket("example", new()
{
BucketName = "example",
});
var example_access_point = new Aws.S3.AccessPoint("example-access-point", new()
{
Bucket = example.Id,
Name = "example-access-point",
});
var example_filtered = new Aws.S3.BucketMetric("example-filtered", new()
{
Bucket = example.Id,
Name = "ImportantBlueDocuments",
Filter = new Aws.S3.Inputs.BucketMetricFilterArgs
{
AccessPoint = example_access_point.Arn,
Tags =
{
{ "priority", "high" },
{ "class", "blue" },
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
import com.pulumi.aws.s3.AccessPoint;
import com.pulumi.aws.s3.AccessPointArgs;
import com.pulumi.aws.s3.BucketMetric;
import com.pulumi.aws.s3.BucketMetricArgs;
import com.pulumi.aws.s3.inputs.BucketMetricFilterArgs;
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 = new Bucket("example", BucketArgs.builder()
.bucket("example")
.build());
var example_access_point = new AccessPoint("example-access-point", AccessPointArgs.builder()
.bucket(example.id())
.name("example-access-point")
.build());
var example_filtered = new BucketMetric("example-filtered", BucketMetricArgs.builder()
.bucket(example.id())
.name("ImportantBlueDocuments")
.filter(BucketMetricFilterArgs.builder()
.accessPoint(example_access_point.arn())
.tags(Map.ofEntries(
Map.entry("priority", "high"),
Map.entry("class", "blue")
))
.build())
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucket: example
example-access-point:
type: aws:s3:AccessPoint
properties:
bucket: ${example.id}
name: example-access-point
example-filtered:
type: aws:s3:BucketMetric
properties:
bucket: ${example.id}
name: ImportantBlueDocuments
filter:
accessPoint: ${["example-access-point"].arn}
tags:
priority: high
class: blue
The accessPoint property in the filter references an Access Point ARN. CloudWatch tracks only requests routed through that endpoint. You can combine Access Point filtering with tags to further narrow the scope.
Beyond these examples
These snippets focus on specific metrics configuration features: bucket-wide and filtered metric collection, prefix and tag-based filtering, and Access Point integration. They’re intentionally minimal rather than full monitoring solutions.
The examples reference pre-existing infrastructure such as S3 buckets, S3 Access Points (for Access Point example), and tagged objects (for tag filtering). They focus on configuring metrics collection rather than provisioning buckets or dashboards.
To keep things focused, common metrics patterns are omitted, including:
- CloudWatch dashboard integration
- Alarm configuration based on metrics
- Cost implications of metrics collection
- Metrics retention and querying
These omissions are intentional: the goal is to illustrate how each metrics feature is wired, not provide drop-in monitoring modules. See the S3 BucketMetric resource reference for all available configuration options.
Let's configure AWS S3 Bucket Metrics
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Setup
filter property to collect metrics for the entire bucket. Add a filter with prefix, tags, or both to monitor only specific objects.bucket:metric with pulumi import, for example: pulumi import aws:s3/bucketMetric:BucketMetric my-bucket-entire-bucket my-bucket:EntireBucketFiltering & Scope
prefix, tags, Access Point ARN (accessPoint), or a logical AND of prefix and tags.filter.accessPoint field to collect metrics for objects accessed through that Access Point.Limitations & Constraints
bucket and name are immutable. Changing either requires replacing the resource.name must be a unique identifier for the bucket and cannot exceed 64 characters in length.Using a different cloud?
Explore monitoring guides for other cloud providers: