Last active
November 30, 2021 16:24
-
-
Save latesr/f38b2d30803a37d1b73b4c0d1678c3ae to your computer and use it in GitHub Desktop.
AWS cdk for V1 ReplicatingBucket and ReplicaBucket supporting replication of 'soft-delete' and cross account configuration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//References: | |
//For permissions required for replication: | |
// https://docs.aws.amazon.com/AmazonS3/latest/dev/setting-repl-config-perm-overview.html | |
//To understand delete propagation and the differences between V1 and V2 replication: | |
// https://aws.amazon.com/blogs/storage/managing-delete-marker-replication-in-amazon-s3/ | |
// | |
//Summary: | |
//This exposes: | |
// 1) Two classes that extend s3.Bucket (ReplicatingBucket and ReplicaBucket) | |
// 2) Two interfaces that extends s3.BucketProps (ReplicatingBucketProps and ReplicaBucketProps) | |
import * as cdk from '@aws-cdk/core'; | |
import * as s3 from '@aws-cdk/aws-s3'; | |
import * as iam from '@aws-cdk/aws-iam'; | |
import * as assert from "assert"; | |
interface ReplicationRoleProps { | |
srcBucketArn: string; | |
dstBucketArn: string; | |
} | |
class ReplicationRole extends iam.Role { | |
constructor(scope: cdk.Construct, id: string, props: ReplicationRoleProps) { | |
super(scope, id, {assumedBy: new iam.ServicePrincipal('s3.amazonaws.com')}); | |
this.addToPolicy(new iam.PolicyStatement({ | |
effect: iam.Effect.ALLOW, | |
actions: [ | |
's3:GetReplicationConfiguration', | |
's3:ListBucket', | |
], | |
resources: [props.srcBucketArn], | |
})); | |
this.addToPolicy(new iam.PolicyStatement({ | |
effect: iam.Effect.ALLOW, | |
actions: [ | |
's3:GetObjectVersion', | |
's3:GetObjectVersionAcl', | |
's3:GetObjectVersionTagging' | |
], | |
resources: [props.srcBucketArn + '/*'], | |
})); | |
this.addToPolicy(new iam.PolicyStatement({ | |
effect: iam.Effect.ALLOW, | |
actions: [ | |
's3:ReplicateObject', | |
's3:ReplicateDelete', | |
's3:ReplicateTags', | |
's3:ObjectOwnerOverrideToBucketOwner', | |
], | |
resources: [props.dstBucketArn + '/*'], | |
})); | |
} | |
} | |
export interface ReplicatingBucketProps extends s3.BucketProps { | |
dstBucketArn: string | |
dstStorageClass: string; | |
dstAccountId: string; | |
} | |
export class ReplicatingBucket extends s3.Bucket { | |
constructor(scope: cdk.Construct, id: string, props: ReplicatingBucketProps) { | |
super(scope, id, props); | |
assert(props.versioned == true); | |
const role = new ReplicationRole(this, id, { | |
srcBucketArn: this.bucketArn, | |
dstBucketArn: props.dstBucketArn, | |
}); | |
const cfnArchive = this.node.defaultChild as s3.CfnBucket; | |
cfnArchive.replicationConfiguration = { | |
role: role.roleArn, | |
rules: [ | |
{ | |
status: "Enabled", | |
id: id, | |
prefix: "", | |
destination: { | |
accessControlTranslation: { | |
owner: "Destination", | |
}, | |
account: props.dstAccountId, | |
bucket: props.dstBucketArn, | |
storageClass: props.dstStorageClass, | |
} | |
} | |
] | |
}; | |
} | |
} | |
export interface ReplicaBucketProps extends s3.BucketProps { | |
srcAccountId: string; | |
} | |
export class ReplicaBucket extends s3.Bucket { | |
constructor(scope: cdk.Construct, id: string, props: ReplicaBucketProps) { | |
super(scope, id, props); | |
assert(props.versioned == true); | |
this.addToResourcePolicy(new iam.PolicyStatement({ | |
actions: [ | |
"s3:ReplicateDelete", | |
"s3:ReplicateObject", | |
"s3:ObjectOwnerOverrideToBucketOwner", | |
], | |
effect: iam.Effect.ALLOW, | |
resources: [ | |
this.bucketArn + '/*' | |
], | |
principals: [ | |
new iam.AccountPrincipal(props.srcAccountId), | |
], | |
})); | |
this.addToResourcePolicy(new iam.PolicyStatement({ | |
actions: [ | |
"s3:List*", | |
"s3:GetBucketVersioning", | |
"s3:PutBucketVersioning", | |
], | |
effect: iam.Effect.ALLOW, | |
resources: [ | |
this.bucketArn, | |
], | |
principals: [ | |
new iam.AccountPrincipal(props.srcAccountId), | |
], | |
})); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment