Skip to content

Commit

Permalink
feat: Share snapshot with other accounts (#5)
Browse files Browse the repository at this point in the history
Close #2
  • Loading branch information
kichik authored Jul 15, 2022
1 parent c94b290 commit f670b73
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
15 changes: 14 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A process to create sanitized snapshots of RDS instance or cluster, optionally o
The process is handled by a step function.

1. Snapshot the source database
2. Optionally re-ncrypt the snapshot with a different key in case you want to share it with an account that doesn't have access to the original key
2. Optionally re-encrypt the snapshot with a different key in case you want to share it with an account that doesn't have access to the original key
3. Create a temporary database
4. Run a Fargate task to connect to the temporary database and execute an arbitrary SQL script to sanitize it
5. Snapshot the sanitized database
Expand Down Expand Up @@ -161,6 +161,7 @@ Trigger this step function to get a new snapshot.
| <code><a href="#@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.fargateCluster">fargateCluster</a></code> | <code>aws-cdk-lib.aws_ecs.ICluster</code> | Cluster where sanitization task will be executed. |
| <code><a href="#@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.sanitizeSubnets">sanitizeSubnets</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | VPC subnets to use for sanitization task. |
| <code><a href="#@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.schedule">schedule</a></code> | <code>aws-cdk-lib.aws_events.Schedule</code> | The schedule or rate (frequency) that determines when the sanitized snapshot runs automatically. |
| <code><a href="#@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.shareAccounts">shareAccounts</a></code> | <code>string[]</code> | List of accounts the sanitized snapshot should be shared with. |
| <code><a href="#@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.snapshotHistoryLimit">snapshotHistoryLimit</a></code> | <code>number</code> | Limit the number of snapshot history. |
| <code><a href="#@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.snapshotKey">snapshotKey</a></code> | <code>aws-cdk-lib.aws_kms.IKey</code> | Optional KMS key to encrypt target snapshot. |
| <code><a href="#@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.snapshotPrefix">snapshotPrefix</a></code> | <code>string</code> | Prefix for sanitized snapshot name. |
Expand Down Expand Up @@ -300,6 +301,18 @@ The schedule or rate (frequency) that determines when the sanitized snapshot run

---

##### `shareAccounts`<sup>Optional</sup> <a name="shareAccounts" id="@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.shareAccounts"></a>

```typescript
public readonly shareAccounts: string[];
```

- *Type:* string[]

List of accounts the sanitized snapshot should be shared with.

---

##### `snapshotHistoryLimit`<sup>Optional</sup> <a name="snapshotHistoryLimit" id="@cloudsnorkel/cdk-rds-sanitized-snapshots.IRdsSanitizedSnapshotter.property.snapshotHistoryLimit"></a>

```typescript
Expand Down
25 changes: 24 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,18 @@ export interface IRdsSanitizedSnapshotter {
* Limit the number of snapshot history. Set this to delete old snapshots and only leave a certain number of snapshots.
*/
readonly snapshotHistoryLimit?: number;

/**
* List of accounts the sanitized snapshot should be shared with.
*/
readonly shareAccounts?: string[];
}

/**
* A process to create sanitized snapshots of RDS instance or cluster, optionally on a schedule. The process is handled by a step function.
*
* 1. Snapshot the source database
* 2. Optionally re-ncrypt the snapshot with a different key in case you want to share it with an account that doesn't have access to the original key
* 2. Optionally re-encrypt the snapshot with a different key in case you want to share it with an account that doesn't have access to the original key
* 3. Create a temporary database
* 4. Run a Fargate task to connect to the temporary database and execute an arbitrary SQL script to sanitize it
* 5. Snapshot the sanitized database
Expand Down Expand Up @@ -259,6 +264,9 @@ export class RdsSanitizedSnapshotter extends Construct {
s = s.next(this.sanitize());
s = s.next(this.finalSnapshot());
s = s.next(this.waitForOperation('Wait for Final Snapshot', 'snapshot', '$.tempDbId', '$.targetSnapshotId'));
if (props.shareAccounts) {
s = s.next(this.shareSnapshot(props.shareAccounts));
}

if (props.snapshotHistoryLimit) {
s.next(this.deleteOldSnapshots(props.snapshotHistoryLimit));
Expand Down Expand Up @@ -657,6 +665,21 @@ export class RdsSanitizedSnapshotter extends Construct {
// );
// }

private shareSnapshot(accounts: string[]) {
return new stepfunctions_tasks.CallAwsService(this, 'Share Snapshot', {
service: 'rds',
action: this.isCluster ? 'modifyDBClusterSnapshotAttribute' : 'modifyDBSnapshotAttribute',
parameters: {
DbClusterSnapshotIdentifier: this.isCluster ? stepfunctions.JsonPath.stringAt('$.targetSnapshotId') : undefined,
DbSnapshotIdentifier: this.isCluster ? undefined : stepfunctions.JsonPath.stringAt('$.targetSnapshotId'),
AttributeName: 'restore',
ValuesToAdd: accounts,
},
iamResources: [this.targetSnapshotArn],
resultPath: stepfunctions.JsonPath.DISCARD,
});
}

private deleteOldSnapshots(historyLimit: number) {
const deleteOldFn = new DeleteOldFunction(this, 'delete-old', {
logRetention: logs.RetentionDays.ONE_MONTH,
Expand Down

0 comments on commit f670b73

Please sign in to comment.