Package software.amazon.awscdk.services.secretsmanager
AWS Secrets Manager Construct Library
import software.amazon.awscdk.services.secretsmanager.*;
Create a new Secret in a Stack
To have SecretsManager generate a new secret value automatically, follow this example:
IVpc vpc;
DatabaseInstance instance1 = DatabaseInstance.Builder.create(this, "PostgresInstance1")
.engine(DatabaseInstanceEngine.POSTGRES)
// Generate the secret with admin username `postgres` and random password
.credentials(Credentials.fromGeneratedSecret("postgres"))
.vpc(vpc)
.build();
// Templated secret with username and password fields
Secret templatedSecret = Secret.Builder.create(this, "TemplatedSecret")
.generateSecretString(SecretStringGenerator.builder()
.secretStringTemplate(JSON.stringify(Map.of("username", "postgres")))
.generateStringKey("password")
.excludeCharacters("/@\"")
.build())
.build();
// Using the templated secret as credentials
DatabaseInstance instance2 = DatabaseInstance.Builder.create(this, "PostgresInstance2")
.engine(DatabaseInstanceEngine.POSTGRES)
.credentials(Map.of(
"username", templatedSecret.secretValueFromJson("username").toString(),
"password", templatedSecret.secretValueFromJson("password")))
.vpc(vpc)
.build();
If you need to use a pre-existing secret, the recommended way is to manually
provision the secret in AWS SecretsManager and use the Secret.fromSecretArn
or Secret.fromSecretAttributes method to make it available in your CDK Application:
Key encryptionKey;
ISecret secret = Secret.fromSecretAttributes(this, "ImportedSecret", SecretAttributes.builder()
.secretArn("arn:aws:secretsmanager:<region>:<account-id-number>:secret:<secret-name>-<random-6-characters>")
// If the secret is encrypted using a KMS-hosted CMK, either import or reference that key:
.encryptionKey(encryptionKey)
.build());
SecretsManager secret values can only be used in select set of properties. For the list of properties, see the CloudFormation Dynamic References documentation.
A secret can set RemovalPolicy. If it set to RETAIN, removing that secret will fail.
Grant permission to use the secret to a role
You must grant permission to a resource for that resource to be allowed to
use a secret. This can be achieved with the Secret.grantRead and/or Secret.grantWrite
method, depending on your need:
Role role = Role.Builder.create(this, "SomeRole").assumedBy(new AccountRootPrincipal()).build(); Secret secret = new Secret(this, "Secret"); secret.grantRead(role); secret.grantWrite(role);
If, as in the following example, your secret was created with a KMS key:
Role role; Key key = new Key(this, "KMS"); Secret secret = Secret.Builder.create(this, "Secret").encryptionKey(key).build(); secret.grantRead(role); secret.grantWrite(role);
then Secret.grantRead and Secret.grantWrite will also grant the role the
relevant encrypt and decrypt permissions to the KMS key through the
SecretsManager service principal.
The principal is automatically added to Secret resource policy and KMS Key policy for cross account access:
AccountPrincipal otherAccount = new AccountPrincipal("1234");
Key key = new Key(this, "KMS");
Secret secret = Secret.Builder.create(this, "Secret").encryptionKey(key).build();
secret.grantRead(otherAccount);
Rotating a Secret
Using a Custom Lambda Function
A rotation schedule can be added to a Secret using a custom Lambda function:
import software.amazon.awscdk.services.lambda.*;
Function fn;
Secret secret = new Secret(this, "Secret");
secret.addRotationSchedule("RotationSchedule", RotationScheduleOptions.builder()
.rotationLambda(fn)
.automaticallyAfter(Duration.days(15))
.rotateImmediatelyOnUpdate(false)
.build());
Note: The required permissions for Lambda to call SecretsManager and the other way round are automatically granted based on AWS Documentation as long as the Lambda is not imported.
See Overview of the Lambda Rotation Function on how to implement a Lambda Rotation Function.
Using a Hosted Lambda Function
Use the hostedRotation prop to rotate a secret with a hosted Lambda function:
Secret secret = new Secret(this, "Secret");
secret.addRotationSchedule("RotationSchedule", RotationScheduleOptions.builder()
.hostedRotation(HostedRotation.mysqlSingleUser())
.build());
Hosted rotation is available for secrets representing credentials for MySQL, PostgreSQL, Oracle, MariaDB, SQLServer, Redshift and MongoDB (both for the single and multi user schemes).
When deployed in a VPC, the hosted rotation implements ec2.IConnectable:
IVpc myVpc;
Connections dbConnections;
Secret secret;
HostedRotation myHostedRotation = HostedRotation.mysqlSingleUser(SingleUserHostedRotationOptions.builder().vpc(myVpc).build());
secret.addRotationSchedule("RotationSchedule", RotationScheduleOptions.builder().hostedRotation(myHostedRotation).build());
dbConnections.allowDefaultPortFrom(myHostedRotation);
Use the excludeCharacters option to customize the characters excluded from
the generated password when it is rotated. By default, the rotation excludes
the same characters as the ones excluded for the secret. If none are defined
then the following set is used: % +~#$&*()|[]{}:;<>?!'/@"`.
See also Automating secret creation in AWS CloudFormation.
Rotating database credentials
Define a SecretRotation to rotate database credentials:
Secret mySecret;
IConnectable myDatabase;
Vpc myVpc;
SecretRotation.Builder.create(this, "SecretRotation")
.application(SecretRotationApplication.MYSQL_ROTATION_SINGLE_USER) // MySQL single user scheme
.secret(mySecret)
.target(myDatabase) // a Connectable
.vpc(myVpc) // The VPC where the secret rotation application will be deployed
.excludeCharacters(" %+:;{}")
.build();
The secret must be a JSON string with the following format:
{
"engine": "<required: database engine>",
"host": "<required: instance host name>",
"username": "<required: username>",
"password": "<required: password>",
"dbname": "<optional: database name>",
"port": "<optional: if not specified, default port will be used>",
"masterarn": "<required for multi user rotation: the arn of the master secret which will be used to create users/change passwords>"
}
For the multi user scheme, a masterSecret must be specified:
Secret myUserSecret;
Secret myMasterSecret;
IConnectable myDatabase;
Vpc myVpc;
SecretRotation.Builder.create(this, "SecretRotation")
.application(SecretRotationApplication.MYSQL_ROTATION_MULTI_USER)
.secret(myUserSecret) // The secret that will be rotated
.masterSecret(myMasterSecret) // The secret used for the rotation
.target(myDatabase)
.vpc(myVpc)
.build();
By default, any stack updates will cause AWS Secrets Manager to rotate a secret immediately. To prevent this behavior and wait until the next scheduled rotation window specified via the automaticallyAfter property, set the rotateImmediatelyOnUpdate property to false:
Secret myUserSecret;
Secret myMasterSecret;
IConnectable myDatabase;
Vpc myVpc;
SecretRotation.Builder.create(this, "SecretRotation")
.application(SecretRotationApplication.MYSQL_ROTATION_MULTI_USER)
.secret(myUserSecret) // The secret that will be rotated
.masterSecret(myMasterSecret) // The secret used for the rotation
.target(myDatabase)
.vpc(myVpc)
.automaticallyAfter(Duration.days(7))
.rotateImmediatelyOnUpdate(false)
.build();
See also aws-rds where credentials generation and rotation is integrated.
Importing Secrets
Existing secrets can be imported by ARN, name, and other attributes (including the KMS key used to encrypt the secret). Secrets imported by name should use the short-form of the name (without the SecretsManager-provided suffix); the secret name must exist in the same account and region as the stack. Importing by name makes it easier to reference secrets created in different regions, each with their own suffix and ARN.
String secretCompleteArn = "arn:aws:secretsmanager:eu-west-1:111111111111:secret:MySecret-f3gDy9";
String secretPartialArn = "arn:aws:secretsmanager:eu-west-1:111111111111:secret:MySecret"; // No Secrets Manager suffix
IKey encryptionKey = Key.fromKeyArn(this, "MyEncKey", "arn:aws:kms:eu-west-1:111111111111:key/21c4b39b-fde2-4273-9ac0-d9bb5c0d0030");
ISecret mySecretFromCompleteArn = Secret.fromSecretCompleteArn(this, "SecretFromCompleteArn", secretCompleteArn);
ISecret mySecretFromPartialArn = Secret.fromSecretPartialArn(this, "SecretFromPartialArn", secretPartialArn);
ISecret mySecretFromName = Secret.fromSecretNameV2(this, "SecretFromName", "MySecret");
ISecret mySecretFromAttrs = Secret.fromSecretAttributes(this, "SecretFromAttributes", SecretAttributes.builder()
.secretCompleteArn(secretCompleteArn)
.encryptionKey(encryptionKey)
.build());
Replicating secrets
Secrets can be replicated to multiple regions by specifying replicaRegions:
Key myKey;
Secret.Builder.create(this, "Secret")
.replicaRegions(List.of(ReplicaRegion.builder()
.region("eu-west-1")
.build(), ReplicaRegion.builder()
.region("eu-central-1")
.encryptionKey(myKey)
.build()))
.build();
Alternatively, use addReplicaRegion():
Secret secret = new Secret(this, "Secret");
secret.addReplicaRegion("eu-west-1");
Creating JSON Secrets
Sometimes it is necessary to create a secret in SecretsManager that contains a JSON object. For example:
{
"username": "myUsername",
"database": "foo",
"password": "mypassword"
}
In order to create this type of secret, use the secretObjectValue input prop.
Stack stack;
User user = new User(this, "User");
AccessKey accessKey = AccessKey.Builder.create(this, "AccessKey").user(user).build();
Secret.Builder.create(this, "Secret")
.secretObjectValue(Map.of(
"username", SecretValue.unsafePlainText(user.getUserName()),
"database", SecretValue.unsafePlainText("foo"),
"password", accessKey.getSecretAccessKey()))
.build();
In this case both the username and database are not a Secret so SecretValue.unsafePlainText needs to be used.
This means that they will be rendered as plain text in the template, but in this case neither of those
are actual "secrets".
-
ClassDescriptionOptions to add a secret attachment to a secret.A builder for
AttachedSecretOptionsAn implementation forAttachedSecretOptionsThe type of service or database that's being associated with the secret.Attaches a resource-based permission policy to a secret.A fluent builder forCfnResourcePolicy.Properties for defining aCfnResourcePolicy.A builder forCfnResourcePolicyPropsAn implementation forCfnResourcePolicyPropsConfigure the rotation schedule and Lambda rotation function for a secret.A fluent builder forCfnRotationSchedule.The metadata needed to successfully rotate a managed external secret.An implementation forCfnRotationSchedule.ExternalSecretRotationMetadataItemPropertyCreates a new Lambda rotation function based on one of the Secrets Manager rotation function templates .A builder forCfnRotationSchedule.HostedRotationLambdaPropertyAn implementation forCfnRotationSchedule.HostedRotationLambdaPropertyThe rotation schedule and window.A builder forCfnRotationSchedule.RotationRulesPropertyAn implementation forCfnRotationSchedule.RotationRulesPropertyProperties for defining aCfnRotationSchedule.A builder forCfnRotationSchedulePropsAn implementation forCfnRotationSchedulePropsCreates a new secret.A fluent builder forCfnSecret.Generates a random password.A builder forCfnSecret.GenerateSecretStringPropertyAn implementation forCfnSecret.GenerateSecretStringPropertySpecifies aRegionand theKmsKeyIdfor a replica secret.A builder forCfnSecret.ReplicaRegionPropertyAn implementation forCfnSecret.ReplicaRegionPropertyProperties for defining aCfnSecret.A builder forCfnSecretPropsAn implementation forCfnSecretPropsTheAWS::SecretsManager::SecretTargetAttachmentresource completes the final link between a Secrets Manager secret and the associated database by adding the database connection information to the secret JSON.A fluent builder forCfnSecretTargetAttachment.Properties for defining aCfnSecretTargetAttachment.A builder forCfnSecretTargetAttachmentPropsAn implementation forCfnSecretTargetAttachmentPropsA hosted rotation.Hosted rotation type.A secret in AWS Secrets Manager.Internal default implementation forISecret.A proxy class which represents a concrete javascript instance of this type.A secret attachment target.Internal default implementation forISecretAttachmentTarget.A proxy class which represents a concrete javascript instance of this type.Internal default implementation forISecretTargetAttachment.A proxy class which represents a concrete javascript instance of this type.Multi user hosted rotation options.A builder forMultiUserHostedRotationOptionsAn implementation forMultiUserHostedRotationOptionsSecret replica region.A builder forReplicaRegionAn implementation forReplicaRegionResource Policy for SecretsManager Secrets.A fluent builder forResourcePolicy.Construction properties for a ResourcePolicy.A builder forResourcePolicyPropsAn implementation forResourcePolicyPropsA rotation schedule.A fluent builder forRotationSchedule.Options to add a rotation schedule to a secret.A builder forRotationScheduleOptionsAn implementation forRotationScheduleOptionsConstruction properties for a RotationSchedule.A builder forRotationSchedulePropsAn implementation forRotationSchedulePropsCreates a new secret in AWS SecretsManager.A fluent builder forSecret.Attachment target specifications.A builder forSecretAttachmentTargetPropsAn implementation forSecretAttachmentTargetPropsAttributes required to import an existing secret into the Stack.A builder forSecretAttributesAn implementation forSecretAttributesThe properties required to create a new secret in AWS Secrets Manager.A builder forSecretPropsAn implementation forSecretPropsSecret rotation for a service or database.A fluent builder forSecretRotation.A secret rotation serverless application.A fluent builder forSecretRotationApplication.Options for a SecretRotationApplication.A builder forSecretRotationApplicationOptionsAn implementation forSecretRotationApplicationOptionsConstruction properties for a SecretRotation.A builder forSecretRotationPropsAn implementation forSecretRotationPropsConfiguration to generate secrets such as passwords automatically.A builder forSecretStringGeneratorAn implementation forSecretStringGeneratorDeprecated.An attached secret.A fluent builder forSecretTargetAttachment.Construction properties for an AttachedSecret.A builder forSecretTargetAttachmentPropsAn implementation forSecretTargetAttachmentPropsSingle user hosted rotation options.A builder forSingleUserHostedRotationOptionsAn implementation forSingleUserHostedRotationOptions
cdk.SecretValueinstead.