The aws:s3/bucketMetric:BucketMetric resource, part of the Pulumi AWS provider, defines CloudWatch metrics configurations that track request and data transfer activity for S3 buckets. This guide focuses on three capabilities: bucket-wide metrics, prefix and tag filtering, and Access Point filtering.
Metrics configurations reference existing S3 buckets and optionally Access Points. The examples are intentionally small. Combine them with your own bucket infrastructure and monitoring dashboards.
Track metrics for all objects in a bucket
CloudWatch metrics for S3 provide visibility into request rates, data transfer, and error counts across the entire bucket.
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 S3 bucket to monitor. The name property creates a unique identifier for this metrics configuration (up to 64 characters). Without a filter, CloudWatch tracks all objects in the bucket.
Track metrics for objects matching prefix and tags
Large buckets often contain multiple workloads. Filtered metrics let you monitor specific subsets by path and metadata.
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 to objects matching criteria. The prefix limits tracking to objects under a specific path. The tags property further filters by object metadata, requiring both conditions to match. This configuration tracks only high-priority blue documents in the documents/ path.
Track metrics for objects accessed through an Access Point
S3 Access Points provide named network endpoints with specific permissions. Metrics filtered by Access Point show activity through that endpoint.
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 filter.accessPoint property tracks requests through a specific Access Point by ARN. This isolates metrics for traffic using that endpoint’s permissions and policies, separate from direct bucket access or other Access Points.
Beyond these examples
These snippets focus on specific metrics configuration features: bucket-wide and filtered metrics, prefix and tag-based filtering, and Access Point filtering. They’re intentionally minimal rather than full monitoring solutions.
The examples reference pre-existing infrastructure such as S3 buckets and Access Points (for Access Point filtering). They focus on configuring metrics rather than provisioning the underlying storage.
To keep things focused, common metrics patterns are omitted, including:
- Multiple metrics configurations per bucket
- Region-specific configuration (region property)
- Metrics configuration lifecycle management
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 monitor the entire bucket. To monitor specific objects, add a filter with prefix, tags, or both.Filtering & Scope
prefix (object key prefix), tags (object tags), accessPoint (Access Point ARN), or a logical AND of prefix and tags.accessPoint field in the filter with the Access Point ARN, optionally combined with tags.Limitations & Constraints
bucket and name properties are immutable. Changing either requires replacing the resource.name must be 64 characters or less.Using a different cloud?
Explore monitoring guides for other cloud providers: