(s3): L2 Bucket Construct does not Allow S3 Replication Rule Metrics to be Enabled without RTC Enabled
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
The L2 S3 Bucket Construct does not permit enabling metrics on s3 object replication between buckets unless replication time control (RTC)[https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication-time-control.html] is also enabled, which costs additional money.
On the AWS console and through cloudformation directly, you can enable metrics without enabling RTC. Please see the aforementioned documentation which clearly outlines this.
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Library Version
_No response_
### Expected Behavior
It is expected that you should be able to enable metrics without specifying RTC. Both are marked as optional arguments but does not say if 1 is specified the other has to be specified:
```typescript
/**
* Specifying S3 Replication Time Control (S3 RTC),
* including whether S3 RTC is enabled and the time when all objects and operations on objects must be replicated.
*
* @default - S3 Replication Time Control is not enabled
*/
readonly replicationTimeControl?: ReplicationTimeValue;
/**
* A container specifying replication metrics-related settings enabling replication metrics and events.
*
* When a value is set, metrics will be output to indicate whether the replication took longer than the specified time.
*
* @default - Replication metrics are not enabled
*/
readonly metrics?: ReplicationTimeValue;
```
I'm not sure why `metrics` is of type ReplicationTimeValue. It seems like it should be a boolean (true/false).
### Current Behavior
Runtime error when trying to set `metrics` in `replicationRules[]` without setting `replicationTimeControl`:
```bash
6:27:38 PM | UPDATE_FAILED | AWS::S3::Bucket | stackuseast27936359F Resource handler returned message: "Metrics cannot contain an event threshold when ReplicationTime is not specified or Disabled (Service: S3, Status Code: 400, Request ID: ..., Extended Request ID: ...) (SDK Attempt Count: 1)" (RequestToken: ..., HandlerErrorCode: InvalidRequest)
```
Code:
```typescript
... replicationRules: [
{
id: "MyRuleId",
destination: s3.Bucket.fromBucketName(this, "my-cool-bucket", "my-cool-bucket"),
metrics: s3.ReplicationTimeValue.FIFTEEN_MINUTES,
priority: 1,
},
],
...
```
See code snippet below for how you must modify the L1 construct directly in order to achieve the desired functionality in CDK:
```typescript
const outputBucket = new s3.Bucket(this, `src-bucket-name`, {
bucketName: `src-bucket-name`,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
versioned: true,
// S3 Replication
replicationRules: [
{
id: 'RuleIdName',
destination: s3.Bucket.fromBucketName(this, `dest-bucket-name`,`dest-bucket-name`),
priority: 1,
},
],
});
// Unfortunately no way to enable replication metrics WITHOUT enabling RTC via L2 construct yet
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/repl-metrics.html
const cfnBucket = outputBucket.node.defaultChild as s3.CfnBucket;
cfnBucket.addPropertyOverride('ReplicationConfiguration.Rules.0.Destination.Metrics', {
Status: 'Enabled', // EventThreshold is purposefully omitted here
});
```
This is what the cloudformation template looks like:
```json
"ReplicationConfiguration": { "Role": { "Fn::GetAtt": [ "resourceproduseast2ReplicationRole5313A389", "Arn" ] }, "Rules": [ { "DeleteMarkerReplication": { "Status": "Disabled" }, "Destination": { "Bucket": "arn:aws:s3:::my-source-bucket-name", "Metrics": { "EventThreshold": { "Minutes": 15 }, "Status": "Enabled" } }, "Filter": { "Prefix": "" }, "Id": "ReplicateToFootageFinderBucket", "Priority": 1, "Status": "Enabled" } ] },
```
Notice above how CDK builds and this is not included:
```json
"ReplicationTime": {
"Status": "Enabled",
"Time": { "Minutes": 15 }
},
```
### Reproduction Steps
1. Create two versioned s3 buckets in CDK, with replication rule from bucket 1 to bucket 2
2. Try to enable metrics without enabling RTC on the console (success)
3. Try to enable metrics in CDK without enabling RTC (failure)
```typescript
const destinationBucket = new s3.Bucket(this, "my-other-really-cool-bucket-name", {
bucketName: "my-other-really-cool-bucket-name",
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
versioned: true,
});
new s3.Bucket(this, "my-really-cool-bucket-name", {
bucketName: "my-really-cool-bucket-name",
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
versioned: true,
replicationRules: [
{
destination: destinationBucket,
metrics: s3.ReplicationTimeValue.FIFTEEN_MINUTES,
priority: 1,
},
],
});
```
### Possible Solution
_No response_
### Additional Information/Context
_No response_
### AWS CDK Library version (aws-cdk-lib)
2.202.0
### AWS CDK CLI version
2.1020.2 (build cf35f57)
### Node.js Version
v24.4.0
### OS
MacOS
### Language
TypeScript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Start at the L2 S3 Bucket Construct's replicationRules handling and compare the generated CfnBucket ReplicationConfiguration with the direct property override shown in the issue. Reproduce a rule using metrics without replicationTimeControl; done means the synthesized or deployed configuration enables Metrics without requiring ReplicationTime, with coverage for that case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100