Create credentials (username, password) in secret manager and consume it in RDS
Applicable when
- You don't want your application secrets to be exposed in the repository code
- You want to create credentials automatically (no manual steps required)
Service limitations
- Secret name should be unique for each environment in cloud formation deployment. You can use environment suffix in secret name for uniqueness. e.g. rds-secret-name-dev.
- Secrets Manager does not immediately delete secrets. Instead, Secrets Manager immediately makes the secrets inaccessible and scheduled for deletion after a recovery window of a minimum of seven days.
We can't use existing secrets by name in CDK constructs as of now but it will be supported soon with this PR. Then will be able to refer existing secret by name in CDK constructs.
Configuring the service
Following construct is used to create credentials with secret name rds-secret-name-dev
import { ISecret, Secret } from '@aws-cdk/aws-secretsmanager'; import { Construct } from '@aws-cdk/core'; export class ProjectSecret extends Construct { public readonly rdsCredentials: ISecret; constructor(scope: Construct) { super(scope, 'Secret'); // This will generated this secret { 'username': 'Administrator', 'password': 'random-password-32-chars'} this.rdsCredentials = new Secret(this, 'Rds Credentials', { description: 'Rds credentials', secretName: 'rds-secret-name-dev', generateSecretString: { secretStringTemplate: '{"username": "Administrator"}', generateStringKey: 'password', excludePunctuation: true },
removalPolicy: RemovalPolicy.RETAIN }); } }
Deploy
cdk deploy
Using the service
There are two approaches to use above credentials.
1. With direct reference
You need to create instance of ProjectSecret in your stack, then you can use that object reference for credentials.
const secret = new ProjectSecret(this); new CfnDBCluster(this, 'Cluster', { engine, masterUsername: this.secrets.rdsCredentials.secretValueFromJson('username').toString(), masterUserPassword: this.secrets.rdsCredentials.secretValueFromJson('password').toString(), ... });
2. With secret key name
Use following function to get credentials by secret id
Example:
const auroraSecret = await getSecret('rds-secret-name-dev'); const auroraSecretObject = JSON.parse(auroraSecret);
const username = auroraSecretObject.username;
const password = auroraSecretObject.password;
process.env.AWS_SDK_LOAD_CONFIG = 'true'; import { SecretsManager } from 'aws-sdk'; export async function getSecret(SecretId: string): Promise { let secretString: string; try { const secretResponse = await new SecretsManager() .getSecretValue({ SecretId, }) .promise(); secretString = secretResponse.SecretString; } catch (e) { throw new Error(`No secret value found for SecretId: '${SecretId}'`); } return secretString; }
Testing
After deployment, you can verify credentials are created in secret manager. Now you can use secret name rds-secret-name-dev to access username/password.
You can also test them by connecting to database with db client using these credentials.
Related Article
https://central-supportdesk.zendesk.com/knowledge/articles/360015918019/en-us?brand_id=360001597600
Comments
0 comments
Please sign in to leave a comment.