Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

s3: replication only allows a single source bucket #33355

Closed
1 task
jochemd opened this issue Feb 9, 2025 · 4 comments · Fixed by #33360
Closed
1 task

s3: replication only allows a single source bucket #33355

jochemd opened this issue Feb 9, 2025 · 4 comments · Fixed by #33360
Labels
@aws-cdk/aws-s3 Related to Amazon S3 bug This issue is a bug. effort/medium Medium work item – several days of effort p2

Comments

@jochemd
Copy link

jochemd commented Feb 9, 2025

Describe the bug

v2.177.0 introduced the ability to set up S3 replication. This supports replicating from one source bucket to multiple destination buckets. But as soon as you configure a second source bucket, the stack fails to deploy (synth and diff work fine) with the error: CDKReplicationRole already exists ...

This appears to be caused by the replication feature using a role with a hardcoded name without any checks if a role by that name already exists.

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Version

No response

Expected Behavior

Deployment does not generate any errors and all source buckets are set up with functioning replication.

Current Behavior

During deployment an error occurs:
CDKReplicationRole already exists in stack arn:aws:cloudformation:eu-west-1:xxxxxxxxxxxx:stack/test-BucketsInfraStack/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Reproduction Steps

#!/usr/bin/env node
import { App } from 'aws-cdk-lib'
import { BucketsStage } from '../lib/BucketsStage'

const app = new App()
new BucketsStage(app, 'test', {})
app.synth()
import { Stage, StageProps } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import { BucketsDrStack } from './BucketsDRStack'
import { BucketsInfraStack } from './BucketsInfraStack'

export class BucketsStage extends Stage {
  constructor(scope: Construct, id: string, props: StageProps) {
    super(scope, id, props)

    /**
     * Disaster recovery to a different region
     */
    const bucketsDrStack = new BucketsDrStack(this, 'BucketsDrStack', {
      env: {
        account: 'xxxxxxxxxxxx',
        region: 'eu-central-1'
      },
      crossRegionReferences: true,
      description: 'Disaster recovery to a different region'
    })

    /**
     * Infra stack sets up the basic and statefull infra
     */
    new BucketsInfraStack(this, 'BucketsInfraStack', {
      env: {
        account: 'xxxxxxxxxxxx',
        region: 'eu-west-1'
      },
      bucketsDrStack,
      crossRegionReferences: true,
      description: 'Infra stack sets up the basic and statefull infra'
    })
  }
}
import { RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'
import { BlockPublicAccess, Bucket, BucketEncryption, IBucket } from 'aws-cdk-lib/aws-s3'
import type { Construct } from 'constructs'

export class BucketsDrStack extends Stack {
  readonly bucketAReplica: IBucket
  readonly bucketBReplica: IBucket

  constructor (scope: Construct, id: string, props: StackProps) {
    super(scope, id, props)

    this.bucketAReplica = new Bucket(this, 'bucketAReplica', {
      blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
      encryption: BucketEncryption.S3_MANAGED,
      enforceSSL: true,
      versioned: true,
      removalPolicy: RemovalPolicy.DESTROY
    })

    this.bucketBReplica = new Bucket(this, 'bucketBReplica', {
      blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
      encryption: BucketEncryption.S3_MANAGED,
      enforceSSL: true,
      versioned: true,
      removalPolicy: RemovalPolicy.DESTROY
    })
  }
}
import {
  RemovalPolicy,
  Stack,
  StackProps
} from 'aws-cdk-lib'
import { BlockPublicAccess, Bucket, BucketEncryption } from 'aws-cdk-lib/aws-s3'
import type { Construct } from 'constructs'
import { BucketsDrStack } from './BucketsDRStack'

export interface OrInfraStackProps extends StackProps {
  bucketsDrStack: BucketsDrStack;
}

export class BucketsInfraStack extends Stack {
  readonly privateBucket: Bucket
  readonly publicBucket: Bucket

  constructor(
    scope: Construct,
    id: string,
    props: OrInfraStackProps
  ) {
    super(scope, id, props)

    const { bucketsDrStack } = props

    // The S3 bucket for the private assets
    this.privateBucket = new Bucket(this, 'PrivateBucket', {
      blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
      encryption: BucketEncryption.S3_MANAGED,
      enforceSSL: true,
      versioned: true,
      replicationRules: [{
        deleteMarkerReplication: true,
        destination: bucketsDrStack.bucketAReplica,
        priority: 1,
      }],
      removalPolicy: RemovalPolicy.DESTROY
    })

    // The S3 bucket for the public (accessible through CloudFront) assets
    this.publicBucket = new Bucket(this, 'PublicBucket', {
      blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
      encryption: BucketEncryption.S3_MANAGED,
      enforceSSL: true,
      versioned: true,
      /* uncommenting the next lines will cause the error
      replicationRules: [{
        deleteMarkerReplication: true,
        destination: bucketsDrStack.bucketBReplica,
        priority: 1,
      }],
      */
      removalPolicy: RemovalPolicy.DESTROY
    })
  }
}

Possible Solution

The source bucket should accept an explicit replication role and add permissions to it instead of creating a role.

Additional Information/Context

No response

CDK CLI Version

2.178.1 (build ae342cb)

Framework Version

No response

Node.js Version

v22.13.0

OS

Linux

Language

TypeScript

Language Version

5.7.3

Other information

No response

@jochemd jochemd added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Feb 9, 2025
@github-actions github-actions bot added the @aws-cdk/aws-s3 Related to Amazon S3 label Feb 9, 2025
@pahud
Copy link
Contributor

pahud commented Feb 10, 2025

Thank you for your report and I've seen @badmintoncryer WIP on #33360.

We'll review the PR when it's ready and hopefully address this issue.

@pahud pahud added p2 effort/medium Medium work item – several days of effort and removed needs-triage This issue or PR still needs to be triaged. labels Feb 10, 2025
@foamcows
Copy link

If its of value, the workaround I had to use was to create the bucket using the normal CDK construct, then flip it to a Cfn Construct as shown below.

const sampleCfnBucket = sampleS3Bucket.node.defaultChild as CfnBucket;

Once you have the CfnBucket, you can then create and append a replicationConfiguration (link) which allows you to define the IAM role and append the replication settings.

Not ideal, and your suggestion solution would be much better, but this might unstick you in the meantime.

@shooit
Copy link
Contributor

shooit commented Feb 17, 2025

We are blocked by this too! Would be great to have this fix pushed through 🤞 . Thanks!

@mergify mergify bot closed this as completed in #33360 Mar 3, 2025
mergify bot pushed a commit that referenced this issue Mar 3, 2025
…ture flag) (#33360)

### Issue # (if applicable)

Closes #33355.

### Reason for this change

We cannot deploy multiple source buckets for object replication due to the explicitly set replication role name.

### Description of changes

Set replication role name by `PhysicalName.GENERATE_IF_NEEDED`.

### Describe any new or updated permissions being added

None

### Description of how you validated changes

Update both unit and integ test.

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Copy link

github-actions bot commented Mar 3, 2025

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 3, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
@aws-cdk/aws-s3 Related to Amazon S3 bug This issue is a bug. effort/medium Medium work item – several days of effort p2
Projects
None yet
4 participants