Skip to content

Commit

Permalink
fix(redshift): Fix Redshift User Secret Multi-User Rotation
Browse files Browse the repository at this point in the history
Fixes Redshift User Secret Multi-User Rotation for new Users
by including `masterarn` in the Secret's Serialized JSON Object Text.

Note: This doesn't affect existing users (nor fixes roation for them)
since the secret string template is only used when the secret is
first created. For those existing secrets, the secret text will need
to be updated to include `masterarn` using the GetSecretValue and
UpdateSecret SecretManager APIs.

closes #28852

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
pennia committed Jan 25, 2024
1 parent 5ede456 commit 313b606
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
14 changes: 12 additions & 2 deletions packages/@aws-cdk/aws-redshift-alpha/lib/database-secret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ export interface DatabaseSecretProps {
* @default default master key
*/
readonly encryptionKey?: kms.IKey;

/**
* The master secret which will be used to rotate this secret.
*
* @default - no master secret information will be included
*/
readonly masterSecret?: secretsmanager.ISecret;
}

/**
Expand All @@ -30,10 +37,13 @@ export class DatabaseSecret extends secretsmanager.Secret {
encryptionKey: props.encryptionKey,
generateSecretString: {
passwordLength: 30, // Redshift password could be up to 64 characters
secretStringTemplate: JSON.stringify({ username: props.username }),
secretStringTemplate: JSON.stringify({
username: props.username,
masterarn: props.masterSecret?.secretArn,
}),
generateStringKey: 'password',
excludeCharacters: '"@/\\\ \'',
},
});
}
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-redshift-alpha/lib/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export class User extends UserBase {
const secret = new DatabaseSecret(this, 'Secret', {
username,
encryptionKey: props.encryptionKey,
masterSecret: props.adminUser,
});
const attachedSecret = secret.attach(props.cluster);
this.password = attachedSecret.secretValueFromJson('password');
Expand Down
32 changes: 31 additions & 1 deletion packages/@aws-cdk/aws-redshift-alpha/test/user.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ describe('cluster user', () => {
let cluster: redshift.ICluster;
const databaseName = 'databaseName';
let databaseOptions: redshift.DatabaseOptions;
let databaseOptionsWithAdminUser: redshift.DatabaseOptions;

beforeEach(() => {
stack = new cdk.Stack();
vpc = new ec2.Vpc(stack, 'VPC');
cluster = new redshift.Cluster(stack, 'Cluster', {
const clusterImpl = new redshift.Cluster(stack, 'Cluster', {
vpc: vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
Expand All @@ -25,10 +26,15 @@ describe('cluster user', () => {
},
publiclyAccessible: true,
});
cluster = clusterImpl;
databaseOptions = {
cluster,
databaseName,
};
databaseOptionsWithAdminUser = {
...databaseOptions,
adminUser: clusterImpl.secret,
};
});

it('creates using custom resource', () => {
Expand Down Expand Up @@ -62,6 +68,30 @@ describe('cluster user', () => {
});
});

it('creates database secret with admin user secret', () => {
const user = new redshift.User(stack, 'User', databaseOptionsWithAdminUser);

Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', {
GenerateSecretString: {
SecretStringTemplate: {
'Fn::Join': [
'',
[
`{"username":"${cdk.Names.uniqueId(user).toLowerCase()}","masterarn":"`,
{
Ref: 'ClusterSecretAttachment769E6258',
},
'"}',
],
],
},
},
});
Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::SecretTargetAttachment', {
SecretId: { Ref: 'UserSecretE2C04A69' },
});
});

it('username property is pulled from custom resource', () => {
const user = new redshift.User(stack, 'User', databaseOptions);

Expand Down

0 comments on commit 313b606

Please sign in to comment.